eeprom.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. #include "eeprom.h"
  2. #include "board_cfg.h"
  3. #include "gd32e23x.h"
  4. #include "common.h"
  5. #include "systick.h"
  6. #define ACK 1
  7. #define NACK 0
  8. #define IIC_WP_PIN GPIO_PIN_15
  9. #define IIC_DATA_IO GPIOF
  10. #define IIC_SDA_PIN GPIO_PIN_0
  11. #define IIC_SCL_PIN GPIO_PIN_1
  12. #define PAGE_SZIE_32 (32)
  13. #define PAGE_SIZE_16 (16)
  14. #define IIC_READ_SDA() gpio_input_bit_get(IIC_DATA_IO, IIC_SDA_PIN)
  15. #define IIC_SCL_SET gpio_bit_set(IIC_DATA_IO, IIC_SCL_PIN)
  16. #define IIC_SCL_CLR gpio_bit_reset(IIC_DATA_IO, IIC_SCL_PIN)
  17. #define IIC_SDA_SET gpio_bit_set(IIC_DATA_IO, IIC_SDA_PIN)
  18. #define IIC_SDA_CLR gpio_bit_reset(IIC_DATA_IO, IIC_SDA_PIN)
  19. #define AT24C01 127
  20. #define AT24C02 255
  21. #define AT24C04 511
  22. #define AT24C08 1023
  23. #define AT24C16 2047
  24. #define AT24C32 4095
  25. #define AT24C64 8191
  26. #define AT24C128 16383
  27. #define AT24C256 32767
  28. #define USER_DEFINE_EEPROM_TYPE AT24C64
  29. #define PAGE_SIZE PAGE_SZIE_32
  30. static void iic_init(void);
  31. static void iic_start_signal(void);
  32. static void iic_stop_signal(void);
  33. static void iic_send_byte(uint8_t data);
  34. static uint8_t iic_read_byte(uint8_t ack);
  35. static uint8_t iic_wait_ack(void);
  36. static void iic_send_ack(void);
  37. static void iic_send_nack(void);
  38. static uint8_t eeprom_read_1_byte(uint16_t addr);
  39. static void eeprom_write_1_byte(uint16_t addr,uint8_t data);
  40. static void eeprom_write(uint16_t w_addr,uint8_t *data,uint16_t lenth);
  41. static void eeprom_read(uint16_t r_addr,uint8_t *data,uint16_t lenth);
  42. static void check_threshold(uint8_t in_out,uint8_t channel);
  43. static uint8_t eeprom_page_read(uint16_t addr,uint8_t *data,uint16_t lenth);
  44. static uint8_t eeprom_write_page(uint16_t addr,uint8_t *data,uint16_t chuank);
  45. static void eeprom_auto_page_write(uint16_t addr,uint8_t *data,uint16_t lenth);
  46. static void eeprom_auto_page_read(uint16_t addr,uint8_t *data,uint16_t lenth);
  47. static inline void iic_set_sda_input()
  48. {
  49. gpio_mode_set(IIC_DATA_IO, GPIO_MODE_INPUT, GPIO_PUPD_NONE, IIC_SDA_PIN);
  50. }
  51. static inline void iic_set_sda_output()
  52. {
  53. gpio_mode_set(IIC_DATA_IO, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, IIC_SDA_PIN);
  54. gpio_output_options_set(IIC_DATA_IO, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, IIC_SDA_PIN);
  55. }
  56. void eeprom_init(void)
  57. {
  58. board_t *board = get_board();
  59. iic_init();
  60. board->read_eeprom = eeprom_read;
  61. board->write_eeprom = eeprom_write;
  62. board->check_threshold = check_threshold;
  63. board->read_eeprom_page = eeprom_auto_page_read;
  64. board->write_eeprom_page = eeprom_auto_page_write;
  65. }
  66. static void iic_init(void)
  67. {
  68. rcu_periph_clock_enable(RCU_GPIOC);
  69. gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_15);
  70. gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15); /* WP */
  71. gpio_bit_reset(GPIOC, GPIO_PIN_15);
  72. rcu_periph_clock_enable(RCU_GPIOF);
  73. gpio_mode_set(IIC_DATA_IO, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
  74. gpio_output_options_set(IIC_DATA_IO, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, IIC_SDA_PIN); /* SDA */
  75. gpio_mode_set(IIC_DATA_IO, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1); /* SCL */
  76. gpio_output_options_set(IIC_DATA_IO, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, IIC_SCL_PIN);
  77. }
  78. /*****************************************************************************************
  79. * start data transport signal
  80. * 1 2 3 4
  81. * __________
  82. * SCL : __/ \_____
  83. * ________
  84. * SDA : \___________
  85. ******************************************************************************************/
  86. static void iic_start_signal(void)
  87. {
  88. iic_set_sda_output();
  89. IIC_SDA_SET;
  90. IIC_SCL_SET;
  91. DelayNus(4);
  92. IIC_SDA_CLR;
  93. DelayNus(4);
  94. IIC_SCL_CLR;
  95. }
  96. /*****************************************************************************************
  97. * stop data transport signal
  98. * 1 2 3 4
  99. * _______________
  100. * SCL : ______/
  101. * __ ____________
  102. * SDA : \______/
  103. * ^
  104. * |
  105. *
  106. ******************************************************************************************/
  107. static void iic_stop_signal(void)
  108. {
  109. iic_set_sda_output();
  110. IIC_SCL_CLR;
  111. IIC_SDA_CLR;
  112. DelayNus(4);
  113. IIC_SCL_SET;
  114. DelayNus(4);
  115. IIC_SDA_SET;
  116. DelayNus(4);
  117. }
  118. /*****************************************************************************************
  119. * iic send 1 byte
  120. * 1 2 3 4
  121. * ______
  122. * SCL: ________/ \______
  123. * ______________________
  124. * SDA: \\\___________________
  125. *
  126. ******************************************************************************************/
  127. static void iic_send_byte(uint8_t data)
  128. {
  129. iic_set_sda_output();
  130. IIC_SCL_CLR;
  131. uint8_t t;
  132. for(t = 0; t < 8; t++){
  133. if((data & 0x80) >> 7)
  134. {
  135. IIC_SDA_SET;
  136. }else
  137. {
  138. IIC_SDA_CLR;
  139. }
  140. data <<= 1;
  141. DelayNus(2);
  142. IIC_SCL_SET;
  143. DelayNus(2);
  144. IIC_SCL_CLR;
  145. DelayNus(2);
  146. }
  147. }
  148. /*****************************************************************************************
  149. * read 1 byte
  150. * 1 2 3 4
  151. * ______
  152. * SCL: ______/ \___
  153. * ____________________
  154. * SDA: \\\\______________\\\
  155. *
  156. ******************************************************************************************/
  157. static uint8_t iic_read_byte(uint8_t ack)
  158. {
  159. uint8_t i;
  160. uint8_t receive = 0;
  161. iic_set_sda_input();
  162. for(i = 0; i < 8; i++ ){
  163. IIC_SCL_CLR;
  164. DelayNus(2);
  165. IIC_SCL_SET;
  166. receive <<= 1;
  167. if(IIC_READ_SDA())
  168. {
  169. receive ++;
  170. }
  171. DelayNus(1);
  172. }
  173. if(NACK == ack)
  174. {
  175. iic_send_nack();
  176. }else{
  177. iic_send_ack();
  178. }
  179. return receive;
  180. }
  181. /*****************************************************************************************
  182. * wait ack signal
  183. * _______|____
  184. * SCL: | \_________
  185. * _______|
  186. * SDA: \_____________
  187. *
  188. ******************************************************************************************/
  189. static uint8_t iic_wait_ack(void)
  190. {
  191. uint8_t err_time = 0;
  192. iic_set_sda_input();
  193. IIC_SCL_SET;
  194. DelayNus(1);
  195. while(IIC_READ_SDA())
  196. {
  197. err_time++;
  198. if(err_time >250)
  199. {
  200. iic_stop_signal();
  201. return 1;
  202. }
  203. }
  204. IIC_SCL_CLR;
  205. return 0;
  206. }
  207. /*****************************************************************************************
  208. * send ack signal
  209. * 1 2 3 4
  210. * ______
  211. * SCL: ________/ \______
  212. * __
  213. * SDA: \___________________
  214. ******************************************************************************************/
  215. static void iic_send_ack(void)
  216. {
  217. IIC_SCL_CLR;
  218. iic_set_sda_output();
  219. IIC_SDA_CLR;
  220. DelayNus(2);
  221. IIC_SCL_SET;
  222. DelayNus(2);
  223. IIC_SCL_CLR;
  224. }
  225. /*****************************************************************************************
  226. * send nack signal
  227. * 1 2 3 4
  228. * ______
  229. * SCL: ________/ \______
  230. * ______________________
  231. * SDA: __/
  232. ******************************************************************************************/
  233. static void iic_send_nack(void)
  234. {
  235. IIC_SCL_CLR;
  236. iic_set_sda_output();
  237. IIC_SDA_SET;
  238. DelayNus(2);
  239. IIC_SCL_SET;
  240. DelayNus(2);
  241. IIC_SCL_CLR;
  242. }
  243. static uint8_t eeprom_read_1_byte(uint16_t addr)
  244. {
  245. uint8_t temp =0;
  246. iic_start_signal();
  247. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  248. {
  249. iic_send_byte(0XA0);
  250. iic_wait_ack();
  251. iic_send_byte(addr >> 8);
  252. }else
  253. {
  254. iic_send_byte(0XA0 + ((addr / 256) << 1));
  255. }
  256. iic_wait_ack();
  257. iic_send_byte(addr % 256);
  258. iic_wait_ack();
  259. iic_start_signal();
  260. iic_send_byte(0XA1);
  261. iic_wait_ack();
  262. temp = iic_read_byte(0);
  263. iic_stop_signal();
  264. return temp;
  265. }
  266. static void eeprom_write_1_byte(uint16_t addr,uint8_t data)
  267. {
  268. iic_start_signal();
  269. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  270. {
  271. iic_send_byte(0XA0);
  272. iic_wait_ack();
  273. iic_send_byte(addr >> 8);
  274. }else
  275. {
  276. iic_send_byte(0XA0 + ((addr / 256) << 1));
  277. }
  278. iic_wait_ack();
  279. iic_send_byte(addr % 256);
  280. iic_wait_ack();
  281. iic_send_byte(data);
  282. iic_wait_ack();
  283. iic_stop_signal();
  284. DelayNms(7);
  285. }
  286. static void eeprom_write(uint16_t w_addr,uint8_t *data,uint16_t lenth)
  287. {
  288. while(lenth)
  289. {
  290. eeprom_write_1_byte(w_addr,*data);
  291. w_addr++;
  292. data++;
  293. lenth--;
  294. }
  295. }
  296. static void eeprom_read(uint16_t r_addr,uint8_t *data,uint16_t lenth)
  297. {
  298. while(lenth)
  299. {
  300. *data = eeprom_read_1_byte(r_addr);
  301. data++;
  302. r_addr++;
  303. lenth--;
  304. }
  305. }
  306. static void check_threshold(uint8_t in_out,uint8_t channel)
  307. {
  308. if(in_out == THRESHOLD_IN)
  309. {
  310. board_t *board = get_board();
  311. if(board->md_data.rw_data.totol_thr.v_top > Default_Voltage_Max) board->md_data.rw_data.totol_thr.v_top = 0;
  312. if(board->md_data.rw_data.totol_thr.v_down > Default_Voltage_Max) board->md_data.rw_data.totol_thr.v_down = 0;
  313. if(board->md_data.rw_data.totol_thr.i_top > Default_Current_Max) board->md_data.rw_data.totol_thr.i_top = 0;
  314. if(board->md_data.rw_data.totol_thr.p_top > Default_Power_Max) board->md_data.rw_data.totol_thr.p_top = 0;
  315. if(board->md_data.rw_data.totol_thr.e_top > Default_Consum_Max) board->md_data.rw_data.totol_thr.e_top = 0;
  316. if(board->md_data.rw_data.totol_thr.v_top <= THRESHOULD_JUDGMENT)
  317. UNSET_VOLTAGE_MAX_EN(board->in_wanning_en[0]);
  318. else
  319. SET_VOLTAGE_MAX_EN(board->in_wanning_en[0]);
  320. if(board->md_data.rw_data.totol_thr.v_down <= THRESHOULD_JUDGMENT)
  321. UNSET_VOLTAGE_MIN_EN(board->in_wanning_en[channel]);
  322. else
  323. SET_VOLTAGE_MIN_EN(board->in_wanning_en[channel]);
  324. if(board->md_data.rw_data.totol_thr.i_top <= THRESHOULD_JUDGMENT)
  325. UNSET_CURRENT_MAX_EN(board->in_wanning_en[channel]);
  326. else
  327. SET_CURRENT_MAX_EN(board->in_wanning_en[channel]);
  328. if(board->md_data.rw_data.totol_thr.p_top <= THRESHOULD_JUDGMENT)
  329. UNSET_POWER_MAX_EN(board->in_wanning_en[channel]);
  330. else
  331. SET_POWER_MAX_EN(board->in_wanning_en[channel]);
  332. if(board->md_data.rw_data.totol_thr.e_top <= THRESHOULD_JUDGMENT)
  333. UNSET_CONSUMER_MAX_EN(board->in_wanning_en[channel]);
  334. else
  335. SET_CONSUMER_MAX_EN(board->in_wanning_en[channel]);
  336. }else if(in_out == THRESHOLD_OUT)
  337. {
  338. board_t *board = get_board();
  339. if(channel < RelaySlaveChaNum)
  340. {
  341. if(board->md_data.rw_data.thr.th[channel].v_top > Default_Voltage_Max) board->md_data.rw_data.thr.th[channel].v_top = 0;
  342. if(board->md_data.rw_data.thr.th[channel].v_down > Default_Voltage_Max) board->md_data.rw_data.thr.th[channel].v_down = 0;
  343. if(board->md_data.rw_data.thr.th[channel].i_top > Default_Current_Max) board->md_data.rw_data.thr.th[channel].i_top = 0;
  344. if(board->md_data.rw_data.thr.th[channel].p_top > Default_Power_Max) board->md_data.rw_data.thr.th[channel].p_top = 0;
  345. if(board->md_data.rw_data.thr.th[channel].e_top > Default_Consum_Max) board->md_data.rw_data.thr.th[channel].e_top = 0;
  346. if(board->md_data.rw_data.thr.th[channel].v_top <= THRESHOULD_JUDGMENT)
  347. UNSET_VOLTAGE_MAX_EN(board->out_wanning_en[channel]);
  348. else
  349. SET_VOLTAGE_MAX_EN(board->out_wanning_en[channel]);
  350. if(board->md_data.rw_data.thr.th[channel].v_down <= THRESHOULD_JUDGMENT)
  351. UNSET_VOLTAGE_MIN_EN(board->out_wanning_en[channel]);
  352. else
  353. SET_VOLTAGE_MIN_EN(board->out_wanning_en[channel]);
  354. if(board->md_data.rw_data.thr.th[channel].i_top <= THRESHOULD_JUDGMENT)
  355. UNSET_CURRENT_MAX_EN(board->out_wanning_en[channel]);
  356. else
  357. SET_CURRENT_MAX_EN(board->out_wanning_en[channel]);
  358. if(board->md_data.rw_data.thr.th[channel].p_top <= THRESHOULD_JUDGMENT)
  359. UNSET_POWER_MAX_EN(board->out_wanning_en[channel]);
  360. else
  361. SET_POWER_MAX_EN(board->out_wanning_en[channel]);
  362. if(board->md_data.rw_data.thr.th[channel].e_top <= THRESHOULD_JUDGMENT)
  363. UNSET_CONSUMER_MAX_EN(board->out_wanning_en[channel]);
  364. else
  365. SET_CONSUMER_MAX_EN(board->out_wanning_en[channel]);
  366. }
  367. }
  368. }
  369. static uint8_t eeprom_page_read(uint16_t addr,uint8_t *data,uint16_t lenth)
  370. {
  371. if(lenth == 0 || lenth > PAGE_SIZE || ((addr % PAGE_SIZE) + lenth > PAGE_SIZE))
  372. {
  373. return 1;
  374. }
  375. iic_start_signal();
  376. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  377. {
  378. iic_send_byte(0XA0);
  379. if(iic_wait_ack())
  380. goto failed;
  381. iic_send_byte(addr >> 8);
  382. }else
  383. {
  384. iic_send_byte(0XA0 + ((addr / 256) << 1));
  385. }
  386. if(iic_wait_ack())
  387. goto failed;
  388. iic_send_byte(addr % 256);
  389. if(iic_wait_ack())
  390. goto failed;
  391. iic_start_signal();
  392. iic_send_byte(0XA1);
  393. if(iic_wait_ack())
  394. goto failed;
  395. for(int i = 0; i < lenth;i++)
  396. {
  397. if(i == lenth -1)
  398. {
  399. data[i] = iic_read_byte(0);
  400. }else
  401. {
  402. data[i] = iic_read_byte(1);
  403. }
  404. }
  405. iic_stop_signal();
  406. return 0;
  407. failed:
  408. iic_stop_signal();
  409. return 1;
  410. }
  411. static uint8_t eeprom_write_page(uint16_t addr,uint8_t *data,uint16_t chuank)
  412. {
  413. if(chuank == 0 || chuank > PAGE_SIZE || ((addr % PAGE_SIZE) + chuank > PAGE_SIZE))
  414. {
  415. return 1;
  416. }
  417. iic_start_signal();
  418. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  419. {
  420. iic_send_byte(0XA0);
  421. if(iic_wait_ack())
  422. goto failed;
  423. iic_send_byte(addr >> 8);
  424. }else
  425. {
  426. iic_send_byte(0XA0 + ((addr / 256) << 1));
  427. }
  428. if(iic_wait_ack())
  429. goto failed;
  430. iic_send_byte(addr % 256);
  431. if(iic_wait_ack())
  432. goto failed;
  433. for(uint16_t i = 0; i < chuank;i++)
  434. {
  435. iic_send_byte(data[i]);
  436. if(iic_wait_ack())
  437. goto failed;
  438. }
  439. iic_stop_signal();
  440. DelayNms(7);
  441. return 0;
  442. failed:
  443. iic_stop_signal();
  444. return 1;
  445. }
  446. static void eeprom_auto_page_write(uint16_t addr,uint8_t *data,uint16_t lenth)
  447. {
  448. uint16_t remaining = lenth;
  449. uint8_t *p = data;
  450. uint8_t count = 5;
  451. while(remaining > 0)
  452. {
  453. uint8_t chunk = PAGE_SIZE - (addr % PAGE_SIZE);
  454. if(chunk > remaining) chunk = remaining;
  455. do{
  456. if(!eeprom_write_page(addr, p,chunk))
  457. {
  458. break;
  459. }
  460. }while(count--);
  461. addr += chunk;
  462. p += chunk;
  463. remaining -= chunk;
  464. }
  465. }
  466. static void eeprom_auto_page_read(uint16_t addr,uint8_t *data,uint16_t lenth)
  467. {
  468. uint16_t remaining = lenth;
  469. uint8_t *p = data;
  470. uint8_t count = 5;
  471. while(remaining > 0)
  472. {
  473. uint8_t chunk = PAGE_SIZE - (addr % PAGE_SIZE);
  474. if(chunk > remaining) chunk = remaining;
  475. do{
  476. if(!eeprom_page_read(addr, p, chunk))
  477. {
  478. break;
  479. }
  480. }while(count--);
  481. addr += chunk;
  482. p += chunk;
  483. remaining -= chunk;
  484. }
  485. }