drv_i2c.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2020-11-11 Wayne First version
  10. ******************************************************************************/
  11. #include <rtconfig.h>
  12. #if defined( BSP_USING_I2C)
  13. #include <rtdevice.h>
  14. #include "NuMicro.h"
  15. #include <drv_i2c.h>
  16. #include <drv_sys.h>
  17. /* Private define ---------------------------------------------------------------*/
  18. #define LOG_TAG "drv.i2c"
  19. #define DBG_ENABLE
  20. #define DBG_SECTION_NAME LOG_TAG
  21. #define DBG_LEVEL DBG_INFO
  22. #define DBG_COLOR
  23. #include <rtdbg.h>
  24. enum
  25. {
  26. I2C_START = -1,
  27. #if defined(BSP_USING_I2C0)
  28. I2C0_IDX,
  29. #endif
  30. #if defined(BSP_USING_I2C1)
  31. I2C1_IDX,
  32. #endif
  33. #if defined(BSP_USING_I2C2)
  34. I2C2_IDX,
  35. #endif
  36. #if defined(BSP_USING_I2C3)
  37. I2C3_IDX,
  38. #endif
  39. #if defined(BSP_USING_I2C4)
  40. I2C4_IDX,
  41. #endif
  42. #if defined(BSP_USING_I2C5)
  43. I2C5_IDX,
  44. #endif
  45. I2C_CNT
  46. };
  47. /* Private typedef --------------------------------------------------------------*/
  48. typedef struct _nu_i2c_bus
  49. {
  50. struct rt_i2c_bus_device parent;
  51. I2C_T *I2C;
  52. struct rt_i2c_msg *msg;
  53. char *device_name;
  54. } nu_i2c_bus_t;
  55. /* Private variables ------------------------------------------------------------*/
  56. static nu_i2c_bus_t nu_i2c_arr [ ] =
  57. {
  58. #if defined(BSP_USING_I2C0)
  59. {
  60. .I2C = I2C0, .device_name = "i2c0",
  61. },
  62. #endif
  63. #if defined(BSP_USING_I2C1)
  64. {
  65. .I2C = I2C1, .device_name = "i2c1",
  66. },
  67. #endif
  68. #if defined(BSP_USING_I2C2)
  69. {
  70. .I2C = I2C2, .device_name = "i2c2",
  71. },
  72. #endif
  73. #if defined(BSP_USING_I2C3)
  74. {
  75. .I2C = I2C3, .device_name = "i2c3",
  76. },
  77. #endif
  78. #if defined(BSP_USING_I2C4)
  79. {
  80. .I2C = I2C4, .device_name = "i2c4",
  81. },
  82. #endif
  83. #if defined(BSP_USING_I2C5)
  84. {
  85. .I2C = I2C5, .device_name = "i2c5",
  86. },
  87. #endif
  88. };
  89. /* Private functions ------------------------------------------------------------*/
  90. #if defined(BSP_USING_I2C)
  91. static rt_ssize_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  92. struct rt_i2c_msg msgs[],
  93. rt_uint32_t num);
  94. static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus,
  95. int cmd,
  96. void *args);
  97. static const struct rt_i2c_bus_device_ops nu_i2c_ops =
  98. {
  99. .master_xfer = nu_i2c_mst_xfer,
  100. .slave_xfer = NULL,
  101. .i2c_bus_control = nu_i2c_bus_control
  102. };
  103. static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus, int u32Cmd, void *args)
  104. {
  105. nu_i2c_bus_t *nu_i2c;
  106. RT_ASSERT(bus != RT_NULL);
  107. nu_i2c = (nu_i2c_bus_t *) bus;
  108. switch (cmd)
  109. {
  110. case RT_I2C_DEV_CTRL_CLK:
  111. I2C_SetBusClockFreq(nu_i2c->I2C, *(rt_uint32_t *)args);
  112. break;
  113. default:
  114. return -RT_EIO;
  115. }
  116. return RT_EOK;
  117. }
  118. static inline rt_err_t nu_i2c_wait_ready_with_timeout(nu_i2c_bus_t *bus)
  119. {
  120. rt_tick_t start = rt_tick_get();
  121. while (!(bus->I2C->CTL0 & I2C_CTL0_SI_Msk))
  122. {
  123. if ((rt_tick_get() - start) > bus->parent.timeout)
  124. {
  125. LOG_E("\ni2c: timeout!\n");
  126. return -RT_ETIMEOUT;
  127. }
  128. }
  129. return RT_EOK;
  130. }
  131. static inline rt_err_t nu_i2c_send_data(nu_i2c_bus_t *nu_i2c, rt_uint8_t data)
  132. {
  133. I2C_SET_DATA(nu_i2c->I2C, data);
  134. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_SI);
  135. return nu_i2c_wait_ready_with_timeout(nu_i2c);
  136. }
  137. static rt_err_t nu_i2c_send_address(nu_i2c_bus_t *nu_i2c,
  138. struct rt_i2c_msg *msg)
  139. {
  140. rt_uint16_t flags = msg->flags;
  141. rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
  142. rt_uint8_t addr1, addr2;
  143. rt_err_t ret;
  144. if (flags & RT_I2C_ADDR_10BIT)
  145. {
  146. nu_i2c->I2C->CTL1 |= I2C_CTL1_ADDR10EN_Msk;
  147. addr1 = 0xf0 | ((msg->addr >> 7) & 0x06);
  148. addr2 = msg->addr & 0xff;
  149. LOG_D("address1: %d, address2: %d\n", addr1, addr2);
  150. ret = nu_i2c_send_data(nu_i2c, addr1);
  151. if (ret != RT_EOK) /* for timeout condition */
  152. return -RT_EIO;
  153. if ((I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_TRANSMIT_ADDRESS_ACK) && !ignore_nack)
  154. {
  155. LOG_E("NACK: sending first address failed\n");
  156. return -RT_EIO;
  157. }
  158. ret = nu_i2c_send_data(nu_i2c, addr2);
  159. if (ret != RT_EOK) /* for timeout condition */
  160. return -RT_EIO;
  161. if ((I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_TRANSMIT_ADDRESS_ACK) && !ignore_nack)
  162. {
  163. LOG_E("NACK: sending second address failed\n");
  164. return -RT_EIO;
  165. }
  166. if (flags & RT_I2C_RD)
  167. {
  168. LOG_D("send repeated START signal\n");
  169. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_STA_SI);
  170. ret = nu_i2c_wait_ready_with_timeout(nu_i2c);
  171. if (ret != RT_EOK) /* for timeout condition */
  172. return -RT_EIO;
  173. if ((I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_REPEAT_START) && !ignore_nack)
  174. {
  175. //LOG_E("sending repeated START failed\n");
  176. return -RT_EIO;
  177. }
  178. addr1 |= 0x01;
  179. ret = nu_i2c_send_data(nu_i2c, addr1);
  180. if (ret != RT_EOK) /* for timeout condition */
  181. return -RT_EIO;
  182. if ((I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_RECEIVE_ADDRESS_ACK) && !ignore_nack)
  183. {
  184. LOG_E("NACK: sending read address failed\n");
  185. return -RT_EIO;
  186. }
  187. }
  188. }
  189. else
  190. {
  191. /* 7-bit addr */
  192. addr1 = msg->addr << 1;
  193. if (flags & RT_I2C_RD)
  194. addr1 |= 1;
  195. /* Send device address */
  196. ret = nu_i2c_send_data(nu_i2c, addr1); /* Send Address */
  197. if (ret != RT_EOK) /* for timeout condition */
  198. return -RT_EIO;
  199. if ((I2C_GET_STATUS(nu_i2c->I2C)
  200. != ((flags & RT_I2C_RD) ? NU_I2C_MASTER_STATUS_RECEIVE_ADDRESS_ACK : NU_I2C_MASTER_STATUS_TRANSMIT_ADDRESS_ACK))
  201. && !ignore_nack)
  202. {
  203. LOG_E("sending address failed\n");
  204. return -RT_EIO;
  205. }
  206. }
  207. return RT_EOK;
  208. }
  209. static rt_ssize_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  210. struct rt_i2c_msg msgs[],
  211. rt_uint32_t num)
  212. {
  213. struct rt_i2c_msg *msg;
  214. nu_i2c_bus_t *nu_i2c;
  215. rt_size_t i;
  216. rt_uint32_t cnt_data;
  217. rt_uint16_t ignore_nack;
  218. rt_err_t ret;
  219. RT_ASSERT(bus != RT_NULL);
  220. nu_i2c = (nu_i2c_bus_t *) bus;
  221. nu_i2c->msg = msgs;
  222. nu_i2c->I2C->CTL0 |= I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk;
  223. ret = nu_i2c_wait_ready_with_timeout(nu_i2c);
  224. if (ret != RT_EOK) /* for timeout condition */
  225. {
  226. rt_set_errno(-RT_ETIMEOUT);
  227. return 0;
  228. }
  229. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_START)
  230. {
  231. i = 0;
  232. LOG_E("Send START Failed");
  233. return i;
  234. }
  235. for (i = 0; i < num; i++)
  236. {
  237. msg = &msgs[i];
  238. ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
  239. if (!(msg->flags & RT_I2C_NO_START))
  240. {
  241. if (i)
  242. {
  243. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_STA_SI);
  244. ret = nu_i2c_wait_ready_with_timeout(nu_i2c);
  245. if (ret != RT_EOK) /* for timeout condition */
  246. break;
  247. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_REPEAT_START)
  248. {
  249. i = 0;
  250. //LOG_E("Send repeat START Fail");
  251. break;
  252. }
  253. }
  254. if ((RT_EOK != nu_i2c_send_address(nu_i2c, msg))
  255. && !ignore_nack)
  256. {
  257. i = 0;
  258. LOG_E("Send Address Fail");
  259. break;
  260. }
  261. }
  262. if (nu_i2c->msg[i].flags & RT_I2C_RD) /* Receive Bytes */
  263. {
  264. rt_uint32_t do_rd_nack = (i == (num - 1));
  265. for (cnt_data = 0 ; cnt_data < (nu_i2c->msg[i].len) ; cnt_data++)
  266. {
  267. do_rd_nack += (cnt_data == (nu_i2c->msg[i].len - 1)); /* NACK after last byte for hardware setting */
  268. if (do_rd_nack == 2)
  269. {
  270. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_SI);
  271. }
  272. else
  273. {
  274. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_SI_AA);
  275. }
  276. ret = nu_i2c_wait_ready_with_timeout(nu_i2c);
  277. if (ret != RT_EOK) /* for timeout condition */
  278. break;
  279. if (nu_i2c->I2C->CTL0 & I2C_CTL_AA)
  280. {
  281. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_RECEIVE_DATA_ACK)
  282. {
  283. i = 0;
  284. break;
  285. }
  286. }
  287. else
  288. {
  289. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_RECEIVE_DATA_NACK)
  290. {
  291. i = 0;
  292. break;
  293. }
  294. }
  295. nu_i2c->msg[i].buf[cnt_data] = nu_i2c->I2C->DAT;
  296. }
  297. }
  298. else /* Send Bytes */
  299. {
  300. for (cnt_data = 0 ; cnt_data < (nu_i2c->msg[i].len) ; cnt_data++)
  301. {
  302. /* Send register number and MSB of data */
  303. ret = nu_i2c_send_data(nu_i2c, (uint8_t)(nu_i2c->msg[i].buf[cnt_data]));
  304. if (ret != RT_EOK) /* for timeout condition */
  305. break;
  306. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_TRANSMIT_DATA_ACK
  307. && !ignore_nack
  308. ) /* Send aata and get Ack */
  309. {
  310. i = 0;
  311. break;
  312. }
  313. }
  314. }
  315. }
  316. I2C_STOP(nu_i2c->I2C);
  317. RT_ASSERT(I2C_GET_STATUS(nu_i2c->I2C) == NU_I2C_MASTER_STATUS_BUS_RELEASED);
  318. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_BUS_RELEASED)
  319. {
  320. i = 0;
  321. }
  322. nu_i2c->msg = RT_NULL;
  323. nu_i2c->I2C->CTL1 = 0; /*clear all sub modes like 10 bit mode*/
  324. return i;
  325. }
  326. #endif
  327. /* Public functions -------------------------------------------------------------*/
  328. int rt_hw_i2c_init(void)
  329. {
  330. int i;
  331. rt_err_t ret = RT_EOK;
  332. for (i = (I2C_START + 1); i < I2C_CNT; i++)
  333. {
  334. /* Reset and initial IP engine. */
  335. I2C_Close(nu_i2c_arr[i].I2C);
  336. I2C_Open(nu_i2c_arr[i].I2C, 100000);
  337. nu_i2c_arr[i].parent.ops = &nu_i2c_ops;
  338. ret = rt_i2c_bus_device_register(&nu_i2c_arr[i].parent, nu_i2c_arr[i].device_name);
  339. RT_ASSERT(RT_EOK == ret);
  340. }
  341. return 0;
  342. }
  343. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  344. #endif /* BSP_USING_I2C */