drv_i2c.c 3.4 KB

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