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_ERROR
  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. I2C_CNT
  40. };
  41. /* Private typedef --------------------------------------------------------------*/
  42. typedef struct _nu_i2c_bus
  43. {
  44. struct rt_i2c_bus_device parent;
  45. I2C_T *I2C;
  46. struct rt_i2c_msg *msg;
  47. char *device_name;
  48. E_SYS_IPRST rstidx;
  49. E_SYS_IPCLK clkidx;
  50. } nu_i2c_bus_t;
  51. /* Private variables ------------------------------------------------------------*/
  52. static nu_i2c_bus_t nu_i2c_arr [ ] =
  53. {
  54. #if defined(BSP_USING_I2C0)
  55. {
  56. .I2C = I2C0,
  57. .device_name = "i2c0",
  58. .rstidx = I2C0RST,
  59. .clkidx = I2C0CKEN,
  60. },
  61. #endif
  62. #if defined(BSP_USING_I2C1)
  63. {
  64. .I2C = I2C1,
  65. .device_name = "i2c1",
  66. .rstidx = I2C1RST,
  67. .clkidx = I2C1CKEN,
  68. },
  69. #endif
  70. #if defined(BSP_USING_I2C2)
  71. {
  72. .I2C = I2C2,
  73. .device_name = "i2c2",
  74. .rstidx = I2C2RST,
  75. .clkidx = I2C2CKEN,
  76. },
  77. #endif
  78. #if defined(BSP_USING_I2C3)
  79. {
  80. .I2C = I2C3,
  81. .device_name = "i2c3",
  82. .rstidx = I2C3RST,
  83. .clkidx = I2C3CKEN,
  84. },
  85. #endif
  86. };
  87. /* Private functions ------------------------------------------------------------*/
  88. #if defined(BSP_USING_I2C)
  89. static rt_size_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  90. struct rt_i2c_msg msgs[],
  91. rt_uint32_t num);
  92. static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus,
  93. rt_uint32_t u32Cmd,
  94. rt_uint32_t u32Value);
  95. static const struct rt_i2c_bus_device_ops nu_i2c_ops =
  96. {
  97. .master_xfer = nu_i2c_mst_xfer,
  98. .slave_xfer = NULL,
  99. .i2c_bus_control = nu_i2c_bus_control
  100. };
  101. static rt_err_t nu_i2c_bus_control(struct rt_i2c_bus_device *bus, rt_uint32_t u32Cmd, rt_uint32_t u32Value)
  102. {
  103. nu_i2c_bus_t *nu_i2c;
  104. RT_ASSERT(bus != RT_NULL);
  105. nu_i2c = (nu_i2c_bus_t *) bus;
  106. switch (u32Cmd)
  107. {
  108. case RT_I2C_DEV_CTRL_CLK:
  109. I2C_SetBusClockFreq(nu_i2c->I2C, u32Value);
  110. break;
  111. default:
  112. return -RT_EIO;
  113. }
  114. return RT_EOK;
  115. }
  116. static inline rt_err_t nu_i2c_wait_ready_with_timeout(nu_i2c_bus_t *bus)
  117. {
  118. rt_tick_t start = rt_tick_get();
  119. while (!(bus->I2C->CTL0 & I2C_CTL0_SI_Msk))
  120. {
  121. if ((rt_tick_get() - start) > bus->parent.timeout)
  122. {
  123. LOG_E("\ni2c: timeout!\n");
  124. return -RT_ETIMEOUT;
  125. }
  126. }
  127. return RT_EOK;
  128. }
  129. static inline rt_err_t nu_i2c_send_data(nu_i2c_bus_t *nu_i2c, rt_uint8_t data)
  130. {
  131. I2C_SET_DATA(nu_i2c->I2C, data);
  132. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_SI);
  133. return nu_i2c_wait_ready_with_timeout(nu_i2c);
  134. }
  135. static rt_err_t nu_i2c_send_address(nu_i2c_bus_t *nu_i2c,
  136. struct rt_i2c_msg *msg)
  137. {
  138. rt_uint16_t flags = msg->flags;
  139. rt_uint16_t ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
  140. rt_uint8_t addr1, addr2;
  141. rt_err_t ret;
  142. if (flags & RT_I2C_ADDR_10BIT)
  143. {
  144. nu_i2c->I2C->CTL1 |= I2C_CTL1_ADDR10EN_Msk;
  145. addr1 = 0xf0 | ((msg->addr >> 7) & 0x06);
  146. addr2 = msg->addr & 0xff;
  147. LOG_D("address1: %d, address2: %d\n", addr1, addr2);
  148. ret = nu_i2c_send_data(nu_i2c, addr1);
  149. if (ret != RT_EOK) /* for timeout condition */
  150. return -RT_EIO;
  151. if ((I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_TRANSMIT_ADDRESS_ACK) && !ignore_nack)
  152. {
  153. LOG_E("NACK: sending first address failed\n");
  154. return -RT_EIO;
  155. }
  156. ret = nu_i2c_send_data(nu_i2c, addr2);
  157. if (ret != RT_EOK) /* for timeout condition */
  158. return -RT_EIO;
  159. if ((I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_TRANSMIT_ADDRESS_ACK) && !ignore_nack)
  160. {
  161. LOG_E("NACK: sending second address failed\n");
  162. return -RT_EIO;
  163. }
  164. if (flags & RT_I2C_RD)
  165. {
  166. LOG_D("send repeated START signal\n");
  167. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_STA_SI);
  168. ret = nu_i2c_wait_ready_with_timeout(nu_i2c);
  169. if (ret != RT_EOK) /* for timeout condition */
  170. return -RT_EIO;
  171. if ((I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_REPEAT_START) && !ignore_nack)
  172. {
  173. LOG_E("sending repeated START failed\n");
  174. return -RT_EIO;
  175. }
  176. addr1 |= 0x01;
  177. ret = nu_i2c_send_data(nu_i2c, addr1);
  178. if (ret != RT_EOK) /* for timeout condition */
  179. return -RT_EIO;
  180. if ((I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_RECEIVE_ADDRESS_ACK) && !ignore_nack)
  181. {
  182. LOG_E("NACK: sending read address failed\n");
  183. return -RT_EIO;
  184. }
  185. }
  186. }
  187. else
  188. {
  189. /* 7-bit addr */
  190. addr1 = msg->addr << 1;
  191. if (flags & RT_I2C_RD)
  192. addr1 |= 1;
  193. /* Send device address */
  194. ret = nu_i2c_send_data(nu_i2c, addr1); /* Send Address */
  195. if (ret != RT_EOK) /* for timeout condition */
  196. return -RT_EIO;
  197. if ((I2C_GET_STATUS(nu_i2c->I2C)
  198. != ((flags & RT_I2C_RD) ? NU_I2C_MASTER_STATUS_RECEIVE_ADDRESS_ACK : NU_I2C_MASTER_STATUS_TRANSMIT_ADDRESS_ACK))
  199. && !ignore_nack)
  200. {
  201. LOG_E("sending address failed\n");
  202. return -RT_EIO;
  203. }
  204. }
  205. return RT_EOK;
  206. }
  207. static rt_size_t nu_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  208. struct rt_i2c_msg msgs[],
  209. rt_uint32_t num)
  210. {
  211. struct rt_i2c_msg *msg;
  212. nu_i2c_bus_t *nu_i2c;
  213. rt_size_t i;
  214. rt_uint32_t cnt_data;
  215. rt_uint16_t ignore_nack;
  216. rt_err_t ret;
  217. RT_ASSERT(bus != RT_NULL);
  218. nu_i2c = (nu_i2c_bus_t *) bus;
  219. nu_i2c->msg = msgs;
  220. nu_i2c->I2C->CTL0 |= I2C_CTL0_STA_Msk | I2C_CTL0_SI_Msk;
  221. ret = nu_i2c_wait_ready_with_timeout(nu_i2c);
  222. if (ret != RT_EOK) /* for timeout condition */
  223. {
  224. rt_set_errno(-RT_ETIMEOUT);
  225. return 0;
  226. }
  227. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_START)
  228. {
  229. i = 0;
  230. LOG_E("Send START Failed");
  231. return i;
  232. }
  233. for (i = 0; i < num; i++)
  234. {
  235. msg = &msgs[i];
  236. ignore_nack = msg->flags & RT_I2C_IGNORE_NACK;
  237. if (!(msg->flags & RT_I2C_NO_START))
  238. {
  239. if (i)
  240. {
  241. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_STA_SI);
  242. ret = nu_i2c_wait_ready_with_timeout(nu_i2c);
  243. if (ret != RT_EOK) /* for timeout condition */
  244. break;
  245. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_REPEAT_START)
  246. {
  247. i = 0;
  248. LOG_E("Send repeat START Fail");
  249. break;
  250. }
  251. }
  252. if ((RT_EOK != nu_i2c_send_address(nu_i2c, msg))
  253. && !ignore_nack)
  254. {
  255. i = 0;
  256. LOG_E("Send Address Fail");
  257. break;
  258. }
  259. }
  260. if (nu_i2c->msg[i].flags & RT_I2C_RD) /* Receive Bytes */
  261. {
  262. rt_uint32_t do_rd_nack = (i == (num - 1));
  263. for (cnt_data = 0 ; cnt_data < (nu_i2c->msg[i].len) ; cnt_data++)
  264. {
  265. do_rd_nack += (cnt_data == (nu_i2c->msg[i].len - 1)); /* NACK after last byte for hardware setting */
  266. if (do_rd_nack == 2)
  267. {
  268. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_SI);
  269. }
  270. else
  271. {
  272. I2C_SET_CONTROL_REG(nu_i2c->I2C, I2C_CTL_SI_AA);
  273. }
  274. ret = nu_i2c_wait_ready_with_timeout(nu_i2c);
  275. if (ret != RT_EOK) /* for timeout condition */
  276. break;
  277. if (nu_i2c->I2C->CTL0 & I2C_CTL_AA)
  278. {
  279. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_RECEIVE_DATA_ACK)
  280. {
  281. i = 0;
  282. break;
  283. }
  284. }
  285. else
  286. {
  287. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_RECEIVE_DATA_NACK)
  288. {
  289. i = 0;
  290. break;
  291. }
  292. }
  293. nu_i2c->msg[i].buf[cnt_data] = nu_i2c->I2C->DAT;
  294. }
  295. }
  296. else /* Send Bytes */
  297. {
  298. for (cnt_data = 0 ; cnt_data < (nu_i2c->msg[i].len) ; cnt_data++)
  299. {
  300. /* Send register number and MSB of data */
  301. ret = nu_i2c_send_data(nu_i2c, (uint8_t)(nu_i2c->msg[i].buf[cnt_data]));
  302. if (ret != RT_EOK) /* for timeout condition */
  303. break;
  304. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_TRANSMIT_DATA_ACK
  305. && !ignore_nack
  306. ) /* Send aata and get Ack */
  307. {
  308. i = 0;
  309. break;
  310. }
  311. }
  312. }
  313. }
  314. I2C_STOP(nu_i2c->I2C);
  315. RT_ASSERT(I2C_GET_STATUS(nu_i2c->I2C) == NU_I2C_MASTER_STATUS_BUS_RELEASED);
  316. if (I2C_GET_STATUS(nu_i2c->I2C) != NU_I2C_MASTER_STATUS_BUS_RELEASED)
  317. {
  318. i = 0;
  319. }
  320. nu_i2c->msg = RT_NULL;
  321. nu_i2c->I2C->CTL1 = 0; /*clear all sub modes like 10 bit mode*/
  322. return i;
  323. }
  324. #endif
  325. /* Public functions -------------------------------------------------------------*/
  326. int rt_hw_i2c_init(void)
  327. {
  328. int i;
  329. rt_err_t ret = RT_EOK;
  330. for (i = (I2C_START + 1); i < I2C_CNT; i++)
  331. {
  332. nu_sys_ipclk_enable(nu_i2c_arr[i].clkidx);
  333. nu_sys_ip_reset(nu_i2c_arr[i].rstidx);
  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 */