drv_i2c.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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-04-06 YangXi 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. enum
  16. {
  17. #ifdef BSP_USING_I2C0
  18. I2C0_INDEX,
  19. #endif
  20. #ifdef BSP_USING_I2C1
  21. I2C1_INDEX,
  22. #endif
  23. #ifdef BSP_USING_I2C2
  24. I2C2_INDEX,
  25. #endif
  26. };
  27. #define i2c_dbg rt_kprintf
  28. struct lpc_i2c_bus
  29. {
  30. struct rt_i2c_bus_device parent;
  31. LPI2C_Type *I2C;
  32. clock_attach_id_t clock_attach_id;
  33. clock_div_name_t clock_div_name;
  34. clock_name_t clock_src;
  35. uint32_t baud;
  36. char *name;
  37. };
  38. struct lpc_i2c_bus lpc_obj[] =
  39. {
  40. #ifdef BSP_USING_I2C0
  41. {
  42. .I2C = LPI2C0,
  43. .baud = 100000U,
  44. .clock_attach_id = kFRO12M_to_FLEXCOMM0,
  45. .clock_div_name = kCLOCK_DivFlexcom0Clk,
  46. .clock_src = kCLOCK_Fro12M,
  47. .name = "i2c0",
  48. },
  49. #endif
  50. #ifdef BSP_USING_I2C1
  51. {
  52. .I2C = LPI2C1,
  53. .baud = 100000U,
  54. .clock_attach_id = kFRO12M_to_FLEXCOMM1,
  55. .clock_div_name = kCLOCK_DivFlexcom1Clk,
  56. .clock_src = kCLOCK_Fro12M,
  57. .name = "i2c1",
  58. },
  59. #endif
  60. #ifdef BSP_USING_I2C2
  61. {
  62. .I2C = LPI2C2,
  63. .baud = 100000U,
  64. .clock_attach_id = kFRO12M_to_FLEXCOMM2,
  65. .clock_div_name = kCLOCK_DivFlexcom2Clk,
  66. .clock_src = kCLOCK_Fro12M,
  67. .name = "i2c2",
  68. },
  69. #endif
  70. };
  71. static rt_ssize_t lpc_i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
  72. {
  73. struct rt_i2c_msg *msg;
  74. lpi2c_master_transfer_t xfer = {0};
  75. rt_uint32_t i;
  76. rt_ssize_t ret = 0;
  77. struct lpc_i2c_bus *lpc_i2c = (struct lpc_i2c_bus *)bus;
  78. for (i = 0; i < num; i++)
  79. {
  80. msg = &msgs[i];
  81. if (msg->flags & RT_I2C_RD)
  82. {
  83. xfer.slaveAddress = msg->addr;
  84. xfer.direction = kLPI2C_Read;
  85. xfer.subaddress = 0;
  86. xfer.subaddressSize = 0;
  87. xfer.data = msg->buf;
  88. xfer.dataSize = msg->len;
  89. if(i != 0)
  90. xfer.flags = kLPI2C_TransferRepeatedStartFlag;
  91. else
  92. xfer.flags = kLPI2C_TransferDefaultFlag;
  93. if (LPI2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success)
  94. {
  95. i2c_dbg("i2c bus read failed!\n");
  96. return i;
  97. }
  98. }
  99. else
  100. {
  101. xfer.slaveAddress = msg->addr;
  102. xfer.direction = kLPI2C_Write;
  103. xfer.subaddress = 0;
  104. xfer.subaddressSize = 0;
  105. xfer.data = msg->buf;
  106. xfer.dataSize = msg->len;
  107. if(i == 0)
  108. xfer.flags = kLPI2C_TransferNoStopFlag;
  109. else
  110. xfer.flags = kLPI2C_TransferDefaultFlag;
  111. if (LPI2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success)
  112. {
  113. i2c_dbg("i2c bus write failed!\n");
  114. return i;
  115. }
  116. }
  117. }
  118. ret = i;
  119. return ret;
  120. }
  121. static const struct rt_i2c_bus_device_ops i2c_ops =
  122. {
  123. lpc_i2c_xfer,
  124. RT_NULL,
  125. RT_NULL
  126. };
  127. int rt_hw_i2c_init(void)
  128. {
  129. int i;
  130. lpi2c_master_config_t masterConfig;
  131. for(i=0; i<ARRAY_SIZE(lpc_obj); i++)
  132. {
  133. CLOCK_SetClkDiv(lpc_obj[i].clock_div_name, 1u);
  134. CLOCK_AttachClk(lpc_obj[i].clock_attach_id);
  135. LPI2C_MasterGetDefaultConfig(&masterConfig);
  136. masterConfig.baudRate_Hz = lpc_obj[i].baud;
  137. LPI2C_MasterInit(lpc_obj[i].I2C, &masterConfig, CLOCK_GetFreq(lpc_obj[i].clock_src));
  138. lpc_obj[i].parent.ops = &i2c_ops;
  139. rt_i2c_bus_device_register(&lpc_obj[i].parent, lpc_obj[i].name);
  140. }
  141. return RT_EOK;
  142. }
  143. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  144. #endif /* RT_USING_I2C */