api_rt_i2c.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. #include "api_rt_i2c.h"
  2. #include "api_rt_dbg.h"
  3. #include "board_config.h"
  4. #include "gd32f30x.h"
  5. #include <stdint.h>
  6. ApiRtI2C_Handle I2Cs[1];
  7. /* ========================================================================== */
  8. /* ============================ Api RT Functions ============================ */
  9. /* ========================================================================== */
  10. void iRtI2C_Init()
  11. {
  12. I2Cs[0].I2CBase = I2C0;
  13. }
  14. int iRtI2C_BusReset(uint8_t devIndex)
  15. {
  16. i2c_deinit(I2Cs[devIndex].I2CBase);
  17. /* Configure SDA/SCL for GPIO */
  18. GPIO_BC(GPIOB) |= GPIO_PIN_6;
  19. GPIO_BC(GPIOB) |= GPIO_PIN_7;
  20. gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
  21. gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
  22. __NOP();
  23. __NOP();
  24. __NOP();
  25. __NOP();
  26. __NOP();
  27. GPIO_BOP(GPIOB) |= GPIO_PIN_6;
  28. __NOP();
  29. __NOP();
  30. __NOP();
  31. __NOP();
  32. __NOP();
  33. GPIO_BOP(GPIOB) |= GPIO_PIN_7;
  34. /* Connect I2C_SCL_PIN to I2C_SCL */
  35. /* Connect I2C_SDA_PIN to I2C_SDA */
  36. gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
  37. gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
  38. /* configure I2Cs[devIndex].I2CBase clock */
  39. i2c_clock_config(I2Cs[devIndex].I2CBase, 100000, I2C_DTCY_2);
  40. /* Configure I2C address */
  41. i2c_mode_addr_config(I2Cs[devIndex].I2CBase, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, HW_I2C_EE_ADDR_BLOCK1);
  42. /* Enable acknowledge */
  43. i2c_ack_config(I2Cs[devIndex].I2CBase, I2C_ACK_ENABLE);
  44. /* Enable I2C_DMA */
  45. // i2c_dma_config(I2Cs[devIndex].I2CBase, I2C_DMA_ON);
  46. /* Enable I2C */
  47. i2c_enable(I2Cs[devIndex].I2CBase);
  48. return 1;
  49. }
  50. void iRtI2C_WaitEEReady()
  51. {
  52. uint16_t cnt1 = 0, cnt2 = 0;
  53. /* Wait at least 5ms after writing a page */
  54. while (cnt2 < 2)
  55. {
  56. cnt1++;
  57. if (cnt1 == 10000)
  58. {
  59. cnt2++;
  60. cnt1 = 0;
  61. }
  62. }
  63. }
  64. int iRtI2C_PageWrite2EE(uint8_t devIndex, uint16_t devAddr, uint16_t memAddr, uint8_t *data, uint8_t count)
  65. {
  66. uint8_t state = (uint8_t)I2C_START;
  67. uint16_t timeoutCnt = 0;
  68. uint8_t i2c_timeout_flag = 0;
  69. uint8_t i2cBusResetCnt = 0;
  70. /* Write to EEPROM enable*/
  71. GPIO_OCTL(GPIOC) &= ~0x1000;
  72. /* Enable acknowledge */
  73. i2c_ack_config(I2Cs[devIndex].I2CBase , I2C_ACK_ENABLE);
  74. while(!(i2c_timeout_flag))
  75. {
  76. /* I2C process */
  77. switch(state)
  78. {
  79. case I2C_START:
  80. /* I2C master sends start signal only when the bus is idle */
  81. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_I2CBSY) != 0) && (timeoutCnt < I2C_TIME_OUT))
  82. {
  83. timeoutCnt++;
  84. }
  85. if(timeoutCnt < I2C_TIME_OUT)
  86. {
  87. i2c_start_on_bus(I2Cs[devIndex].I2CBase);
  88. timeoutCnt = 0;
  89. state = I2C_SEND_ADDRESS;
  90. }
  91. else
  92. {
  93. i2cBusResetCnt += iRtI2C_BusReset(devIndex);
  94. timeoutCnt = 0;
  95. state = I2C_START;
  96. //printf("i2c bus is busy in WRITE!\n");
  97. }
  98. break;
  99. case I2C_SEND_ADDRESS:
  100. /* I2C master sends START signal successfully */
  101. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_SBSEND) == 0) && (timeoutCnt < I2C_TIME_OUT))
  102. {
  103. timeoutCnt++;
  104. }
  105. if(timeoutCnt < I2C_TIME_OUT)
  106. {
  107. i2c_master_addressing(I2Cs[devIndex].I2CBase, devAddr, I2C_TRANSMITTER);
  108. timeoutCnt = 0;
  109. state = I2C_CLEAR_ADDRESS_FLAG;
  110. }
  111. else
  112. {
  113. timeoutCnt = 0;
  114. state = I2C_START;
  115. printf("i2c master sends start signal timeoutCnt in WRITE!\n");
  116. }
  117. break;
  118. case I2C_CLEAR_ADDRESS_FLAG:
  119. /* address flag set means i2c slave sends ACK */
  120. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND) == 0) && (timeoutCnt < I2C_TIME_OUT))
  121. {
  122. timeoutCnt++;
  123. }
  124. if(timeoutCnt < I2C_TIME_OUT)
  125. {
  126. i2c_flag_clear(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND);
  127. timeoutCnt = 0;
  128. state = I2C_TRANSMIT_DATA;
  129. }
  130. else
  131. {
  132. timeoutCnt = 0;
  133. state = I2C_START;
  134. //printf("i2c master clears address flag timeoutCnt in WRITE!\n");
  135. }
  136. break;
  137. case I2C_TRANSMIT_DATA:
  138. /* wait until the transmit data buffer is empty */
  139. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_TBE) == 0) && (timeoutCnt < I2C_TIME_OUT))
  140. {
  141. timeoutCnt++;
  142. }
  143. if(timeoutCnt < I2C_TIME_OUT) {
  144. /* send the EEPROM's internal address to write to : only one byte address */
  145. i2c_data_transmit(I2Cs[devIndex].I2CBase, memAddr);
  146. timeoutCnt = 0;
  147. }
  148. else
  149. {
  150. timeoutCnt = 0;
  151. state = I2C_START;
  152. //printf("i2c master sends EEPROM's internal address timeoutCnt in WRITE!\n");
  153. }
  154. /* wait until BTC bit is set */
  155. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_BTC) == 0) && (timeoutCnt < I2C_TIME_OUT)){
  156. timeoutCnt++;
  157. }
  158. if(timeoutCnt < I2C_TIME_OUT)
  159. {
  160. timeoutCnt = 0;
  161. }
  162. else
  163. {
  164. timeoutCnt = 0;
  165. state = I2C_START;
  166. //printf("i2c master sends data timeoutCnt in WRITE!\n");
  167. }
  168. while(count != 0)
  169. {
  170. count --;
  171. i2c_data_transmit(I2Cs[devIndex].I2CBase, *data);
  172. /* Point to the next byte to be written */
  173. data++;
  174. /* wait until BTC bit is set */
  175. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_BTC) == 0) && (timeoutCnt < I2C_TIME_OUT))
  176. {
  177. timeoutCnt++;
  178. }
  179. if(timeoutCnt < I2C_TIME_OUT)
  180. {
  181. timeoutCnt = 0;
  182. }
  183. else
  184. {
  185. timeoutCnt = 0;
  186. state = I2C_START;
  187. //printf("i2c master sends data timeoutCnt in WRITE!\n");
  188. }
  189. }
  190. timeoutCnt = 0;
  191. state = I2C_STOP;
  192. break;
  193. case I2C_STOP:
  194. /* send a stop condition to I2C bus */
  195. i2c_stop_on_bus(I2Cs[devIndex].I2CBase);
  196. /* I2C master sends STOP signal successfully */
  197. while((I2C_CTL0(I2Cs[devIndex].I2CBase) & I2C_CTL0_STOP) && (timeoutCnt < I2C_TIME_OUT))
  198. {
  199. timeoutCnt++;
  200. }
  201. if(timeoutCnt < I2C_TIME_OUT)
  202. {
  203. timeoutCnt = 0;
  204. state = I2C_COMPLETE;
  205. i2c_timeout_flag = 1;
  206. }
  207. else
  208. {
  209. timeoutCnt = 0;
  210. state = I2C_START;
  211. //printf("i2c master sends stop signal timeoutCnt in WRITE!\n");
  212. }
  213. break;
  214. default:
  215. state = I2C_START;
  216. i2c_timeout_flag = 1;
  217. timeoutCnt = 0;
  218. //printf("i2c master sends start signal in WRITE.\n");
  219. break;
  220. }
  221. if(i2cBusResetCnt > 10)
  222. {
  223. break;
  224. }
  225. }
  226. /* Write to EEPROM disable */
  227. GPIO_OCTL(GPIOC) |= 0x1000;
  228. if(state == I2C_COMPLETE)
  229. {
  230. return count;
  231. }
  232. else
  233. {
  234. return 0;
  235. }
  236. }
  237. /* ========================================================================== */
  238. /* ============================== API Functions ============================= */
  239. /* ========================================================================== */
  240. int iI2C_Write(uint8_t devIndex, uint16_t devAddr, uint16_t memAddr, uint8_t memAddrSize, uint8_t* data, uint16_t count)
  241. {
  242. uint8_t addr = 0, misalignedDataCnt = 0, pageCnt = 0, singleDataCnt = 0;
  243. uint16_t writeCompCnt = 0;
  244. if(memAddrSize == 0x8)
  245. {
  246. memAddr = memAddr & 0xFF;
  247. }
  248. addr = memAddr % HW_I2C_EE_PAGESIZE_BYTE;
  249. misalignedDataCnt = HW_I2C_EE_PAGESIZE_BYTE - addr;
  250. pageCnt = count / HW_I2C_EE_PAGESIZE_BYTE;
  251. singleDataCnt = count % HW_I2C_EE_PAGESIZE_BYTE;
  252. /* If memAddr is HW_I2C_EE_PAGESIZE_BYTE aligned */
  253. if (addr == 0)
  254. {
  255. while (pageCnt != 0)
  256. {
  257. pageCnt--;
  258. writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, HW_I2C_EE_PAGESIZE_BYTE);
  259. iRtI2C_WaitEEReady();
  260. memAddr += HW_I2C_EE_PAGESIZE_BYTE;
  261. data += HW_I2C_EE_PAGESIZE_BYTE;
  262. }
  263. if (singleDataCnt != 0)
  264. {
  265. writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, singleDataCnt);
  266. iRtI2C_WaitEEReady();
  267. }
  268. }
  269. else
  270. {
  271. /* If memAddr is not HW_I2C_EE_PAGESIZE_BYTE aligned */
  272. if(count < misalignedDataCnt)
  273. {
  274. writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, count);
  275. iRtI2C_WaitEEReady();
  276. }
  277. else
  278. {
  279. count -= misalignedDataCnt;
  280. pageCnt = count / HW_I2C_EE_PAGESIZE_BYTE;
  281. singleDataCnt = count % HW_I2C_EE_PAGESIZE_BYTE;
  282. /* Write misaligned data */
  283. if(misalignedDataCnt != 0)
  284. {
  285. writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, misalignedDataCnt);
  286. iRtI2C_WaitEEReady();
  287. memAddr += misalignedDataCnt;
  288. data += misalignedDataCnt;
  289. }
  290. /* Write page data */
  291. while(pageCnt != 0)
  292. {
  293. pageCnt --;
  294. writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, HW_I2C_EE_PAGESIZE_BYTE);
  295. iRtI2C_WaitEEReady();
  296. memAddr += HW_I2C_EE_PAGESIZE_BYTE;
  297. data += HW_I2C_EE_PAGESIZE_BYTE;
  298. }
  299. /* Write single data */
  300. if (singleDataCnt != 0)
  301. {
  302. writeCompCnt += iRtI2C_PageWrite2EE(devIndex, devAddr, memAddr, data, singleDataCnt);
  303. iRtI2C_WaitEEReady();
  304. }
  305. }
  306. }
  307. return writeCompCnt;
  308. }
  309. int iI2C_Read(uint8_t devIndex, uint16_t devAddr, uint16_t memAddr, uint8_t memAddrSize, uint8_t* data, uint16_t count)
  310. {
  311. uint8_t state = (uint8_t)I2C_START;
  312. uint8_t read_cycle = 0;
  313. uint16_t timeoutCnt = 0;
  314. uint8_t i2c_timeout_flag = 0;
  315. uint8_t i2cBusResetCnt = 0;
  316. /* enable acknowledge */
  317. i2c_ack_config(I2Cs[devIndex].I2CBase, I2C_ACK_ENABLE);
  318. while(i2c_timeout_flag ==0)
  319. {
  320. switch(state)
  321. {
  322. case I2C_START:
  323. if(RESET == read_cycle)
  324. {
  325. /* Disable I2C0 */
  326. i2c_disable(I2Cs[devIndex].I2CBase);
  327. /* Enable I2C0 */
  328. i2c_enable(I2Cs[devIndex].I2CBase);
  329. /* Enable acknowledge */
  330. i2c_ack_config(I2Cs[devIndex].I2CBase, I2C_ACK_ENABLE);
  331. /* I2C master sends start signal only when the bus is idle */
  332. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_I2CBSY) != 0) && (timeoutCnt < I2C_TIME_OUT))
  333. {
  334. timeoutCnt++;
  335. }
  336. if(timeoutCnt < I2C_TIME_OUT)
  337. {
  338. /* Send the start signal */
  339. i2c_start_on_bus(I2Cs[devIndex].I2CBase);
  340. timeoutCnt = 0;
  341. state = (uint8_t)I2C_SEND_ADDRESS;
  342. }
  343. else
  344. {
  345. i2cBusResetCnt += iRtI2C_BusReset(devIndex);
  346. timeoutCnt = 0;
  347. state = (uint8_t)I2C_START;
  348. }
  349. }
  350. else
  351. {
  352. i2c_start_on_bus(I2Cs[devIndex].I2CBase);
  353. timeoutCnt = 0;
  354. state = (uint8_t)I2C_SEND_ADDRESS;
  355. }
  356. break;
  357. case I2C_SEND_ADDRESS:
  358. /* I2C master sends START signal successfully */
  359. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_SBSEND) == 0) && (timeoutCnt < I2C_TIME_OUT))
  360. {
  361. timeoutCnt++;
  362. }
  363. if(timeoutCnt < I2C_TIME_OUT)
  364. {
  365. if(RESET == read_cycle)
  366. {
  367. i2c_master_addressing(I2Cs[devIndex].I2CBase, devAddr, I2C_TRANSMITTER);
  368. state = (uint8_t)I2C_CLEAR_ADDRESS_FLAG;
  369. }
  370. else
  371. {
  372. i2c_master_addressing(I2Cs[devIndex].I2CBase, devAddr, I2C_RECEIVER);
  373. state = (uint8_t)I2C_CLEAR_ADDRESS_FLAG;
  374. }
  375. timeoutCnt = 0;
  376. }
  377. else
  378. {
  379. timeoutCnt = 0;
  380. state = (uint8_t)I2C_START;
  381. read_cycle = 0;
  382. }
  383. break;
  384. case I2C_CLEAR_ADDRESS_FLAG:
  385. /* Address flag set means i2c slave sends ACK */
  386. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND) == 0) && (timeoutCnt < I2C_TIME_OUT))
  387. {
  388. timeoutCnt++;
  389. }
  390. if(timeoutCnt < I2C_TIME_OUT)
  391. {
  392. i2c_flag_clear(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND);
  393. timeoutCnt = 0;
  394. state = (uint8_t)I2C_TRANSMIT_DATA;
  395. }
  396. else
  397. {
  398. timeoutCnt = 0;
  399. state = (uint8_t)I2C_START;
  400. read_cycle = 0;
  401. }
  402. break;
  403. case I2C_TRANSMIT_DATA:
  404. if(RESET == read_cycle)
  405. {
  406. /* Wait until the transmit data buffer is empty */
  407. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_TBE) == 0) && (timeoutCnt < I2C_TIME_OUT))
  408. {
  409. timeoutCnt++;
  410. }
  411. if(timeoutCnt < I2C_TIME_OUT)
  412. {
  413. /* Send the EEPROM's internal address to write to : only one byte address */
  414. i2c_data_transmit(I2Cs[devIndex].I2CBase, memAddr);
  415. timeoutCnt = 0;
  416. }
  417. else
  418. {
  419. timeoutCnt = 0;
  420. state = (uint8_t)I2C_START;
  421. read_cycle = 0;
  422. }
  423. /* Wait until BTC bit is set */
  424. while((i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_BTC) == 0) && (timeoutCnt < I2C_TIME_OUT))
  425. {
  426. timeoutCnt++;
  427. }
  428. if(timeoutCnt < I2C_TIME_OUT)
  429. {
  430. timeoutCnt = 0;
  431. state = (uint8_t)I2C_START;
  432. read_cycle++;
  433. }
  434. else
  435. {
  436. timeoutCnt = 0;
  437. state = (uint8_t)I2C_START;
  438. read_cycle = 0;
  439. }
  440. }
  441. else
  442. {
  443. /* One byte master reception procedure (polling) */
  444. if(count < 2)
  445. {
  446. /* Disable acknowledge */
  447. i2c_ack_config(I2Cs[devIndex].I2CBase, I2C_ACK_DISABLE);
  448. /* Clear ADDSEND register by reading I2C_STAT0 then I2C_STAT1 register (I2C_STAT0 has already been read) */
  449. i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_ADDSEND);
  450. /* Send a stop condition to I2C bus*/
  451. i2c_stop_on_bus(I2Cs[devIndex].I2CBase);
  452. /* Wait for the byte to be received */
  453. while(i2c_flag_get(I2Cs[devIndex].I2CBase, I2C_FLAG_RBNE) == 0)
  454. {
  455. // do nothing
  456. }
  457. /* Read the byte received from the EEPROM */
  458. *data = i2c_data_receive(I2Cs[devIndex].I2CBase);
  459. /* Decrement the read bytes counter */
  460. count--;
  461. timeoutCnt = 0;
  462. state = (uint8_t)I2C_STOP;
  463. }
  464. else
  465. { /* More than one byte master reception procedure (DMA) */
  466. dma_transfer_number_config(DMA0, DMA_CH6, count);
  467. DMA_CH6MADDR(DMA0) = (uint32_t)data;
  468. i2c_dma_last_transfer_config(I2Cs[devIndex].I2CBase, I2C_DMALST_ON);
  469. /* Enable I2Cs[devIndex].I2CBase DMA */
  470. i2c_dma_config(I2Cs[devIndex].I2CBase, I2C_DMA_ON);
  471. /* Enable DMA0 channel5 */
  472. dma_channel_enable(DMA0, DMA_CH6);
  473. /* Wait until BTC bit is set */
  474. while(dma_flag_get(DMA0, DMA_CH6, DMA_FLAG_FTF) == 0)
  475. {}
  476. state = (uint8_t)I2C_STOP;
  477. }
  478. }
  479. break;
  480. case I2C_STOP:
  481. /* Send a stop condition to I2C bus */
  482. i2c_stop_on_bus(I2Cs[devIndex].I2CBase);
  483. /* I2C master sends STOP signal successfully */
  484. while((I2C_CTL0(I2Cs[devIndex].I2CBase) & I2C_CTL0_STOP) && (timeoutCnt < I2C_TIME_OUT))
  485. {
  486. timeoutCnt++;
  487. }
  488. if(timeoutCnt < I2C_TIME_OUT)
  489. {
  490. timeoutCnt = 0;
  491. i2c_timeout_flag = 1;
  492. state = (uint8_t)I2C_COMPLETE;
  493. read_cycle = 0;
  494. /* Disable DMA0 CH6 */
  495. dma_channel_disable(DMA0, DMA_CH6);
  496. /* Disable I2Cs[devIndex].I2CBase DMA */
  497. i2c_dma_config(I2Cs[devIndex].I2CBase, I2C_DMA_OFF);
  498. i2c_dma_last_transfer_config(I2Cs[devIndex].I2CBase, I2C_DMALST_OFF);
  499. }
  500. else
  501. {
  502. timeoutCnt = 0;
  503. state = (uint8_t)I2C_START;
  504. read_cycle = 0;
  505. }
  506. break;
  507. default:
  508. state = (uint8_t)I2C_START;
  509. read_cycle = 0;
  510. i2c_timeout_flag = 1;
  511. timeoutCnt = 0;
  512. break;
  513. }
  514. if(i2cBusResetCnt > 10)
  515. {
  516. break;
  517. }
  518. }
  519. if(state == I2C_COMPLETE)
  520. {
  521. return count;
  522. }
  523. else
  524. {
  525. return 0;
  526. }
  527. }