drv_hwi2c_ch32f20x.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-01-21 charlown first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <rthw.h>
  13. #include "board.h"
  14. #include "drv_hwi2c.h"
  15. #ifdef BSP_USING_HWI2C
  16. #define LOG_TAG "drv.hwi2c"
  17. #include "drv_log.h"
  18. #define TIMEOUT 0x0FF
  19. struct i2c_bus_device
  20. {
  21. struct rt_i2c_bus_device parent;
  22. I2C_TypeDef *periph;
  23. };
  24. #ifdef BSP_USING_HWI2C1
  25. struct i2c_bus_device i2c_bus1;
  26. #endif
  27. #ifdef BSP_USING_HWI2C2
  28. struct i2c_bus_device i2c_bus2;
  29. #endif
  30. static int ch32f2_i2c_read(I2C_TypeDef *i2c_periph,
  31. rt_uint8_t flags,
  32. rt_uint16_t slave_address,
  33. rt_uint8_t *p_buffer,
  34. rt_uint16_t data_byte)
  35. {
  36. rt_uint32_t try;
  37. if (flags & RT_I2C_ADDR_10BIT)
  38. {
  39. //fixme
  40. }
  41. else
  42. {
  43. //7 bit address
  44. try = 0;
  45. while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY) != RESET)
  46. {
  47. if (try == TIMEOUT)
  48. {
  49. LOG_E("i2c bus read getflag timeout! \n");
  50. return -1;
  51. }
  52. try++;
  53. };
  54. I2C_GenerateSTART(i2c_periph, ENABLE);
  55. try = 0;
  56. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT))
  57. {
  58. if (try == TIMEOUT)
  59. {
  60. LOG_E("i2c bus read checkevent timeout! \n");
  61. return -1;
  62. }
  63. try++;
  64. };
  65. I2C_Send7bitAddress(i2c_periph, (slave_address << 1), I2C_Direction_Transmitter);
  66. try = 0;
  67. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  68. {
  69. if (try == TIMEOUT)
  70. {
  71. LOG_E("i2c bus read checkevent timeout! \n");
  72. return -1;
  73. }
  74. try++;
  75. };
  76. I2C_GenerateSTART(i2c_periph, ENABLE);
  77. try = 0;
  78. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT))
  79. {
  80. if (try == TIMEOUT)
  81. {
  82. LOG_E("i2c bus read checkevent timeout! \n");
  83. return -1;
  84. }
  85. try++;
  86. };
  87. I2C_Send7bitAddress(i2c_periph, (slave_address << 1), I2C_Direction_Receiver);
  88. try = 0;
  89. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  90. {
  91. if (try == TIMEOUT)
  92. {
  93. LOG_E("i2c bus read checkevent timeout! \n");
  94. return -1;
  95. }
  96. try++;
  97. };
  98. if (data_byte == 1)
  99. {
  100. try = 0;
  101. while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_RXNE) == RESET)
  102. {
  103. if (try == TIMEOUT)
  104. {
  105. LOG_E("i2c bus read checkevent timeout! \n");
  106. return -1;
  107. }
  108. try++;
  109. };
  110. I2C_AcknowledgeConfig(i2c_periph, DISABLE);
  111. *p_buffer = I2C_ReceiveData(i2c_periph);
  112. I2C_GenerateSTOP(i2c_periph, ENABLE);
  113. }
  114. else
  115. {
  116. try = 0;
  117. while (data_byte)
  118. {
  119. if (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_RXNE) == RESET)
  120. {
  121. *p_buffer = I2C_ReceiveData(i2c_periph);
  122. p_buffer++;
  123. data_byte--;
  124. try = 0;
  125. if (data_byte == 1)
  126. {
  127. I2C_AcknowledgeConfig(i2c_periph, DISABLE);
  128. I2C_GenerateSTOP(i2c_periph, ENABLE);
  129. }
  130. }
  131. if (try == TIMEOUT)
  132. {
  133. LOG_E("i2c bus read checkevent timeout! \n");
  134. return -1;
  135. }
  136. try++;
  137. }
  138. }
  139. }
  140. return 0;
  141. }
  142. static int ch32f2_i2c_write(I2C_TypeDef *i2c_periph,
  143. rt_uint8_t flags,
  144. rt_uint16_t slave_address,
  145. rt_uint8_t *p_buffer,
  146. rt_uint16_t data_byte)
  147. {
  148. rt_uint32_t try;
  149. if (flags & RT_I2C_ADDR_10BIT)
  150. {
  151. //fixme
  152. }
  153. else
  154. {
  155. //7 bit address
  156. try = 0;
  157. while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_BUSY) != RESET)
  158. {
  159. if (try == TIMEOUT)
  160. {
  161. LOG_E("i2c bus write getflag timeout! \n");
  162. return -1;
  163. }
  164. try++;
  165. };
  166. I2C_GenerateSTART(i2c_periph, ENABLE);
  167. try = 0;
  168. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT))
  169. {
  170. if (try == TIMEOUT)
  171. {
  172. LOG_E("i2c bus write checkevent timeout! \n");
  173. return -1;
  174. }
  175. try++;
  176. };
  177. I2C_Send7bitAddress(i2c_periph, (slave_address << 1), I2C_Direction_Transmitter);
  178. try = 0;
  179. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  180. {
  181. if (try == TIMEOUT)
  182. {
  183. LOG_E("i2c bus write checkevent timeout! \n");
  184. return -1;
  185. }
  186. try++;
  187. };
  188. I2C_GenerateSTART(i2c_periph, ENABLE);
  189. try = 0;
  190. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_MODE_SELECT))
  191. {
  192. if (try == TIMEOUT)
  193. {
  194. LOG_E("i2c bus write checkevent timeout! \n");
  195. return -1;
  196. }
  197. try++;
  198. };
  199. I2C_Send7bitAddress(i2c_periph, (slave_address << 1), I2C_Direction_Transmitter);
  200. try = 0;
  201. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  202. {
  203. if (try == TIMEOUT)
  204. {
  205. LOG_E("i2c bus write checkevent timeout! \n");
  206. return -1;
  207. }
  208. try++;
  209. };
  210. try = 0;
  211. while (I2C_GetFlagStatus(i2c_periph, I2C_FLAG_TXE) == RESET)
  212. {
  213. if (try == TIMEOUT)
  214. {
  215. LOG_E("i2c bus write checkevent timeout! \n");
  216. return -1;
  217. }
  218. try++;
  219. };
  220. while (data_byte)
  221. {
  222. I2C_SendData(i2c_periph, *p_buffer);
  223. p_buffer++;
  224. data_byte--;
  225. try = 0;
  226. while (!I2C_CheckEvent(i2c_periph, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  227. {
  228. if (try == TIMEOUT)
  229. {
  230. LOG_E("i2c bus write checkevent timeout! \n");
  231. return -1;
  232. }
  233. try++;
  234. };
  235. }
  236. I2C_GenerateSTOP(i2c_periph, ENABLE);
  237. }
  238. return 0;
  239. }
  240. static rt_size_t ch32f2_master_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
  241. {
  242. struct rt_i2c_msg *msg;
  243. struct i2c_bus_device *i2c_bus_dev;
  244. rt_uint32_t index;
  245. i2c_bus_dev = (struct i2c_bus_device *)bus;
  246. for (index = 0; index < num; index++)
  247. {
  248. msg = &msgs[index];
  249. if (msg->flags & RT_I2C_RD)
  250. {
  251. if (ch32f2_i2c_read(i2c_bus_dev->periph, msg->flags, msg->addr, msg->buf, msg->len) != 0)
  252. {
  253. LOG_E("i2c bus write failed,i2c bus stop!");
  254. return 0;
  255. }
  256. }
  257. else
  258. {
  259. if (ch32f2_i2c_write(i2c_bus_dev->periph, msg->flags, msg->addr, msg->buf, msg->len) != 0)
  260. {
  261. LOG_E("i2c bus write failed,i2c bus stop!");
  262. return 0;
  263. }
  264. }
  265. }
  266. return index;
  267. }
  268. const struct rt_i2c_bus_device_ops ch32f2_i2c_ops = {
  269. .master_xfer = ch32f2_master_xfer,
  270. .slave_xfer = RT_NULL,
  271. .i2c_bus_control = RT_NULL,
  272. };
  273. int rt_hw_i2c_init(void)
  274. {
  275. int result = RT_EOK;
  276. #ifdef BSP_USING_HWI2C1
  277. i2c_bus1.periph = I2C1;
  278. ch32f2_i2c_clock_and_io_init(i2c_bus1.periph);
  279. ch32f2_i2c_config(i2c_bus1.periph);
  280. i2c_bus1.parent.ops = &ch32f2_i2c_ops;
  281. result = rt_i2c_bus_device_register(&i2c_bus1.parent, "hwi2c1");
  282. if (result != RT_EOK)
  283. {
  284. return result;
  285. }
  286. #endif
  287. #ifdef BSP_USING_HWI2C2
  288. i2c_bus2.periph = I2C2;
  289. ch32f2_i2c_clock_and_io_init(i2c_bus2.periph);
  290. ch32f2_i2c_config(i2c_bus2.periph);
  291. i2c_bus2.parent.ops = &ch32f2_i2c_ops;
  292. rt_i2c_bus_device_register(&i2c_bus2.parent, "hwi2c2");
  293. if (result != RT_EOK)
  294. {
  295. return result;
  296. }
  297. #endif
  298. return RT_EOK;
  299. }
  300. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  301. #endif /* BSP_USING_HWI2C */