eeprom.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  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 void eeprom_page_read(uint16_t addr,uint8_t *data,uint16_t lenth);
  44. static void 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. IIC_SDA_SET;
  115. DelayNus(4);
  116. }
  117. /*****************************************************************************************
  118. * iic send 1 byte
  119. * 1 2 3 4
  120. * ______
  121. * SCL: ________/ \______
  122. * ______________________
  123. * SDA: \\\___________________
  124. *
  125. ******************************************************************************************/
  126. static void iic_send_byte(uint8_t data)
  127. {
  128. iic_set_sda_output();
  129. IIC_SCL_CLR;
  130. uint8_t t;
  131. for(t = 0; t < 8; t++){
  132. if((data & 0x80) >> 7)
  133. {
  134. IIC_SDA_SET;
  135. }else
  136. {
  137. IIC_SDA_CLR;
  138. }
  139. data <<= 1;
  140. DelayNus(2);
  141. IIC_SCL_SET;
  142. DelayNus(2);
  143. IIC_SCL_CLR;
  144. DelayNus(2);
  145. }
  146. }
  147. /*****************************************************************************************
  148. * read 1 byte
  149. * 1 2 3 4
  150. * ______
  151. * SCL: ______/ \___
  152. * ____________________
  153. * SDA: \\\\______________\\\
  154. *
  155. ******************************************************************************************/
  156. static uint8_t iic_read_byte(uint8_t ack)
  157. {
  158. uint8_t i;
  159. uint8_t receive = 0;
  160. iic_set_sda_input();
  161. for(i = 0; i < 8; i++ ){
  162. IIC_SCL_CLR;
  163. DelayNus(2);
  164. IIC_SCL_SET;
  165. receive <<= 1;
  166. if(IIC_READ_SDA())
  167. {
  168. receive ++;
  169. }
  170. DelayNus(1);
  171. }
  172. if(NACK == ack)
  173. {
  174. iic_send_nack();
  175. }else{
  176. iic_send_ack();
  177. }
  178. return receive;
  179. }
  180. /*****************************************************************************************
  181. * wait ack signal
  182. * _______|____
  183. * SCL: | \_________
  184. * _______|
  185. * SDA: \_____________
  186. *
  187. ******************************************************************************************/
  188. static uint8_t iic_wait_ack(void)
  189. {
  190. uint8_t err_time = 0;
  191. iic_set_sda_input();
  192. IIC_SCL_SET;
  193. DelayNus(1);
  194. while(IIC_READ_SDA())
  195. {
  196. err_time++;
  197. if(err_time >250)
  198. {
  199. iic_stop_signal();
  200. return 1;
  201. }
  202. }
  203. IIC_SCL_CLR;
  204. return 0;
  205. }
  206. /*****************************************************************************************
  207. * send ack signal
  208. * 1 2 3 4
  209. * ______
  210. * SCL: ________/ \______
  211. * __
  212. * SDA: \___________________
  213. ******************************************************************************************/
  214. static void iic_send_ack(void)
  215. {
  216. IIC_SCL_CLR;
  217. iic_set_sda_output();
  218. IIC_SDA_CLR;
  219. DelayNus(2);
  220. IIC_SCL_SET;
  221. DelayNus(2);
  222. IIC_SCL_CLR;
  223. }
  224. /*****************************************************************************************
  225. * send nack signal
  226. * 1 2 3 4
  227. * ______
  228. * SCL: ________/ \______
  229. * ______________________
  230. * SDA: __/
  231. ******************************************************************************************/
  232. static void iic_send_nack(void)
  233. {
  234. IIC_SCL_CLR;
  235. iic_set_sda_output();
  236. IIC_SDA_SET;
  237. DelayNus(2);
  238. IIC_SCL_SET;
  239. DelayNus(2);
  240. IIC_SCL_CLR;
  241. }
  242. static uint8_t eeprom_read_1_byte(uint16_t addr)
  243. {
  244. uint8_t temp =0;
  245. iic_start_signal();
  246. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  247. {
  248. iic_send_byte(0XA0);
  249. iic_wait_ack();
  250. iic_send_byte(addr >> 8);
  251. }else
  252. {
  253. iic_send_byte(0XA0 + ((addr / 256) << 1));
  254. }
  255. iic_wait_ack();
  256. iic_send_byte(addr % 256);
  257. iic_wait_ack();
  258. iic_start_signal();
  259. iic_send_byte(0XA1);
  260. iic_wait_ack();
  261. temp = iic_read_byte(0);
  262. iic_stop_signal();
  263. return temp;
  264. }
  265. static void eeprom_write_1_byte(uint16_t addr,uint8_t data)
  266. {
  267. iic_start_signal();
  268. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  269. {
  270. iic_send_byte(0XA0);
  271. iic_wait_ack();
  272. iic_send_byte(addr >> 8);
  273. }else
  274. {
  275. iic_send_byte(0XA0 + ((addr / 256) << 1));
  276. }
  277. iic_wait_ack();
  278. iic_send_byte(addr % 256);
  279. iic_wait_ack();
  280. iic_send_byte(data);
  281. iic_wait_ack();
  282. iic_stop_signal();
  283. DelayNms(7);
  284. }
  285. static void eeprom_write(uint16_t w_addr,uint8_t *data,uint16_t lenth)
  286. {
  287. while(lenth)
  288. {
  289. eeprom_write_1_byte(w_addr,*data);
  290. w_addr++;
  291. data++;
  292. lenth--;
  293. }
  294. }
  295. static void eeprom_read(uint16_t r_addr,uint8_t *data,uint16_t lenth)
  296. {
  297. while(lenth)
  298. {
  299. *data = eeprom_read_1_byte(r_addr);
  300. data++;
  301. r_addr++;
  302. lenth--;
  303. }
  304. }
  305. static void check_threshold(uint8_t in_out,uint8_t channel)
  306. {
  307. if(in_out == THRESHOLD_IN)
  308. {
  309. board_t *board = get_board();
  310. if(board->md_data.rw_data.totol_thr.v_top > Default_Voltage_Max) board->md_data.rw_data.totol_thr.v_top = 0;
  311. if(board->md_data.rw_data.totol_thr.v_down > Default_Voltage_Max) board->md_data.rw_data.totol_thr.v_down = 0;
  312. if(board->md_data.rw_data.totol_thr.i_top > Default_Current_Max) board->md_data.rw_data.totol_thr.i_top = 0;
  313. if(board->md_data.rw_data.totol_thr.p_top > Default_Power_Max) board->md_data.rw_data.totol_thr.p_top = 0;
  314. if(board->md_data.rw_data.totol_thr.e_top > Default_Consum_Max) board->md_data.rw_data.totol_thr.e_top = 0;
  315. if(board->md_data.rw_data.totol_thr.v_top <= THRESHOULD_JUDGMENT)
  316. UNSET_VOLTAGE_MAX_EN(board->in_wanning_en[0]);
  317. else
  318. SET_VOLTAGE_MAX_EN(board->in_wanning_en[0]);
  319. if(board->md_data.rw_data.totol_thr.v_down <= THRESHOULD_JUDGMENT)
  320. UNSET_VOLTAGE_MIN_EN(board->in_wanning_en[channel]);
  321. else
  322. SET_VOLTAGE_MIN_EN(board->in_wanning_en[channel]);
  323. if(board->md_data.rw_data.totol_thr.i_top <= THRESHOULD_JUDGMENT)
  324. UNSET_CURRENT_MAX_EN(board->in_wanning_en[channel]);
  325. else
  326. SET_CURRENT_MAX_EN(board->in_wanning_en[channel]);
  327. if(board->md_data.rw_data.totol_thr.p_top <= THRESHOULD_JUDGMENT)
  328. UNSET_POWER_MAX_EN(board->in_wanning_en[channel]);
  329. else
  330. SET_POWER_MAX_EN(board->in_wanning_en[channel]);
  331. if(board->md_data.rw_data.totol_thr.e_top <= THRESHOULD_JUDGMENT)
  332. UNSET_CONSUMER_MAX_EN(board->in_wanning_en[channel]);
  333. else
  334. SET_CONSUMER_MAX_EN(board->in_wanning_en[channel]);
  335. }else if(in_out == THRESHOLD_OUT)
  336. {
  337. board_t *board = get_board();
  338. if(channel < RelaySlaveChaNum)
  339. {
  340. 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;
  341. 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;
  342. 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;
  343. 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;
  344. 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;
  345. if(board->md_data.rw_data.thr.th[channel].v_top <= THRESHOULD_JUDGMENT)
  346. UNSET_VOLTAGE_MAX_EN(board->out_wanning_en[channel]);
  347. else
  348. SET_VOLTAGE_MAX_EN(board->out_wanning_en[channel]);
  349. if(board->md_data.rw_data.thr.th[channel].v_down <= THRESHOULD_JUDGMENT)
  350. UNSET_VOLTAGE_MIN_EN(board->out_wanning_en[channel]);
  351. else
  352. SET_VOLTAGE_MIN_EN(board->out_wanning_en[channel]);
  353. if(board->md_data.rw_data.thr.th[channel].i_top <= THRESHOULD_JUDGMENT)
  354. UNSET_CURRENT_MAX_EN(board->out_wanning_en[channel]);
  355. else
  356. SET_CURRENT_MAX_EN(board->out_wanning_en[channel]);
  357. if(board->md_data.rw_data.thr.th[channel].p_top <= THRESHOULD_JUDGMENT)
  358. UNSET_POWER_MAX_EN(board->out_wanning_en[channel]);
  359. else
  360. SET_POWER_MAX_EN(board->out_wanning_en[channel]);
  361. if(board->md_data.rw_data.thr.th[channel].e_top <= THRESHOULD_JUDGMENT)
  362. UNSET_CONSUMER_MAX_EN(board->out_wanning_en[channel]);
  363. else
  364. SET_CONSUMER_MAX_EN(board->out_wanning_en[channel]);
  365. }
  366. }
  367. }
  368. static void eeprom_page_read(uint16_t addr,uint8_t *data,uint16_t lenth)
  369. {
  370. if(lenth == 0 || lenth > PAGE_SIZE || ((addr % PAGE_SIZE) + lenth > PAGE_SIZE))
  371. {
  372. return;
  373. }
  374. iic_start_signal();
  375. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  376. {
  377. iic_send_byte(0XA0);
  378. iic_wait_ack();
  379. iic_send_byte(addr >> 8);
  380. }else
  381. {
  382. iic_send_byte(0XA0 + ((addr / 256) << 1));
  383. }
  384. iic_wait_ack();
  385. iic_send_byte(addr % 256);
  386. iic_wait_ack();
  387. iic_start_signal();
  388. iic_send_byte(0XA1);
  389. iic_wait_ack();
  390. for(int i = 0; i < lenth;i++)
  391. {
  392. if(i == lenth -1)
  393. {
  394. data[i] = iic_read_byte(0);
  395. }else
  396. {
  397. data[i] = iic_read_byte(1);
  398. }
  399. }
  400. iic_stop_signal();
  401. }
  402. static void eeprom_write_page(uint16_t addr,uint8_t *data,uint16_t chuank)
  403. {
  404. if(chuank == 0 || chuank > PAGE_SIZE || ((addr % PAGE_SIZE) + chuank > PAGE_SIZE))
  405. {
  406. return;
  407. }
  408. iic_start_signal();
  409. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  410. {
  411. iic_send_byte(0XA0);
  412. iic_wait_ack();
  413. iic_send_byte(addr >> 8);
  414. }else
  415. {
  416. iic_send_byte(0XA0 + ((addr / 256) << 1));
  417. }
  418. iic_wait_ack();
  419. iic_send_byte(addr % 256);
  420. iic_wait_ack();
  421. for(uint16_t i = 0; i < chuank;i++)
  422. {
  423. iic_send_byte(data[i]);
  424. iic_wait_ack();
  425. }
  426. iic_stop_signal();
  427. DelayNms(7);
  428. }
  429. static void eeprom_auto_page_write(uint16_t addr,uint8_t *data,uint16_t lenth)
  430. {
  431. uint16_t remaining = lenth;
  432. uint8_t *p = data;
  433. while(remaining > 0)
  434. {
  435. uint8_t chunk = PAGE_SIZE - (addr % PAGE_SIZE);
  436. if(chunk > remaining) chunk = remaining;
  437. eeprom_write_page(addr, p,chunk);
  438. addr += chunk;
  439. p += chunk;
  440. remaining -= chunk;
  441. }
  442. }
  443. static void eeprom_auto_page_read(uint16_t addr,uint8_t *data,uint16_t lenth)
  444. {
  445. uint16_t remaining = lenth;
  446. uint8_t *p = data;
  447. while(remaining > 0)
  448. {
  449. uint8_t chunk = PAGE_SIZE - (addr % PAGE_SIZE);
  450. if(chunk > remaining) chunk = remaining;
  451. eeprom_page_read(addr, p, chunk);
  452. addr += chunk;
  453. p += chunk;
  454. remaining -= chunk;
  455. }
  456. }