drv_i2c.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-08-21 heyuanjie87 first version
  9. * 2023-03-31 Vandoul formatting code.
  10. */
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include "board.h"
  14. #include "i2c.h"
  15. #include "gpiohs.h"
  16. #include "utils.h"
  17. #include "sleep.h"
  18. #include "fpioa.h"
  19. #ifdef RT_USING_I2C
  20. #ifndef BSP_I2C0_SCL_PIN
  21. #define BSP_I2C0_SCL_PIN 0
  22. #endif
  23. #ifndef BSP_I2C0_SDA_PIN
  24. #define BSP_I2C0_SDA_PIN 1
  25. #endif
  26. #ifndef BSP_I2C1_SCL_PIN
  27. #define BSP_I2C1_SCL_PIN 30
  28. #endif
  29. #ifndef BSP_I2C1_SDA_PIN
  30. #define BSP_I2C1_SDA_PIN 31
  31. #endif
  32. #ifndef BSP_I2C2_SCL_PIN
  33. #define BSP_I2C2_SCL_PIN 4
  34. #endif
  35. #ifndef BSP_I2C2_SDA_PIN
  36. #define BSP_I2C2_SDA_PIN 5
  37. #endif
  38. static rt_err_t ki2c_send(
  39. volatile i2c_t *i2c_adapter,
  40. rt_uint8_t *send_buf,
  41. rt_uint32_t send_buf_len)
  42. {
  43. rt_uint32_t fifo_len, index;
  44. while (send_buf_len)
  45. {
  46. fifo_len = 8 - i2c_adapter->txflr;
  47. fifo_len = send_buf_len < fifo_len ? send_buf_len : fifo_len;
  48. for (index = 0; index < fifo_len; index++)
  49. i2c_adapter->data_cmd = I2C_DATA_CMD_DATA(*send_buf++);
  50. if (i2c_adapter->tx_abrt_source != 0)
  51. {
  52. while (i2c_adapter->status & I2C_STATUS_ACTIVITY); //
  53. i2c_adapter->clr_intr = i2c_adapter->clr_intr; //
  54. return -RT_ERROR;
  55. }
  56. send_buf_len -= fifo_len;
  57. }
  58. return RT_EOK;
  59. }
  60. static rt_err_t ki2c_recv(
  61. volatile i2c_t *i2c_adapter,
  62. rt_uint8_t *receive_buf,
  63. rt_uint32_t receive_buf_len)
  64. {
  65. rt_uint32_t fifo_len, index;
  66. rt_uint32_t rx_len = receive_buf_len;
  67. while (receive_buf_len || rx_len)
  68. {
  69. fifo_len = i2c_adapter->rxflr;
  70. fifo_len = rx_len < fifo_len ? rx_len : fifo_len;
  71. for (index = 0; index < fifo_len; index++)
  72. *receive_buf++ = (rt_uint8_t)i2c_adapter->data_cmd;
  73. rx_len -= fifo_len;
  74. fifo_len = 8 - i2c_adapter->txflr;
  75. fifo_len = receive_buf_len < fifo_len ? receive_buf_len : fifo_len;
  76. for (index = 0; index < fifo_len; index++)
  77. i2c_adapter->data_cmd = I2C_DATA_CMD_CMD;
  78. if (i2c_adapter->tx_abrt_source != 0)
  79. return -RT_ERROR;
  80. receive_buf_len -= fifo_len;
  81. }
  82. return RT_EOK;
  83. }
  84. static void ki2c_setaddr(
  85. volatile i2c_t *i2c_adapter,
  86. rt_uint16_t addr,
  87. int width)
  88. {
  89. i2c_adapter->tar = I2C_TAR_ADDRESS(addr) & I2C_TAR_ADDRESS_MASK;
  90. if(width == 10)
  91. {
  92. i2c_adapter->tar |= I2C_TAR_10BITADDR_MASTER;
  93. }
  94. else
  95. {
  96. i2c_adapter->tar &= ~I2C_TAR_10BITADDR_MASTER;
  97. }
  98. }
  99. static int ki2c_waittx(volatile i2c_t *i2c_adapter, int timeout_ms)
  100. {
  101. rt_tick_t start;
  102. start = rt_tick_get();
  103. while ((i2c_adapter->status & I2C_STATUS_ACTIVITY) || !(i2c_adapter->status & I2C_STATUS_TFE))
  104. {
  105. if (rt_tick_from_millisecond(rt_tick_get() - start) > timeout_ms)
  106. break;
  107. }
  108. if (i2c_adapter->tx_abrt_source != 0)
  109. return -RT_ERROR;
  110. return RT_EOK;
  111. }
  112. static void ki2c_clearerr(volatile i2c_t *i2c_adapter)
  113. {
  114. i2c_adapter->clr_tx_abrt = i2c_adapter->clr_tx_abrt;
  115. }
  116. static rt_ssize_t _i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  117. struct rt_i2c_msg msgs[],
  118. rt_uint32_t num)
  119. {
  120. rt_ssize_t i;
  121. i2c_t *kbus = (i2c_t *)bus->priv;
  122. rt_err_t status;
  123. int waittx = 0;
  124. RT_ASSERT(bus != RT_NULL);
  125. if(msgs[0].flags & RT_I2C_ADDR_10BIT)
  126. {
  127. ki2c_setaddr(kbus, msgs[0].addr, 10);
  128. }
  129. else
  130. {
  131. ki2c_setaddr(kbus, msgs[0].addr, 7);
  132. }
  133. ki2c_clearerr(kbus);
  134. for (i = 0; i < num; i++)
  135. {
  136. waittx = 0;
  137. if (msgs[i].flags & RT_I2C_RD)
  138. {
  139. status = ki2c_recv(kbus, msgs[i].buf, msgs[i].len);
  140. }
  141. else
  142. {
  143. status = ki2c_send(kbus, msgs[i].buf, msgs[i].len);
  144. waittx = 1;
  145. }
  146. if (status != RT_EOK)
  147. {
  148. goto _out;
  149. }
  150. }
  151. if (waittx)
  152. {
  153. status = ki2c_waittx(kbus, 2000);
  154. if (status != RT_EOK)
  155. {
  156. goto _out;
  157. }
  158. }
  159. return i;
  160. _out:
  161. return status;
  162. }
  163. static const struct rt_i2c_bus_device_ops i2c_ops =
  164. {
  165. .master_xfer = _i2c_mst_xfer,
  166. .slave_xfer = RT_NULL,
  167. .i2c_bus_control = RT_NULL,
  168. };
  169. #ifdef RT_USING_I2C_BITOPS
  170. typedef struct pin_info_s {
  171. uint32_t scl;
  172. uint32_t sda;
  173. } pin_info_t;
  174. static void set_sda(void *data, rt_int32_t state)
  175. {
  176. pin_info_t *pin = (pin_info_t *)data;
  177. /* state = 1: disable output. state = 0: enable output.*/
  178. set_gpio_bit(gpiohs->output_en.u32, pin->sda, !state);
  179. }
  180. static void set_scl(void *data, rt_int32_t state)
  181. {
  182. pin_info_t *pin = (pin_info_t *)data;
  183. /* state = 1: disable output. state = 0: enable output.*/
  184. set_gpio_bit(gpiohs->output_en.u32, pin->scl, !state);
  185. }
  186. static rt_int32_t get_sda(void *data)
  187. {
  188. pin_info_t *pin = (pin_info_t *)data;
  189. /* disable output.*/
  190. set_gpio_bit(gpiohs->output_en.u32, pin->sda, 0);
  191. return get_gpio_bit(gpiohs->input_val.u32, pin->sda);
  192. }
  193. static rt_int32_t get_scl(void *data)
  194. {
  195. pin_info_t *pin = (pin_info_t *)data;
  196. /* disable output.*/
  197. set_gpio_bit(gpiohs->output_en.u32, pin->scl, 0);
  198. return get_gpio_bit(gpiohs->input_val.u32, pin->scl);
  199. }
  200. static void udelay(rt_uint32_t us)
  201. {
  202. usleep((uint64_t)us);
  203. }
  204. static struct rt_i2c_bit_ops bit_ops_0 =
  205. {
  206. RT_NULL,
  207. set_sda,
  208. set_scl,
  209. get_sda,
  210. get_scl,
  211. udelay,
  212. 5,
  213. 5
  214. };
  215. static struct rt_i2c_bit_ops bit_ops_1 =
  216. {
  217. RT_NULL,
  218. set_sda,
  219. set_scl,
  220. get_sda,
  221. get_scl,
  222. udelay,
  223. 5,
  224. 5
  225. };
  226. static struct rt_i2c_bit_ops bit_ops_2 =
  227. {
  228. RT_NULL,
  229. set_sda,
  230. set_scl,
  231. get_sda,
  232. get_scl,
  233. udelay,
  234. 5,
  235. 5
  236. };
  237. extern int get_pin_channel(rt_base_t pin_index);
  238. #endif
  239. int rt_hw_i2c_init(void)
  240. {
  241. struct rt_i2c_bus_device *busdev;
  242. #ifdef BSP_USING_I2C0
  243. static struct rt_i2c_bus_device i2c_dev0;
  244. busdev = &i2c_dev0;
  245. #ifdef RT_USING_I2C_BITOPS
  246. fpioa_set_function(BSP_I2C0_SCL_PIN, FUNC_RESV0);
  247. fpioa_set_function(BSP_I2C0_SDA_PIN, FUNC_RESV0);
  248. rt_pin_write(BSP_I2C0_SCL_PIN, PIN_LOW);
  249. rt_pin_write(BSP_I2C0_SDA_PIN, PIN_LOW);
  250. rt_pin_mode(BSP_I2C0_SCL_PIN, PIN_MODE_INPUT_PULLUP);
  251. rt_pin_mode(BSP_I2C0_SDA_PIN, PIN_MODE_INPUT_PULLUP);
  252. static pin_info_t pin0;
  253. pin0.scl = get_pin_channel(BSP_I2C0_SCL_PIN);
  254. pin0.sda = get_pin_channel(BSP_I2C0_SDA_PIN);
  255. bit_ops_0.data = (void *)&pin0;
  256. busdev->priv = (void *)&bit_ops_0;
  257. rt_i2c_bit_add_bus(busdev, "i2c0");
  258. #else
  259. busdev->ops = &i2c_ops;
  260. busdev->priv = (void *)I2C0_BASE_ADDR;
  261. i2c_init(I2C_DEVICE_0, 0, 7, 100000);
  262. rt_i2c_bus_device_register(busdev, "i2c0");
  263. #endif
  264. #endif
  265. #ifdef BSP_USING_I2C1
  266. static struct rt_i2c_bus_device i2c_dev1;
  267. busdev = &i2c_dev1;
  268. #ifdef RT_USING_I2C_BITOPS
  269. fpioa_set_function(BSP_I2C1_SCL_PIN, FUNC_RESV0);
  270. fpioa_set_function(BSP_I2C1_SDA_PIN, FUNC_RESV0);
  271. rt_pin_write(BSP_I2C1_SCL_PIN, PIN_LOW);
  272. rt_pin_write(BSP_I2C1_SDA_PIN, PIN_LOW);
  273. rt_pin_mode(BSP_I2C1_SCL_PIN, PIN_MODE_INPUT_PULLUP);
  274. rt_pin_mode(BSP_I2C1_SDA_PIN, PIN_MODE_INPUT_PULLUP);
  275. static pin_info_t pin1;
  276. pin1.scl = get_pin_channel(BSP_I2C1_SCL_PIN);
  277. pin1.sda = get_pin_channel(BSP_I2C1_SDA_PIN);
  278. bit_ops_1.data = (void *)&pin1;
  279. busdev->priv = (void *)&bit_ops_1;
  280. rt_i2c_bit_add_bus(busdev, "i2c1");
  281. #else
  282. busdev->ops = &i2c_ops;
  283. busdev->priv = (void *)I2C1_BASE_ADDR;
  284. i2c_init(I2C_DEVICE_1, 0, 7, 100000);
  285. rt_i2c_bus_device_register(busdev, "i2c1");
  286. #endif
  287. #endif
  288. #ifdef BSP_USING_I2C2
  289. static struct rt_i2c_bus_device i2c_dev2;
  290. busdev = &i2c_dev2;
  291. #ifdef RT_USING_I2C_BITOPS
  292. fpioa_set_function(BSP_I2C2_SCL_PIN, FUNC_RESV0);
  293. fpioa_set_function(BSP_I2C2_SDA_PIN, FUNC_RESV0);
  294. rt_pin_write(BSP_I2C2_SCL_PIN, PIN_LOW);
  295. rt_pin_write(BSP_I2C2_SDA_PIN, PIN_LOW);
  296. rt_pin_mode(BSP_I2C2_SCL_PIN, PIN_MODE_INPUT_PULLUP);
  297. rt_pin_mode(BSP_I2C2_SDA_PIN, PIN_MODE_INPUT_PULLUP);
  298. static pin_info_t pin2;
  299. pin2.scl = get_pin_channel(BSP_I2C2_SCL_PIN);
  300. pin2.sda = get_pin_channel(BSP_I2C2_SDA_PIN);
  301. bit_ops_2.data = (void *)&pin2;
  302. busdev->priv = (void *)&bit_ops_2;
  303. rt_i2c_bit_add_bus(busdev, "i2c2");
  304. #else
  305. busdev->ops = &i2c_ops;
  306. busdev->priv = (void *)I2C2_BASE_ADDR;
  307. i2c_init(I2C_DEVICE_2, 0, 7, 100000);
  308. rt_i2c_bus_device_register(busdev, "i2c2");
  309. #endif
  310. #endif
  311. return 0;
  312. }
  313. INIT_BOARD_EXPORT(rt_hw_i2c_init);
  314. #endif