eeprom.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  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. #if (AC_3_3 || AC_3_4)
  311. board_t *board = get_board();
  312. if(board->md_data.rw_data.i_V_max > Default_Voltage_Max) board->md_data.rw_data.i_V_max = 0;
  313. if(board->md_data.rw_data.i_V_min > Default_Voltage_Max) board->md_data.rw_data.i_V_min = 0;
  314. if(board->md_data.rw_data.i_I_max > Default_Current_Max) board->md_data.rw_data.i_I_max = 0;
  315. if(board->md_data.rw_data.i_P_max > Default_Power_Max) board->md_data.rw_data.i_P_max = 0;
  316. if(board->md_data.rw_data.i_C_max > Default_Consum_Max) board->md_data.rw_data.i_C_max = 0;
  317. if(board->md_data.rw_data.i_V_max <= THRESHOULD_JUDGMENT)
  318. UNSET_VOLTAGE_MAX_EN(board->in_wanning_en[channel]);
  319. else
  320. SET_VOLTAGE_MAX_EN(board->in_wanning_en[channel]);
  321. if(board->md_data.rw_data.i_V_min <= THRESHOULD_JUDGMENT)
  322. UNSET_VOLTAGE_MIN_EN(board->in_wanning_en[channel]);
  323. else
  324. SET_VOLTAGE_MIN_EN(board->in_wanning_en[channel]);
  325. if(board->md_data.rw_data.i_I_max <= THRESHOULD_JUDGMENT)
  326. UNSET_CURRENT_MAX_EN(board->in_wanning_en[channel]);
  327. else
  328. SET_CURRENT_MAX_EN(board->in_wanning_en[channel]);
  329. if(board->md_data.rw_data.i_P_max <= THRESHOULD_JUDGMENT)
  330. UNSET_POWER_MAX_EN(board->in_wanning_en[channel]);
  331. else
  332. SET_POWER_MAX_EN(board->in_wanning_en[channel]);
  333. if(board->md_data.rw_data.i_C_max <= THRESHOULD_JUDGMENT)
  334. UNSET_CONSUMER_MAX_EN(board->in_wanning_en[channel]);
  335. else
  336. SET_CONSUMER_MAX_EN(board->in_wanning_en[channel]);
  337. #endif
  338. }else if(in_out == THRESHOLD_OUT)
  339. {
  340. board_t *board = get_board();
  341. if(channel < RelaySlaveChaNum)
  342. {
  343. if(board->md_data.rw_data.o_V_max[channel] > Default_Voltage_Max) board->md_data.rw_data.o_V_max[channel] = 0;
  344. if(board->md_data.rw_data.o_V_min[channel] > Default_Voltage_Max) board->md_data.rw_data.o_V_min[channel] = 0;
  345. if(board->md_data.rw_data.o_I_max[channel] > Default_Current_Max) board->md_data.rw_data.o_I_max[channel] = 0;
  346. if(board->md_data.rw_data.o_P_max[channel] > Default_Power_Max) board->md_data.rw_data.o_P_max[channel] = 0;
  347. if(board->md_data.rw_data.o_C_max[channel] > Default_Consum_Max) board->md_data.rw_data.o_C_max[channel] = 0;
  348. if(board->md_data.rw_data.o_V_max[channel] <= THRESHOULD_JUDGMENT)
  349. UNSET_VOLTAGE_MAX_EN(board->out_wanning_en[channel]);
  350. else
  351. SET_VOLTAGE_MAX_EN(board->out_wanning_en[channel]);
  352. if(board->md_data.rw_data.o_V_min[channel] <= THRESHOULD_JUDGMENT)
  353. UNSET_VOLTAGE_MIN_EN(board->out_wanning_en[channel]);
  354. else
  355. SET_VOLTAGE_MIN_EN(board->out_wanning_en[channel]);
  356. if(board->md_data.rw_data.o_I_max[channel] <= THRESHOULD_JUDGMENT)
  357. UNSET_CURRENT_MAX_EN(board->out_wanning_en[channel]);
  358. else
  359. SET_CURRENT_MAX_EN(board->out_wanning_en[channel]);
  360. if(board->md_data.rw_data.o_P_max[channel] <= THRESHOULD_JUDGMENT)
  361. UNSET_POWER_MAX_EN(board->out_wanning_en[channel]);
  362. else
  363. SET_POWER_MAX_EN(board->out_wanning_en[channel]);
  364. if(board->md_data.rw_data.o_C_max[channel] <= THRESHOULD_JUDGMENT)
  365. UNSET_CONSUMER_MAX_EN(board->out_wanning_en[channel]);
  366. else
  367. SET_CONSUMER_MAX_EN(board->out_wanning_en[channel]);
  368. }
  369. }
  370. }
  371. static uint8_t eeprom_page_read(uint16_t addr,uint8_t *data,uint16_t lenth)
  372. {
  373. if(lenth == 0 || lenth > PAGE_SIZE || ((addr % PAGE_SIZE) + lenth > PAGE_SIZE))
  374. {
  375. return 1;
  376. }
  377. iic_start_signal();
  378. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  379. {
  380. iic_send_byte(0XA0);
  381. if(iic_wait_ack())
  382. goto failed;
  383. iic_send_byte(addr >> 8);
  384. }else
  385. {
  386. iic_send_byte(0XA0 + ((addr / 256) << 1));
  387. }
  388. if(iic_wait_ack())
  389. goto failed;
  390. iic_send_byte(addr % 256);
  391. if(iic_wait_ack())
  392. goto failed;
  393. iic_start_signal();
  394. iic_send_byte(0XA1);
  395. if(iic_wait_ack())
  396. goto failed;
  397. for(int i = 0; i < lenth;i++)
  398. {
  399. if(i == lenth -1)
  400. {
  401. data[i] = iic_read_byte(0);
  402. }else
  403. {
  404. data[i] = iic_read_byte(1);
  405. }
  406. }
  407. iic_stop_signal();
  408. return 0;
  409. failed:
  410. iic_stop_signal();
  411. return 1;
  412. }
  413. static uint8_t eeprom_write_page(uint16_t addr,uint8_t *data,uint16_t chuank)
  414. {
  415. if(chuank == 0 || chuank > PAGE_SIZE || ((addr % PAGE_SIZE) + chuank > PAGE_SIZE))
  416. {
  417. return 1;
  418. }
  419. iic_start_signal();
  420. if(USER_DEFINE_EEPROM_TYPE > AT24C16)
  421. {
  422. iic_send_byte(0XA0);
  423. if(iic_wait_ack())
  424. goto failed;
  425. iic_send_byte(addr >> 8);
  426. }else
  427. {
  428. iic_send_byte(0XA0 + ((addr / 256) << 1));
  429. }
  430. if(iic_wait_ack())
  431. goto failed;
  432. iic_send_byte(addr % 256);
  433. if(iic_wait_ack())
  434. goto failed;
  435. for(uint16_t i = 0; i < chuank;i++)
  436. {
  437. iic_send_byte(data[i]);
  438. if(iic_wait_ack())
  439. goto failed;
  440. }
  441. iic_stop_signal();
  442. DelayNms(7);
  443. return 0;
  444. failed:
  445. iic_stop_signal();
  446. return 1;
  447. }
  448. static void eeprom_auto_page_write(uint16_t addr,uint8_t *data,uint16_t lenth)
  449. {
  450. uint16_t remaining = lenth;
  451. uint8_t *p = data;
  452. uint8_t count = 5;
  453. while(remaining > 0)
  454. {
  455. uint8_t chunk = PAGE_SIZE - (addr % PAGE_SIZE);
  456. if(chunk > remaining) chunk = remaining;
  457. do{
  458. if(!eeprom_write_page(addr, p,chunk))
  459. {
  460. break;
  461. }
  462. }while(count--);
  463. addr += chunk;
  464. p += chunk;
  465. remaining -= chunk;
  466. }
  467. }
  468. static void eeprom_auto_page_read(uint16_t addr,uint8_t *data,uint16_t lenth)
  469. {
  470. uint16_t remaining = lenth;
  471. uint8_t *p = data;
  472. uint8_t count = 5;
  473. while(remaining > 0)
  474. {
  475. uint8_t chunk = PAGE_SIZE - (addr % PAGE_SIZE);
  476. if(chunk > remaining) chunk = remaining;
  477. do{
  478. if(!eeprom_page_read(addr, p, chunk))
  479. {
  480. break;
  481. }
  482. }while(count--);
  483. addr += chunk;
  484. p += chunk;
  485. remaining -= chunk;
  486. }
  487. }