drv_i2c.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-07-15 Magicoe The first version for LPC55S6x
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "board.h"
  13. #include "fsl_iocon.h"
  14. #include "fsl_gpio.h"
  15. #include "fsl_i2c.h"
  16. #ifdef RT_USING_I2C
  17. struct lpc_i2c_bus
  18. {
  19. struct rt_i2c_bus_device parent;
  20. I2C_Type *I2C;
  21. char *device_name;
  22. };
  23. static rt_size_t lpc_i2c_xfer(struct rt_i2c_bus_device *bus,
  24. struct rt_i2c_msg msgs[], rt_uint32_t num)
  25. {
  26. struct rt_i2c_msg *msg;
  27. i2c_master_transfer_t xfer = {0};
  28. rt_uint32_t i;
  29. rt_err_t ret = RT_ERROR;
  30. struct lpc_i2c_bus *lpc_i2c = (struct lpc_i2c_bus *)bus;
  31. for (i = 0; i < num; i++)
  32. {
  33. msg = &msgs[i];
  34. if (msg->flags & RT_I2C_RD)
  35. {
  36. xfer.slaveAddress = msg->addr;
  37. xfer.direction = kI2C_Read;
  38. xfer.subaddress = 0;
  39. xfer.subaddressSize = 0;
  40. xfer.data = msg->buf;
  41. xfer.dataSize = msg->len;
  42. if(i != 0)
  43. xfer.flags = kI2C_TransferRepeatedStartFlag;
  44. else
  45. xfer.flags = kI2C_TransferDefaultFlag;
  46. if (I2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success)
  47. {
  48. i2c_dbg("i2c bus write failed,i2c bus stop!\n");
  49. goto out;
  50. }
  51. }
  52. else
  53. {
  54. xfer.slaveAddress = msg->addr;
  55. xfer.direction = kI2C_Write;
  56. xfer.subaddress = 0;
  57. xfer.subaddressSize = 0;
  58. xfer.data = msg->buf;
  59. xfer.dataSize = msg->len;
  60. if(i == 0)
  61. xfer.flags = kI2C_TransferNoStopFlag;
  62. else
  63. xfer.flags = kI2C_TransferDefaultFlag;
  64. if (I2C_MasterTransferBlocking(lpc_i2c->I2C, &xfer) != kStatus_Success)
  65. {
  66. i2c_dbg("i2c bus write failed,i2c bus stop!\n");
  67. goto out;
  68. }
  69. }
  70. }
  71. ret = i;
  72. out:
  73. i2c_dbg("send stop condition\n");
  74. return ret;
  75. }
  76. static const struct rt_i2c_bus_device_ops i2c_ops =
  77. {
  78. lpc_i2c_xfer,
  79. RT_NULL,
  80. RT_NULL
  81. };
  82. int rt_hw_i2c_init(void)
  83. {
  84. i2c_master_config_t masterConfig;
  85. #ifdef BSP_USING_I2C1
  86. static struct lpc_i2c_bus lpc_i2c1;
  87. /* attach 12 MHz clock to FLEXCOMM2 (I2C master for touch controller) */
  88. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM1);
  89. I2C_MasterGetDefaultConfig(&masterConfig);
  90. /* Change the default baudrate configuration */
  91. masterConfig.baudRate_Bps = 100000U;
  92. /* Initialize the I2C master peripheral */
  93. I2C_MasterInit(I2C1, &masterConfig, 12000000);
  94. rt_memset((void *)&lpc_i2c1, 0, sizeof(struct lpc_i2c_bus));
  95. lpc_i2c1.parent.ops = &i2c_ops;
  96. lpc_i2c1.I2C = I2C1;
  97. lpc_i2c1.device_name = "LPC Flexcomm1 as I2C";
  98. rt_i2c_bus_device_register(&lpc_i2c1.parent, "i2c1");
  99. #endif /* BSP_USING_I2C1 */
  100. #ifdef BSP_USING_I2C4
  101. static struct lpc_i2c_bus lpc_i2c4;
  102. /* attach 12 MHz clock to FLEXCOMM2 (I2C master for touch controller) */
  103. CLOCK_AttachClk(kFRO12M_to_FLEXCOMM4);
  104. I2C_MasterGetDefaultConfig(&masterConfig);
  105. /* Change the default baudrate configuration */
  106. masterConfig.baudRate_Bps = 100000U;
  107. /* Initialize the I2C master peripheral */
  108. I2C_MasterInit(I2C4, &masterConfig, 12000000);
  109. rt_memset((void *)&lpc_i2c4, 0, sizeof(struct lpc_i2c_bus));
  110. lpc_i2c4.parent.ops = &i2c_ops;
  111. lpc_i2c4.I2C = I2C4;
  112. lpc_i2c4.device_name = "LPC Flexcomm4 as I2C";
  113. rt_i2c_bus_device_register(&lpc_i2c4.parent, BSP_USING_MMA8562I2C);
  114. #endif /* BSP_USING_I2C4 */
  115. return 0;
  116. }
  117. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  118. #endif /* RT_USING_I2C */