ee_access.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. /* Module for handling DALLAS DS2438, smart battery monitor
  2. Chip can store up to 40 bytes of user data in EEPROM,
  3. perform temp, voltage and current measurements.
  4. Chip also contains a unique serial number.
  5. Always read/write LSb first
  6. For documentaion, see data sheet for DS2438, 2438.pdf
  7. By Thomas.Lange@corelatus.com 001025 */
  8. #include <common.h>
  9. #include <config.h>
  10. #include <mpc8xx.h>
  11. #include <../board/gth/ee_dev.h>
  12. /* We dont have kernel functions */
  13. #define printk printf
  14. #define KERN_DEBUG
  15. #define KERN_ERR
  16. #define EIO 1
  17. static int Debug = 0;
  18. #ifndef TRUE
  19. #define TRUE 1
  20. #endif
  21. #ifndef FALSE
  22. #define FALSE 0
  23. #endif
  24. /*
  25. * lookup table ripped from DS app note 17, understanding and using
  26. * cyclic redundancy checks...
  27. */
  28. static u8 crc_lookup[256] = {
  29. 0, 94, 188, 226, 97, 63, 221, 131,
  30. 194, 156, 126, 32, 163, 253, 31, 65,
  31. 157, 195, 33, 127, 252, 162, 64, 30,
  32. 95, 1, 227, 189, 62, 96, 130, 220,
  33. 35, 125, 159, 193, 66, 28, 254, 160,
  34. 225, 191, 93, 3, 128, 222, 60, 98,
  35. 190, 224, 2, 92, 223, 129, 99, 61,
  36. 124, 34, 192, 158, 29, 67, 161, 255,
  37. 70, 24, 250, 164, 39, 121, 155, 197,
  38. 132, 218, 56, 102, 229, 187, 89, 7,
  39. 219, 133, 103, 57, 186, 228, 6, 88,
  40. 25, 71, 165, 251, 120, 38, 196, 154,
  41. 101, 59, 217, 135, 4, 90, 184, 230,
  42. 167, 249, 27, 69, 198, 152, 122, 36,
  43. 248, 166, 68, 26, 153, 199, 37, 123,
  44. 58, 100, 134, 216, 91, 5, 231, 185,
  45. 140, 210, 48, 110, 237, 179, 81, 15,
  46. 78, 16, 242, 172, 47, 113, 147, 205,
  47. 17, 79, 173, 243, 112, 46, 204, 146,
  48. 211, 141, 111, 49, 178, 236, 14, 80,
  49. 175, 241, 19, 77, 206, 144, 114, 44,
  50. 109, 51, 209, 143, 12, 82, 176, 238,
  51. 50, 108, 142, 208, 83, 13, 239, 177,
  52. 240, 174, 76, 18, 145, 207, 45, 115,
  53. 202, 148, 118, 40, 171, 245, 23, 73,
  54. 8, 86, 180, 234, 105, 55, 213, 139,
  55. 87, 9, 235, 181, 54, 104, 138, 212,
  56. 149, 203, 41, 119, 244, 170, 72, 22,
  57. 233, 183, 85, 11, 136, 214, 52, 106,
  58. 43, 117, 151, 201, 74, 20, 246, 168,
  59. 116, 42, 200, 150, 21, 75, 169, 247,
  60. 182, 232, 10, 84, 215, 137, 107, 53
  61. };
  62. static u8 make_new_crc( u8 Old_crc, u8 New_value ){
  63. /* Compute a new checksum with new byte, using previous checksum as input
  64. See DS app note 17, understanding and using cyclic redundancy checks...
  65. Also see DS2438, page 11 */
  66. return( crc_lookup[Old_crc ^ New_value ]);
  67. }
  68. int ee_crc_ok( u8 *Buffer, int Len, u8 Crc ){
  69. /* Check if the checksum for this buffer is correct */
  70. u8 Curr_crc=0;
  71. int i;
  72. u8 *Curr_byte = Buffer;
  73. for(i=0;i<Len;i++){
  74. Curr_crc = make_new_crc( Curr_crc, *Curr_byte);
  75. Curr_byte++;
  76. }
  77. E_DEBUG("Calculated CRC = 0x%x, read = 0x%x\n", Curr_crc, Crc);
  78. if(Curr_crc == Crc){
  79. /* Good */
  80. return(TRUE);
  81. }
  82. printk(KERN_ERR"EE checksum error, Calculated CRC = 0x%x, read = 0x%x\n",
  83. Curr_crc, Crc);
  84. return(FALSE);
  85. }
  86. static void
  87. set_idle(void){
  88. /* Send idle and keep start time
  89. Continous 1 is idle */
  90. WRITE_PORT(1);
  91. }
  92. static int
  93. do_reset(void){
  94. /* Release reset and verify that chip responds with presence pulse */
  95. int Retries = 0;
  96. while(Retries<5){
  97. udelay(RESET_LOW_TIME);
  98. /* Send reset */
  99. WRITE_PORT(0);
  100. udelay(RESET_LOW_TIME);
  101. /* Release reset */
  102. WRITE_PORT(1);
  103. /* Wait for EEPROM to drive output */
  104. udelay(PRESENCE_TIMEOUT);
  105. if(!READ_PORT){
  106. /* Ok, EEPROM is driving a 0 */
  107. E_DEBUG("Presence detected\n");
  108. if(Retries){
  109. E_DEBUG("Retries %d\n",Retries);
  110. }
  111. /* Make sure chip releases pin */
  112. udelay(PRESENCE_LOW_TIME);
  113. return 0;
  114. }
  115. Retries++;
  116. }
  117. printk(KERN_ERR"EEPROM did not respond when releasing reset\n");
  118. /* Make sure chip releases pin */
  119. udelay(PRESENCE_LOW_TIME);
  120. /* Set to idle again */
  121. set_idle();
  122. return(-EIO);
  123. }
  124. static u8
  125. read_byte(void){
  126. /* Read a single byte from EEPROM
  127. Read LSb first */
  128. int i;
  129. int Value;
  130. u8 Result=0;
  131. #ifndef CFG_IMMR
  132. u32 Flags;
  133. #endif
  134. E_DEBUG("Reading byte\n");
  135. for(i=0;i<8;i++){
  136. /* Small delay between pulses */
  137. udelay(1);
  138. #ifndef CFG_IMMR
  139. /* Disable irq */
  140. save_flags(Flags);
  141. cli();
  142. #endif
  143. /* Pull down pin short time to start read
  144. See page 26 in data sheet */
  145. WRITE_PORT(0);
  146. udelay(READ_LOW);
  147. WRITE_PORT(1);
  148. /* Wait for chip to drive pin */
  149. udelay(READ_TIMEOUT);
  150. Value = READ_PORT;
  151. if(Value)
  152. Value=1;
  153. #ifndef CFG_IMMR
  154. /* Enable irq */
  155. restore_flags(Flags);
  156. #endif
  157. /* Wait for chip to release pin */
  158. udelay(TOTAL_READ_LOW-READ_TIMEOUT);
  159. /* LSb first */
  160. Result|=Value<<i;
  161. }
  162. E_DEBUG("Read byte 0x%x\n",Result);
  163. return(Result);
  164. }
  165. static void
  166. write_byte(u8 Byte){
  167. /* Write a single byte to EEPROM
  168. Write LSb first */
  169. int i;
  170. int Value;
  171. #ifndef CFG_IMMR
  172. u32 Flags;
  173. #endif
  174. E_DEBUG("Writing byte 0x%x\n",Byte);
  175. for(i=0;i<8;i++){
  176. /* Small delay between pulses */
  177. udelay(1);
  178. Value = Byte&1;
  179. #ifndef CFG_IMMR
  180. /* Disable irq */
  181. save_flags(Flags);
  182. cli();
  183. #endif
  184. /* Pull down pin short time for a 1, long time for a 0
  185. See page 26 in data sheet */
  186. WRITE_PORT(0);
  187. if(Value){
  188. /* Write a 1 */
  189. udelay(WRITE_1_LOW);
  190. }
  191. else{
  192. /* Write a 0 */
  193. udelay(WRITE_0_LOW);
  194. }
  195. WRITE_PORT(1);
  196. #ifndef CFG_IMMR
  197. /* Enable irq */
  198. restore_flags(Flags);
  199. #endif
  200. if(Value)
  201. /* Wait for chip to read the 1 */
  202. udelay(TOTAL_WRITE_LOW-WRITE_1_LOW);
  203. Byte>>=1;
  204. }
  205. }
  206. int ee_do_command( u8 *Tx, int Tx_len, u8 *Rx, int Rx_len, int Send_skip ){
  207. /* Execute this command string, including
  208. giving reset and setting to idle after command
  209. if Rx_len is set, we read out data from EEPROM */
  210. int i;
  211. E_DEBUG("Command, Tx_len %d, Rx_len %d\n", Tx_len, Rx_len );
  212. if(do_reset()){
  213. /* Failed! */
  214. return(-EIO);
  215. }
  216. if(Send_skip)
  217. /* Always send SKIP_ROM first to tell chip we are sending a command,
  218. except when we read out rom data for chip */
  219. write_byte(SKIP_ROM);
  220. /* Always have Tx data */
  221. for(i=0;i<Tx_len;i++){
  222. write_byte(Tx[i]);
  223. }
  224. if(Rx_len){
  225. for(i=0;i<Rx_len;i++){
  226. Rx[i]=read_byte();
  227. }
  228. }
  229. set_idle();
  230. E_DEBUG("Command done\n");
  231. return(0);
  232. }
  233. int ee_init_data(void){
  234. int i;
  235. u8 Tx[10];
  236. int tmp;
  237. volatile immap_t *immap = (immap_t *)CFG_IMMR;
  238. while(0){
  239. tmp = 1-tmp;
  240. if(tmp)
  241. immap->im_ioport.iop_padat &= ~PA_FRONT_LED;
  242. else
  243. immap->im_ioport.iop_padat |= PA_FRONT_LED;
  244. udelay(1);
  245. }
  246. /* Set port to open drain to be able to read data from
  247. port without setting it to input */
  248. PORT_B_PAR &= ~PB_EEPROM;
  249. PORT_B_ODR |= PB_EEPROM;
  250. SET_PORT_B_OUTPUT(PB_EEPROM);
  251. /* Set idle mode */
  252. set_idle();
  253. /* Copy all User EEPROM data to scratchpad */
  254. for(i=0;i<USER_PAGES;i++){
  255. Tx[0]=RECALL_MEMORY;
  256. Tx[1]=EE_USER_PAGE_0+i;
  257. if(ee_do_command(Tx,2,NULL,0,TRUE)) return(-EIO);
  258. }
  259. /* Make sure chip doesnt store measurements in NVRAM */
  260. Tx[0]=WRITE_SCRATCHPAD;
  261. Tx[1]=0; /* Page */
  262. Tx[2]=9;
  263. if(ee_do_command(Tx,3,NULL,0,TRUE)) return(-EIO);
  264. Tx[0]=COPY_SCRATCHPAD;
  265. if(ee_do_command(Tx,2,NULL,0,TRUE)) return(-EIO);
  266. /* FIXME check status bit instead
  267. Could take 10 ms to store in EEPROM */
  268. for(i=0;i<10;i++){
  269. udelay(1000);
  270. }
  271. return(0);
  272. }