test_i2c.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-12-30 CDT first version
  9. */
  10. /*
  11. * 程序清单:这是 I2C 设备使用例程。
  12. * 例程导出了 i2c_sample 到控制终端。
  13. * 命令调用格式:i2c_sample
  14. * 命令解释:
  15. * 程序功能:查找I2C模块,读写I2C设备。
  16. * 注意:测试要用逻辑分析仪或示波器抓取信号
  17. */
  18. #include <rtthread.h>
  19. #include <rtdevice.h>
  20. #include <board.h>
  21. /*
  22. * to readout/write from/into i2c device, user could use this macro to choice
  23. * either rt_i2c_master_send & rt_i2c_master_recv or rt_i2c_transfer
  24. */
  25. #if defined(RT_USING_I2C)
  26. #define USING_RT_I2C_TRANSFER
  27. /* defined EEPROM */
  28. #if defined(HC32F472) || defined(HC32F460) || defined(HC32F4A0) || defined(HC32F448) || defined(HC32F4A8) || \
  29. defined(HC32F334)
  30. #define EE_DEV_ADDR 0x50
  31. #define EE_TEST_PAGE_CNT 8 // Test 8 pages
  32. #endif
  33. /* define EEPROM hardware */
  34. #if defined(HC32F472) || defined(HC32F460) || defined(HC32F448) || defined(HC32F4A8) || defined(HC32F334)
  35. #define EE24C256
  36. #elif defined(HC32F4A0)
  37. #define EE24C02
  38. #endif
  39. #if defined (EE24C1024)
  40. #define EE_PAGE_SIZE 256 // 24C1024
  41. #define EE_WORD_ADR_SIZE 2 // 2 word addr
  42. #elif defined (EE24C256)
  43. #define EE_PAGE_SIZE 64 // 24C256
  44. #define EE_WORD_ADR_SIZE 2 // 2 word addr
  45. #elif defined (EE24C02)
  46. #define EE_PAGE_SIZE 8 // 24C02
  47. #define EE_WORD_ADR_SIZE 1 // 1 word addr
  48. #endif
  49. /* device information */
  50. #if defined(HC32F472) || defined(HC32F4A0) || defined(HC32F448) || defined(HC32F4A8) || defined(HC32F334)
  51. #define HW_I2C_DEV "i2c1"
  52. #define SW_I2C_DEV "i2c1_sw"
  53. #elif defined(HC32F460)
  54. #define HW_I2C_DEV "i2c3"
  55. #define SW_I2C_DEV "i2c1_sw"
  56. #endif
  57. /* this API is for eeprom size is smaller than 256Bytes */
  58. static void eeprom_page_write(uint32_t page, uint8_t *pBuf)
  59. {
  60. struct rt_i2c_bus_device *hc32_i2c = RT_NULL;
  61. uint8_t TxBuf[EE_PAGE_SIZE + EE_WORD_ADR_SIZE] = {0};
  62. struct rt_i2c_msg msg[1];
  63. #if defined (BSP_USING_I2C_HW)
  64. hc32_i2c = rt_i2c_bus_device_find(HW_I2C_DEV); //hw i2c
  65. #else
  66. hc32_i2c = rt_i2c_bus_device_find(SW_I2C_DEV); //sw i2c
  67. #endif
  68. /* START --- ADR_W --- WORD_ADR(1 byte) --- DATAn --- STOP */
  69. if (EE_WORD_ADR_SIZE == 2)
  70. {
  71. TxBuf[0] = (page * EE_PAGE_SIZE) / 256; // addrH
  72. TxBuf[1] = page * EE_PAGE_SIZE; // addrL
  73. }
  74. else
  75. {
  76. TxBuf[0] = page * EE_PAGE_SIZE;
  77. }
  78. for (int i = 0; i < EE_PAGE_SIZE; i++) // data fill
  79. {
  80. TxBuf[i + EE_WORD_ADR_SIZE] = *pBuf++;
  81. }
  82. msg[0].addr = EE_DEV_ADDR;
  83. msg[0].flags = RT_I2C_WR;
  84. msg[0].len = EE_PAGE_SIZE + EE_WORD_ADR_SIZE;
  85. msg[0].buf = TxBuf;
  86. #if defined(USING_RT_I2C_TRANSFER)
  87. rt_i2c_transfer(hc32_i2c, &msg[0], 1);
  88. #else
  89. rt_i2c_master_send(hc32_i2c, EE_DEV_ADDR, RT_I2C_NO_STOP, TxBuf, msg[0].len / 2);
  90. rt_i2c_master_send(hc32_i2c, EE_DEV_ADDR, RT_I2C_NO_START, TxBuf + msg[0].len / 2, msg[0].len - msg[0].len / 2);
  91. #endif
  92. /* write cycle 5ms */
  93. rt_thread_mdelay(5);
  94. }
  95. static void eeprom_page_read(uint32_t page, uint8_t *pBuf)
  96. {
  97. struct rt_i2c_bus_device *hc32_i2c = RT_NULL;
  98. uint8_t readAddr[EE_WORD_ADR_SIZE];
  99. #if defined(USING_RT_I2C_TRANSFER)
  100. struct rt_i2c_msg msg[2];
  101. #endif
  102. #if defined (BSP_USING_I2C_HW)
  103. hc32_i2c = rt_i2c_bus_device_find(HW_I2C_DEV); //hw i2c
  104. #else
  105. hc32_i2c = rt_i2c_bus_device_find(SW_I2C_DEV); //sw i2c
  106. #endif
  107. if (EE_WORD_ADR_SIZE == 2)
  108. {
  109. readAddr[0] = (page * EE_PAGE_SIZE) / 256; // addrH
  110. readAddr[1] = page * EE_PAGE_SIZE; // addrL
  111. }
  112. else
  113. {
  114. readAddr[0] = page * EE_PAGE_SIZE;
  115. }
  116. #if defined(USING_RT_I2C_TRANSFER)
  117. msg[0].addr = EE_DEV_ADDR;
  118. msg[0].flags = RT_I2C_WR;
  119. msg[0].len = EE_WORD_ADR_SIZE;
  120. msg[0].buf = readAddr;
  121. msg[1].addr = EE_DEV_ADDR;
  122. msg[1].flags = RT_I2C_RD;
  123. msg[1].len = EE_PAGE_SIZE;
  124. msg[1].buf = pBuf;
  125. rt_i2c_transfer(hc32_i2c, &msg[0], 2);
  126. #else
  127. rt_i2c_master_send(hc32_i2c, EE_DEV_ADDR, RT_I2C_NO_STOP, readAddr, EE_WORD_ADR_SIZE);
  128. rt_i2c_master_recv(hc32_i2c, EE_DEV_ADDR, 0, pBuf, EE_PAGE_SIZE);
  129. #endif
  130. }
  131. void eeprom_test(void)
  132. {
  133. uint32_t page, i;
  134. uint32_t compareValueDiff = 0;
  135. static rt_uint8_t trans_buf[EE_PAGE_SIZE * EE_TEST_PAGE_CNT];
  136. static rt_uint8_t recv_buf[EE_PAGE_SIZE * EE_TEST_PAGE_CNT];
  137. /* write e2 */
  138. for (i = 0; i < sizeof(trans_buf); i++)
  139. {
  140. trans_buf[i] = i;
  141. }
  142. for (page = 0; page < EE_TEST_PAGE_CNT; page++)
  143. {
  144. eeprom_page_write(page, trans_buf + EE_PAGE_SIZE * page);
  145. }
  146. /* read e2 */
  147. for (i = 0; i < sizeof(trans_buf); i++)
  148. {
  149. recv_buf[i] = 0;
  150. }
  151. for (page = 0; page < EE_TEST_PAGE_CNT; page++)
  152. {
  153. eeprom_page_read(page, recv_buf + EE_PAGE_SIZE * page);
  154. }
  155. /* compare e2 */
  156. for (i = 0; i < sizeof(recv_buf); i++)
  157. {
  158. if (trans_buf[i] != recv_buf[i])
  159. {
  160. compareValueDiff = 1;
  161. break;
  162. }
  163. }
  164. if (compareValueDiff == 0)
  165. {
  166. rt_kprintf("eeprom test ok!\r\n");
  167. }
  168. else
  169. {
  170. rt_kprintf("eeprom test failed!\r\n");
  171. }
  172. }
  173. /* TCA9539 device */
  174. #if defined(HC32F472) || defined(HC32F4A0) || defined(HC32F448) || defined(HC32F4A8)
  175. /* TCA9539 define */
  176. #define TCA9539_DEV_ADDR (0x74) // TCA9539 chip address on I2C bus
  177. #define TCA9539_REG_INPUT_PORT0 (0x00U)
  178. #define TCA9539_REG_INPUT_PORT1 (0x01U)
  179. #define TCA9539_REG_OUTPUT_PORT0 (0x02U)
  180. #define TCA9539_REG_OUTPUT_PORT1 (0x03U)
  181. #define TCA9539_REG_INVERT_PORT0 (0x04U)
  182. #define TCA9539_REG_INVERT_PORT1 (0x05U)
  183. #define TCA9539_REG_CONFIG_PORT0 (0x06U)
  184. #define TCA9539_REG_CONFIG_PORT1 (0x07U)
  185. void tca9539_test(void)
  186. {
  187. struct rt_i2c_bus_device *hc32_i2c = RT_NULL;
  188. static rt_uint8_t send_buf0[0x10];
  189. static rt_uint8_t send_buf1[0x10], recv_buf1[0x10];
  190. struct rt_i2c_msg msg[2];
  191. #if defined (BSP_USING_I2C_HW)
  192. hc32_i2c = rt_i2c_bus_device_find(HW_I2C_DEV); //hw i2c
  193. #else
  194. hc32_i2c = rt_i2c_bus_device_find(SW_I2C_DEV); //sw i2c
  195. #endif
  196. RT_ASSERT(hc32_i2c != RT_NULL);
  197. send_buf0[0] = TCA9539_REG_CONFIG_PORT1;
  198. send_buf0[1] = 0xFF;
  199. msg[0].addr = TCA9539_DEV_ADDR;
  200. msg[0].flags = RT_I2C_WR;
  201. msg[0].len = 2;
  202. msg[0].buf = send_buf0;
  203. rt_i2c_transfer(hc32_i2c, &msg[0], 1);
  204. send_buf0[0] = TCA9539_REG_OUTPUT_PORT1;
  205. send_buf0[1] = 0xAC;
  206. msg[1].addr = TCA9539_DEV_ADDR;
  207. msg[1].flags = RT_I2C_WR;
  208. msg[1].len = 2;
  209. msg[1].buf = send_buf0;
  210. rt_i2c_transfer(hc32_i2c, &msg[1], 1);
  211. /* read */
  212. send_buf1[0] = TCA9539_REG_OUTPUT_PORT1;
  213. msg[0].addr = TCA9539_DEV_ADDR;
  214. msg[0].flags = RT_I2C_WR;
  215. msg[0].len = 1;
  216. msg[0].buf = send_buf1;
  217. msg[1].addr = TCA9539_DEV_ADDR;
  218. msg[1].flags = RT_I2C_RD;
  219. msg[1].len = 1;
  220. msg[1].buf = recv_buf1;
  221. rt_i2c_transfer(hc32_i2c, &msg[0], 2);
  222. if (recv_buf1[0] == 0xAC)
  223. {
  224. rt_kprintf("tca9539 test ok!\r\n");
  225. }
  226. else
  227. {
  228. rt_kprintf("tca9539 test failed!\r\n");
  229. }
  230. }
  231. #endif
  232. static void i2c_sample(int argc, char *argv[])
  233. {
  234. eeprom_test();
  235. #if defined(HC32F472) || defined(HC32F4A0) || defined(HC32F448) || defined(HC32F4A8)
  236. tca9539_test();
  237. #endif
  238. }
  239. MSH_CMD_EXPORT(i2c_sample, i2c sample);
  240. #endif/* RT_USING_I2C */
  241. /*
  242. EOF
  243. */