drv_i2c.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-07-08 Rbb666 first implementation.
  9. */
  10. #include "board.h"
  11. #if defined(RT_USING_I2C)
  12. #if defined(BSP_USING_HW_I2C3) || defined(BSP_USING_HW_I2C6)
  13. #include <rtdevice.h>
  14. #ifndef I2C3_CONFIG
  15. #define I2C3_CONFIG \
  16. { \
  17. .name = "i2c3", \
  18. .scl_pin = P6_0, \
  19. .sda_pin = P6_1, \
  20. }
  21. #endif /* I2C3_CONFIG */
  22. #endif
  23. #ifndef I2C6_CONFIG
  24. #define I2C6_CONFIG \
  25. { \
  26. .name = "i2c6", \
  27. .scl_pin = P13_0, \
  28. .sda_pin = P13_1, \
  29. }
  30. #endif /* I2C6_CONFIG */
  31. enum
  32. {
  33. #ifdef BSP_USING_HW_I2C3
  34. I2C3_INDEX,
  35. #endif
  36. #ifdef BSP_USING_HW_I2C6
  37. I2C6_INDEX,
  38. #endif
  39. };
  40. struct ifx_i2c_config
  41. {
  42. char *name;
  43. rt_uint32_t scl_pin;
  44. rt_uint32_t sda_pin;
  45. };
  46. struct ifx_i2c
  47. {
  48. cyhal_i2c_t mI2C;
  49. cyhal_i2c_cfg_t mI2C_cfg;
  50. struct ifx_i2c_config *config;
  51. struct rt_i2c_bus_device i2c_bus;
  52. };
  53. static struct ifx_i2c_config i2c_config[] =
  54. {
  55. #ifdef BSP_USING_HW_I2C3
  56. I2C3_CONFIG,
  57. #endif
  58. #ifdef BSP_USING_HW_I2C6
  59. I2C6_CONFIG,
  60. #endif
  61. };
  62. static struct ifx_i2c i2c_objs[sizeof(i2c_config) / sizeof(i2c_config[0])] = {0};
  63. static int ifx_i2c_read(struct ifx_i2c *hi2c, rt_uint16_t slave_address, rt_uint8_t *p_buffer, rt_uint16_t data_byte)
  64. {
  65. if (cyhal_i2c_master_read(&hi2c->mI2C, slave_address, p_buffer, data_byte, 10, true) != RT_EOK)
  66. {
  67. return -RT_ERROR;
  68. }
  69. return 0;
  70. }
  71. static int ifx_i2c_write(struct ifx_i2c *hi2c, uint16_t slave_address, uint8_t *p_buffer, uint16_t data_byte)
  72. {
  73. if (cyhal_i2c_master_write(&hi2c->mI2C, slave_address, p_buffer, data_byte, 10, true) != RT_EOK)
  74. {
  75. return -RT_ERROR;
  76. }
  77. return 0;
  78. }
  79. static rt_size_t _i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
  80. {
  81. struct rt_i2c_msg *msg;
  82. rt_uint32_t i;
  83. struct ifx_i2c *i2c_obj;
  84. RT_ASSERT(bus != RT_NULL);
  85. RT_ASSERT(msgs != RT_NULL);
  86. i2c_obj = rt_container_of(bus, struct ifx_i2c, i2c_bus);
  87. for (i = 0; i < num; i++)
  88. {
  89. msg = &msgs[i];
  90. if (msg->flags & RT_I2C_RD)
  91. {
  92. if (ifx_i2c_read(i2c_obj, msg->addr, msg->buf, msg->len) != 0)
  93. {
  94. goto out;
  95. }
  96. }
  97. else
  98. {
  99. if (ifx_i2c_write(i2c_obj, msg->addr, msg->buf, msg->len) != 0)
  100. {
  101. goto out;
  102. }
  103. }
  104. }
  105. out:
  106. return i;
  107. }
  108. static const struct rt_i2c_bus_device_ops i2c_ops =
  109. {
  110. _i2c_xfer,
  111. RT_NULL,
  112. RT_NULL
  113. };
  114. void HAL_I2C_Init(struct ifx_i2c *obj)
  115. {
  116. rt_uint8_t result = RT_EOK;
  117. result = cyhal_i2c_init(&obj->mI2C, obj->config->sda_pin, obj->config->scl_pin, NULL);
  118. RT_ASSERT(result == RT_EOK);
  119. result = cyhal_i2c_configure(&obj->mI2C, &obj->mI2C_cfg);
  120. RT_ASSERT(result == RT_EOK);
  121. }
  122. int rt_hw_i2c_init(void)
  123. {
  124. rt_err_t result;
  125. cyhal_i2c_t mI2C;
  126. for (int i = 0; i < sizeof(i2c_config) / sizeof(i2c_config[0]); i++)
  127. {
  128. i2c_objs[i].config = &i2c_config[i];
  129. i2c_objs[i].i2c_bus.parent.user_data = &i2c_config[i];
  130. i2c_objs[i].mI2C_cfg.is_slave = false;
  131. i2c_objs[i].mI2C_cfg.address = 0;
  132. i2c_objs[i].mI2C_cfg.frequencyhal_hz = (400000UL);
  133. i2c_objs[i].mI2C = mI2C;
  134. i2c_objs[i].i2c_bus.ops = &i2c_ops;
  135. HAL_I2C_Init(&i2c_objs[i]);
  136. result = rt_i2c_bus_device_register(&i2c_objs[i].i2c_bus, i2c_config[i].name);
  137. RT_ASSERT(result == RT_EOK);
  138. }
  139. return 0;
  140. }
  141. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  142. #endif /* defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) */