mweeprom.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. * Copyright (C) 2004 by Jan Dubiec. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY JAN DUBIEC AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JAN DUBIEC
  21. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. /*
  30. * $Log$
  31. * Revision 1.1 2005/07/26 18:02:40 haraldkipp
  32. * Moved from dev.
  33. *
  34. * Revision 1.2 2004/03/19 07:46:23 jdubiec
  35. * Make this file independent on sys/types.h due to compilation problems.
  36. *
  37. * Revision 1.1 2004/03/16 16:48:27 haraldkipp
  38. * Added Jan Dubiec's H8/300 port.
  39. *
  40. */
  41. /*
  42. * Microwire EEPROM routines compatible with avr-gcc API which Nut/OS uses.
  43. * Based on Yousuke FURUSAWA's code:
  44. * http://www.open.esys.tsukuba.ac.jp/~yousuke/software/h8/microwire/index.jp.html
  45. *
  46. * Jan Dubiec <jdx@slackware.pl>
  47. *
  48. */
  49. #include <h83068f.h>
  50. #include <dev/mweeprom.h>
  51. #define EEPROM_SET() PADDR = 0x0e
  52. #define EEPROM_CS PADR.BIT.B3
  53. #define EEPROM_SK PADR.BIT.B2
  54. #define EEPROM_DI PADR.BIT.B1
  55. #define EEPROM_DO PADR.BIT.B0
  56. #define EEPROM_HIGH 1
  57. #define EEPROM_LOW 0
  58. #define EEPROM_MASK(x,y) ((x & y) ? EEPROM_HIGH : EEPROM_LOW)
  59. #define EEPROM_WORD 8 /* 93LC66A : 1 word = 8 bit */
  60. static const unsigned short bitmask[16] = {
  61. 0x0001, /* 0000 0000 0000 0001 */
  62. 0x0002, /* 0000 0000 0000 0010 */
  63. 0x0004, /* 0000 0000 0000 0100 */
  64. 0x0008, /* 0000 0000 0000 1000 */
  65. 0x0010, /* 0000 0000 0001 0000 */
  66. 0x0020, /* 0000 0000 0010 0000 */
  67. 0x0040, /* 0000 0000 0100 0000 */
  68. 0x0080, /* 0000 0000 1000 0000 */
  69. 0x0100, /* 0000 0001 0000 0000 */
  70. 0x0200, /* 0000 0010 0000 0000 */
  71. 0x0400, /* 0000 0100 0000 0000 */
  72. 0x0800, /* 0000 1000 0000 0000 */
  73. 0x1000, /* 0001 0000 0000 0000 */
  74. 0x2000, /* 0010 0000 0000 0000 */
  75. 0x4000, /* 0100 0000 0000 0000 */
  76. 0x8000 /* 1000 0000 0000 0000 */
  77. };
  78. /* Delay for about 450 ns
  79. This function depends on crystal frequency; for 22,1184MHz crystal "nop"
  80. execution time is 90,42 ns
  81. */
  82. inline static void microdelay(void)
  83. {
  84. asm("nop");
  85. asm("nop");
  86. asm("nop");
  87. asm("nop");
  88. asm("nop");
  89. } static void eeprom_enable(void)
  90. {
  91. EEPROM_CS = EEPROM_HIGH;
  92. microdelay();
  93. }
  94. static void eeprom_disable(void)
  95. {
  96. EEPROM_CS = EEPROM_LOW;
  97. microdelay();
  98. }
  99. static unsigned char eeprom_pulse(unsigned char di)
  100. {
  101. unsigned char buf;
  102. EEPROM_DI = di;
  103. EEPROM_SK = EEPROM_HIGH;
  104. microdelay();
  105. buf = EEPROM_DO;
  106. EEPROM_SK = EEPROM_LOW;
  107. EEPROM_DI = EEPROM_LOW;
  108. microdelay();
  109. return buf;
  110. }
  111. unsigned char eeprom_read_byte(const unsigned char *addr)
  112. {
  113. signed char i;
  114. unsigned char c;
  115. unsigned short cmd;
  116. eeprom_enable();
  117. cmd = 0x0c00 | (size_t) addr;
  118. for (i = 11; i >= 0; --i)
  119. eeprom_pulse(EEPROM_MASK(cmd, bitmask[i]));
  120. c = 0;
  121. for (i = 7; i >= 0; --i)
  122. c += ((unsigned char) eeprom_pulse(EEPROM_LOW) << i);
  123. eeprom_disable();
  124. return c;
  125. }
  126. void eeprom_read_block(void *buf, const void *addr, size_t n)
  127. {
  128. unsigned char *p, *d;
  129. p = (unsigned char *) addr;
  130. d = (unsigned char *) buf;
  131. while (n-- > 0)
  132. *(d++) = eeprom_read_byte(p++);
  133. }
  134. unsigned short eeprom_read_word(const unsigned short *addr)
  135. {
  136. unsigned short i;
  137. eeprom_read_block((void *) &i, (void *) addr, sizeof(unsigned short));
  138. return i;
  139. }
  140. static void eeprom_write_enable(void)
  141. {
  142. signed char i;
  143. unsigned short cmd;
  144. eeprom_enable();
  145. cmd = 0x0980;
  146. for (i = 11; i >= 0; --i)
  147. eeprom_pulse(EEPROM_MASK(cmd, bitmask[i]));
  148. eeprom_disable();
  149. }
  150. static void eeprom_write_disable(void)
  151. {
  152. signed char i;
  153. unsigned short cmd;
  154. eeprom_enable();
  155. cmd = 0x0800;
  156. for (i = 11; i >= 0; --i)
  157. eeprom_pulse(EEPROM_MASK(cmd, bitmask[i]));
  158. eeprom_disable();
  159. }
  160. static void eeprom_generic_write(unsigned char *addr, unsigned char val)
  161. {
  162. signed char i;
  163. unsigned short cmd;
  164. eeprom_enable();
  165. cmd = 0x0a00 | (size_t) addr;
  166. for (i = 11; i >= 0; --i)
  167. eeprom_pulse(EEPROM_MASK(cmd, bitmask[i]));
  168. for (i = 7; i >= 0; --i)
  169. eeprom_pulse(EEPROM_MASK(val, bitmask[i]));
  170. eeprom_disable();
  171. eeprom_enable();
  172. while (EEPROM_DO == 0);
  173. eeprom_disable();
  174. }
  175. void eeprom_write_byte(unsigned char *addr, unsigned char val)
  176. {
  177. eeprom_write_enable();
  178. eeprom_generic_write(addr, val);
  179. eeprom_write_disable();
  180. }
  181. void eeprom_write_block(const void *buf, void *addr, size_t n)
  182. {
  183. unsigned char *p, *s;
  184. p = (unsigned char *) addr;
  185. s = (unsigned char *) buf;
  186. eeprom_write_enable();
  187. while (n-- > 0)
  188. eeprom_generic_write(p++, *(s++));
  189. eeprom_write_disable();
  190. }
  191. void eeprom_write_word(unsigned short *addr, unsigned short val)
  192. {
  193. eeprom_write_block((void *) addr, (void *) &val, sizeof(unsigned short));
  194. }
  195. void eeprom_fill_all(const unsigned char c)
  196. {
  197. signed char i;
  198. unsigned short cmd;
  199. eeprom_write_enable();
  200. eeprom_enable();
  201. cmd = 0x0880;
  202. for (i = 11; i >= 0; --i)
  203. eeprom_pulse(EEPROM_MASK(cmd, bitmask[i]));
  204. for (i = 7; i >= 0; --i)
  205. eeprom_pulse(EEPROM_MASK(c, bitmask[i]));
  206. eeprom_disable();
  207. eeprom_enable();
  208. while (EEPROM_DO == 0);
  209. eeprom_disable();
  210. eeprom_write_disable();
  211. }
  212. void eeprom_erase(unsigned char *addr)
  213. {
  214. signed char i;
  215. unsigned short cmd;
  216. eeprom_write_enable();
  217. eeprom_enable();
  218. cmd = 0x0e00 | (size_t) addr;
  219. for (i = 11; i >= 0; --i)
  220. eeprom_pulse(EEPROM_MASK(cmd, bitmask[i]));
  221. eeprom_disable();
  222. eeprom_enable();
  223. while (EEPROM_DO == 0);
  224. eeprom_disable();
  225. eeprom_write_disable();
  226. }
  227. void eeprom_erase_all(void)
  228. {
  229. signed char i;
  230. unsigned short cmd;
  231. eeprom_write_enable();
  232. eeprom_enable();
  233. cmd = 0x0900;
  234. for (i = 11; i >= 0; --i)
  235. eeprom_pulse(EEPROM_MASK(cmd, bitmask[i]));
  236. eeprom_disable();
  237. eeprom_enable();
  238. while (EEPROM_DO == 0);
  239. eeprom_disable();
  240. eeprom_write_disable();
  241. }