drv_i2c.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (c) 2006-2024 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-08-21 hywing The first version
  9. */
  10. #include <rtdevice.h>
  11. #include "fsl_lpi2c.h"
  12. #include "fsl_lpi2c_edma.h"
  13. #include "fsl_edma.h"
  14. #ifdef RT_USING_I2C
  15. #define DBG_TAG "drv.i2c"
  16. #define DBG_LVL DBG_INFO
  17. #include <rtdbg.h>
  18. enum
  19. {
  20. #ifdef BSP_USING_I2C0
  21. I2C0_INDEX,
  22. #endif
  23. #ifdef BSP_USING_I2C1
  24. I2C1_INDEX,
  25. #endif
  26. #ifdef BSP_USING_I2C2
  27. I2C2_INDEX,
  28. #endif
  29. #ifdef BSP_USING_I2C3
  30. I2C3_INDEX,
  31. #endif
  32. };
  33. struct lpc_i2c_bus
  34. {
  35. struct rt_i2c_bus_device parent;
  36. LPI2C_Type *I2C;
  37. clock_attach_id_t clock_attach_id;
  38. clock_div_name_t clock_div_name;
  39. clock_name_t clock_src;
  40. uint32_t baud;
  41. char *name;
  42. };
  43. struct lpc_i2c_bus lpc_obj[] =
  44. {
  45. #ifdef BSP_USING_I2C0
  46. {
  47. .I2C = LPI2C0,
  48. .baud = 100000U,
  49. #if (defined(CPU_MCXA346VLH) || defined(CPU_MCXA346VLL) || defined(CPU_MCXA346VLQ) || defined(CPU_MCXA346VPN))
  50. .clock_attach_id = kFRO_LF_DIV_to_LPI2C0,
  51. #else
  52. .clock_attach_id = kFRO12M_to_LPI2C0,
  53. #endif
  54. .clock_div_name = kCLOCK_DivLPI2C0,
  55. .clock_src = kCLOCK_Fro12M,
  56. .name = "i2c0",
  57. },
  58. #endif
  59. #ifdef BSP_USING_I2C1
  60. {
  61. .I2C = LPI2C1,
  62. .baud = 100000U,
  63. #if (defined(CPU_MCXA346VLH) || defined(CPU_MCXA346VLL) || defined(CPU_MCXA346VLQ) || defined(CPU_MCXA346VPN))
  64. .clock_attach_id = kFRO_LF_DIV_to_LPI2C1,
  65. #else
  66. .clock_attach_id = kFRO12M_to_LPI2C1,
  67. #endif
  68. .clock_div_name = kCLOCK_DivLPI2C1,
  69. .clock_src = kCLOCK_Fro12M,
  70. .name = "i2c1",
  71. },
  72. #endif
  73. #ifdef BSP_USING_I2C2
  74. {
  75. .I2C = LPI2C2,
  76. .baud = 100000U,
  77. #if (defined(CPU_MCXA346VLH) || defined(CPU_MCXA346VLL) || defined(CPU_MCXA346VLQ) || defined(CPU_MCXA346VPN))
  78. .clock_attach_id = kFRO_LF_DIV_to_LPI2C2,
  79. #else
  80. .clock_attach_id = kFRO12M_to_LPI2C2,
  81. #endif
  82. .clock_div_name = kCLOCK_DivLPI2C2,
  83. .clock_src = kCLOCK_Fro12M,
  84. .name = "i2c2",
  85. },
  86. #endif
  87. #ifdef BSP_USING_I2C3
  88. {
  89. .I2C = LPI2C3,
  90. .baud = 100000U,
  91. #if (defined(CPU_MCXA346VLH) || defined(CPU_MCXA346VLL) || defined(CPU_MCXA346VLQ) || defined(CPU_MCXA346VPN))
  92. .clock_attach_id = kFRO_LF_DIV_to_LPI2C3,
  93. #else
  94. .clock_attach_id = kFRO12M_to_LPI2C3,
  95. #endif
  96. .clock_div_name = kCLOCK_DivLPI2C3,
  97. .clock_src = kCLOCK_Fro12M,
  98. .name = "i2c3",
  99. },
  100. #endif
  101. };
  102. static rt_ssize_t lpc_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
  103. {
  104. struct rt_i2c_msg *msg;
  105. lpi2c_master_transfer_t xfer = {0};
  106. rt_uint32_t i;
  107. rt_ssize_t ret = 0;
  108. struct lpc_i2c_bus *lpc_i2c = (struct lpc_i2c_bus *)bus;
  109. for (i = 0; i < num; i++)
  110. {
  111. msg = &msgs[i];
  112. if (msg->flags & RT_I2C_RD)
  113. {
  114. xfer.slaveAddress = msg->addr;
  115. xfer.direction = kLPI2C_Read;
  116. xfer.subaddress = 0;
  117. xfer.subaddressSize = 0;
  118. xfer.data = msg->buf;
  119. xfer.dataSize = msg->len;
  120. if(i != 0)
  121. xfer.flags = kLPI2C_TransferRepeatedStartFlag;
  122. else
  123. xfer.flags = kLPI2C_TransferDefaultFlag;
  124. if (LPI2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success)
  125. {
  126. LOG_D("i2c bus read failed!\n");
  127. return i;
  128. }
  129. }
  130. else
  131. {
  132. xfer.slaveAddress = msg->addr;
  133. xfer.direction = kLPI2C_Write;
  134. xfer.subaddress = 0;
  135. xfer.subaddressSize = 0;
  136. xfer.data = msg->buf;
  137. xfer.dataSize = msg->len;
  138. if(i == 0)
  139. xfer.flags = kLPI2C_TransferNoStopFlag;
  140. else
  141. xfer.flags = kLPI2C_TransferDefaultFlag;
  142. if (LPI2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success)
  143. {
  144. LOG_D("i2c bus write failed!\n");
  145. return i;
  146. }
  147. }
  148. }
  149. ret = i;
  150. return ret;
  151. }
  152. static const struct rt_i2c_bus_device_ops i2c_ops =
  153. {
  154. lpc_i2c_xfer,
  155. RT_NULL,
  156. RT_NULL
  157. };
  158. int rt_hw_i2c_init(void)
  159. {
  160. int i;
  161. lpi2c_master_config_t masterConfig;
  162. for(i=0; i<ARRAY_SIZE(lpc_obj); i++)
  163. {
  164. CLOCK_SetClockDiv(lpc_obj[i].clock_div_name, 1u);
  165. CLOCK_AttachClk(lpc_obj[i].clock_attach_id);
  166. LPI2C_MasterGetDefaultConfig(&masterConfig);
  167. masterConfig.baudRate_Hz = lpc_obj[i].baud;
  168. LPI2C_MasterInit(lpc_obj[i].I2C, &masterConfig, CLOCK_GetFreq(lpc_obj[i].clock_src));
  169. lpc_obj[i].parent.ops = &i2c_ops;
  170. rt_i2c_bus_device_register(&lpc_obj[i].parent, lpc_obj[i].name);
  171. }
  172. return RT_EOK;
  173. }
  174. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  175. #endif /* RT_USING_I2C */