drv_i2c.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-10-23 yuzrain the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <rtdbg.h>
  13. #include "board.h"
  14. #include "drv_i2c.h"
  15. #include "md_i2c.h"
  16. #include "md_gpio.h"
  17. #ifdef RT_USING_I2C
  18. #define TIMEOUT 0xF
  19. /* Define I2C hardware SCL timeout */
  20. #define I2C_TIMING_48MHZ_CLK100KHZ ((0xBU<<28)|(4<<20)|(2<<16)|(0xF<<8)|(0x13))
  21. /**
  22. * @brief: I2C receive.
  23. * @param: i2cx, pointer to the I2Cx
  24. * @param: addr, address
  25. * @param: buf, send data buffer
  26. * @param: len, the length of buf
  27. * @param: timout, timeout
  28. * @retval: rt_err_t
  29. */
  30. static rt_err_t __i2c_master_recv(I2C_TypeDef *i2cx, rt_uint16_t addr,
  31. rt_uint8_t *buf, rt_uint16_t len, rt_uint32_t timout)
  32. {
  33. rt_uint32_t rt_timout;
  34. //
  35. // Config I2C transfer mode
  36. //
  37. md_i2c_set_con2_add10(i2cx, MD_I2C_ADDRESSINGMODE_7BIT);
  38. /* Config slaver address */
  39. md_i2c_set_con2_sadd(i2cx, addr);
  40. /* Config data size */
  41. md_i2c_set_con2_nbytes(i2cx, len);
  42. /* Reset TX FIFO */
  43. md_i2c_set_fcon_txfrst(i2cx, MD_I2C_TXFIFO_RESET);
  44. /* Config mode */
  45. md_i2c_set_con2_rd_wrn(i2cx, MD_I2C_MASTER_READ);
  46. /* Config auto-reload */
  47. md_i2c_set_con2_reload(i2cx, MD_I2C_NORELOAD_MODE);
  48. /* When NBYTES is matched, the communication will be automatically stop */
  49. md_i2c_set_con2_autoend(i2cx, MD_I2C_AUTOEND_MODE);
  50. /* Start the I2C communication */
  51. md_i2c_set_con2_start(i2cx, MD_I2C_START_GENERATION);
  52. while (len > 0)
  53. {
  54. /* Wait Rx FIFO non-empty */
  55. rt_timout = timout;
  56. while (md_i2c_is_active_stat_rxe(i2cx) && (--rt_timout));
  57. if (rt_timout == 0)
  58. return RT_ETIMEOUT;
  59. *buf++ = md_i2c_recv(i2cx);
  60. len--;
  61. }
  62. return RT_EOK;
  63. }
  64. /**
  65. * @brief: I2C send.
  66. * @param: i2cx, pointer to the I2Cx
  67. * @param: addr, address
  68. * @param: buf, send data buffer
  69. * @param: len, the length of buf
  70. * @param: timout, timeout
  71. * @retval: rt_err_t
  72. */
  73. static rt_err_t __i2c_master_send(I2C_TypeDef *i2cx, rt_uint16_t addr,
  74. rt_uint8_t *buf, rt_uint16_t len, rt_uint32_t timout)
  75. {
  76. rt_uint32_t rt_timout;
  77. rt_uint8_t index;
  78. //
  79. // Config I2C transfer mode
  80. //
  81. md_i2c_set_con2_add10(i2cx, MD_I2C_ADDRESSINGMODE_7BIT);
  82. /* Config slaver address */
  83. md_i2c_set_con2_sadd(i2cx, addr);
  84. /* Config data size */
  85. md_i2c_set_con2_nbytes(i2cx, len);
  86. /* Reset TX FIFO */
  87. md_i2c_set_fcon_txfrst(i2cx, MD_I2C_TXFIFO_RESET);
  88. /* Config mode */
  89. md_i2c_set_con2_rd_wrn(i2cx, MD_I2C_MASTER_WRITE);
  90. /* Enable auto-end */
  91. md_i2c_set_con2_autoend(i2cx, MD_I2C_AUTOEND_MODE);
  92. //
  93. // Check if the bus is busy
  94. //
  95. /* Wait bus to be ready */
  96. rt_timout = timout;
  97. while ((READ_BIT(i2cx->STAT, I2C_STAT_BUSY_MSK) == I2C_STAT_BUSY_MSK) && (--rt_timout));
  98. if (rt_timout == 0)
  99. return RT_EBUSY;
  100. //
  101. // Start to send
  102. //
  103. if (len <= 8)
  104. {
  105. for (index = 0; index < len; index++)
  106. md_i2c_send(i2cx, *buf++);
  107. len = 0;
  108. }
  109. else
  110. {
  111. for (index = 0; index < 8; index++)
  112. md_i2c_send(i2cx, *buf++);
  113. len -= 8;
  114. }
  115. /* Start the I2C communication */
  116. md_i2c_set_con2_start(i2cx, MD_I2C_START_GENERATION);
  117. while (len > 0)
  118. {
  119. rt_timout = timout;
  120. while (md_i2c_is_active_stat_txf(i2cx) && (--rt_timout));
  121. if (rt_timout == 0)
  122. return RT_ETIMEOUT;
  123. md_i2c_send(i2cx, *buf++);
  124. len--;
  125. }
  126. return RT_EOK;
  127. }
  128. static rt_size_t es32f0_master_xfer(struct rt_i2c_bus_device *bus,
  129. struct rt_i2c_msg msgs[],
  130. rt_uint32_t num)
  131. {
  132. struct rt_i2c_msg *msg;
  133. rt_uint32_t i;
  134. rt_err_t ret = RT_ERROR;
  135. for (i = 0; i < num; i++)
  136. {
  137. msg = &msgs[i];
  138. if (msg->flags & RT_I2C_RD)
  139. {
  140. if (__i2c_master_recv(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0)
  141. {
  142. LOG_E("i2c bus write failed,i2c bus stop!\n");
  143. goto out;
  144. }
  145. }
  146. else
  147. {
  148. if (__i2c_master_send(bus->priv, msg->addr << 1, msg->buf, msg->len, TIMEOUT) != 0)
  149. {
  150. LOG_E("i2c bus write failed,i2c bus stop!\n");
  151. goto out;
  152. }
  153. }
  154. }
  155. ret = i;
  156. out:
  157. LOG_E("send stop condition\n");
  158. return ret;
  159. }
  160. const struct rt_i2c_bus_device_ops es32f0_i2c_ops =
  161. {
  162. es32f0_master_xfer,
  163. RT_NULL,
  164. RT_NULL,
  165. };
  166. static void _i2c_init(void)
  167. {
  168. md_i2c_inittypedef I2C_Init =
  169. {
  170. .Timing = CLK100kHz48M,
  171. .Address1 = 0x55 << 1,
  172. .AddrSize = MD_I2C_ADDRESSINGMODE_7BIT,
  173. .DualAddressMode = MD_I2C_DUALADDRESS_DISABLE,
  174. .Address2 = 0xAA,
  175. .Address2Masks = MD_I2C_ADDR2_NOMASK
  176. };
  177. #ifdef BSP_USING_I2C1
  178. /* Open I2C clock */
  179. SET_BIT(RCU->APB1EN, RCU_APB1EN_I2C1EN_MSK);
  180. /* GPIO configuration */
  181. md_gpio_set_pull (GPIOC, MD_GPIO_PIN_12, MD_GPIO_PULL_UP);
  182. md_gpio_set_pull (GPIOD, MD_GPIO_PIN_2, MD_GPIO_PULL_UP);
  183. md_gpio_set_output_type (GPIOC, MD_GPIO_PIN_12, MD_GPIO_OUTPUT_OPENDRAIN);
  184. md_gpio_set_output_type (GPIOD, MD_GPIO_PIN_2, MD_GPIO_OUTPUT_OPENDRAIN);
  185. md_gpio_set_mode (GPIOC, MD_GPIO_PIN_12, MD_GPIO_MODE_FUNCTION);
  186. md_gpio_set_mode (GPIOD, MD_GPIO_PIN_2, MD_GPIO_MODE_FUNCTION);
  187. md_gpio_set_function8_15(GPIOC, MD_GPIO_PIN_12, MD_GPIO_AF1);
  188. md_gpio_set_function0_7 (GPIOD, MD_GPIO_PIN_2, MD_GPIO_AF1);
  189. //
  190. // Config I2C
  191. //
  192. md_i2c_init(I2C1, &I2C_Init);
  193. #endif
  194. #ifdef BSP_USING_I2C2
  195. /* Open I2C clock */
  196. SET_BIT(RCU->APB1EN, RCU_APB1EN_I2C2EN_MSK);
  197. /* GPIO configuration */
  198. md_gpio_set_pull (GPIOB, MD_GPIO_PIN_10, MD_GPIO_PULL_UP);
  199. md_gpio_set_pull (GPIOB, MD_GPIO_PIN_11, MD_GPIO_PULL_UP);
  200. md_gpio_set_output_type (GPIOB, MD_GPIO_PIN_10, MD_GPIO_OUTPUT_OPENDRAIN);
  201. md_gpio_set_output_type (GPIOB, MD_GPIO_PIN_11, MD_GPIO_OUTPUT_OPENDRAIN);
  202. md_gpio_set_mode (GPIOB, MD_GPIO_PIN_10, MD_GPIO_MODE_FUNCTION);
  203. md_gpio_set_mode (GPIOB, MD_GPIO_PIN_11, MD_GPIO_MODE_FUNCTION);
  204. md_gpio_set_function8_15(GPIOB, MD_GPIO_PIN_10, MD_GPIO_AF1);
  205. md_gpio_set_function8_15(GPIOB, MD_GPIO_PIN_11, MD_GPIO_AF1);
  206. //
  207. // Config I2C
  208. //
  209. md_i2c_init(I2C2, &I2C_Init);
  210. #endif
  211. }
  212. #ifdef BSP_USING_I2C2
  213. static struct rt_i2c_bus_device i2c_device2;
  214. #endif
  215. #ifdef BSP_USING_I2C1
  216. static struct rt_i2c_bus_device i2c_device1;
  217. #endif
  218. int rt_hw_i2c_init(void)
  219. {
  220. _i2c_init();
  221. #ifdef BSP_USING_I2C2
  222. /* define i2c Instance */
  223. rt_memset((void *)&i2c_device2, 0, sizeof(struct rt_i2c_bus_device));
  224. i2c_device2.ops = &es32f0_i2c_ops;
  225. i2c_device2.priv = I2C2;
  226. rt_i2c_bus_device_register(&i2c_device2, "i2c2");
  227. #endif
  228. #ifdef BSP_USING_I2C1
  229. /* define i2c Instance */
  230. rt_memset((void *)&i2c_device1, 0, sizeof(struct rt_i2c_bus_device));
  231. i2c_device1.ops = &es32f0_i2c_ops;
  232. i2c_device1.priv = I2C1;
  233. rt_i2c_bus_device_register(&i2c_device1, "i2c1");
  234. #endif
  235. return RT_EOK;
  236. }
  237. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  238. #endif