drv_i2c.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. * 2022-07-08 Rbb666 first implementation.
  9. * 2025-04-21 Hydevcode adapt xmc7100d
  10. */
  11. #include "board.h"
  12. #if defined(RT_USING_I2C)
  13. #if defined(BSP_USING_HW_I2C1) || defined(BSP_USING_HW_I2C2) || defined(BSP_USING_HW_I2C3) || defined(BSP_USING_HW_I2C4)|| defined(BSP_USING_HW_I2C6)
  14. #include <rtdevice.h>
  15. #ifndef I2C1_CONFIG
  16. #define I2C1_CONFIG \
  17. { \
  18. .name = "i2c1", \
  19. .scl_pin = BSP_I2C1_SCL_PIN, \
  20. .sda_pin = BSP_I2C1_SDA_PIN, \
  21. }
  22. #endif /* I2C1_CONFIG */
  23. #ifndef I2C2_CONFIG
  24. #define I2C2_CONFIG \
  25. { \
  26. .name = "i2c2", \
  27. .scl_pin = BSP_I2C2_SCL_PIN, \
  28. .sda_pin = BSP_I2C2_SDA_PIN, \
  29. }
  30. #endif /* I2C2_CONFIG */
  31. #ifndef I2C3_CONFIG
  32. #define I2C3_CONFIG \
  33. { \
  34. .name = "i2c3", \
  35. .scl_pin = BSP_I2C3_SCL_PIN, \
  36. .sda_pin = BSP_I2C3_SDA_PIN, \
  37. }
  38. #endif /* I2C3_CONFIG */
  39. #ifndef I2C4_CONFIG
  40. #define I2C4_CONFIG \
  41. { \
  42. .name = "i2c4", \
  43. .scl_pin = BSP_I2C4_SCL_PIN, \
  44. .sda_pin = BSP_I2C4_SDA_PIN, \
  45. }
  46. #endif /* I2C4_CONFIG */
  47. #ifndef I2C6_CONFIG
  48. #define I2C6_CONFIG \
  49. { \
  50. .name = "i2c6", \
  51. .scl_pin = BSP_I2C6_SCL_PIN, \
  52. .sda_pin = BSP_I2C6_SDA_PIN, \
  53. }
  54. #endif /* I2C6_CONFIG */
  55. #endif /* defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) */
  56. enum
  57. {
  58. #ifdef BSP_USING_HW_I2C1
  59. I2C1_INDEX,
  60. #endif
  61. #ifdef BSP_USING_HW_I2C2
  62. I2C2_INDEX,
  63. #endif
  64. #ifdef BSP_USING_HW_I2C3
  65. I2C3_INDEX,
  66. #endif
  67. #ifdef BSP_USING_HW_I2C4
  68. I2C4_INDEX,
  69. #endif
  70. #ifdef BSP_USING_HW_I2C6
  71. I2C6_INDEX,
  72. #endif
  73. };
  74. struct ifx_i2c_config
  75. {
  76. char *name;
  77. rt_uint32_t scl_pin;
  78. rt_uint32_t sda_pin;
  79. };
  80. struct ifx_i2c
  81. {
  82. cyhal_i2c_t mI2C;
  83. cyhal_i2c_cfg_t mI2C_cfg;
  84. struct ifx_i2c_config *config;
  85. struct rt_i2c_bus_device i2c_bus;
  86. };
  87. static struct ifx_i2c_config i2c_config[] =
  88. {
  89. #ifdef BSP_USING_HW_I2C1
  90. I2C1_CONFIG,
  91. #endif
  92. #ifdef BSP_USING_HW_I2C2
  93. I2C2_CONFIG,
  94. #endif
  95. #ifdef BSP_USING_HW_I2C3
  96. I2C3_CONFIG,
  97. #endif
  98. #ifdef BSP_USING_HW_I2C4
  99. I2C4_CONFIG,
  100. #endif
  101. #ifdef BSP_USING_HW_I2C6
  102. I2C6_CONFIG,
  103. #endif
  104. };
  105. static struct ifx_i2c i2c_objs[sizeof(i2c_config) / sizeof(i2c_config[0])] =
  106. {0};
  107. static int ifx_i2c_read(struct ifx_i2c *hi2c, rt_uint16_t slave_address, rt_uint8_t *p_buffer, rt_uint16_t data_byte)
  108. {
  109. if (cyhal_i2c_master_read(&hi2c->mI2C, slave_address, p_buffer, data_byte, 10, true) != RT_EOK)
  110. {
  111. return -RT_ERROR;
  112. }
  113. return 0;
  114. }
  115. static int ifx_i2c_write(struct ifx_i2c *hi2c, uint16_t slave_address, uint8_t *p_buffer, uint16_t data_byte)
  116. {
  117. if (cyhal_i2c_master_write(&hi2c->mI2C, slave_address, p_buffer, data_byte, 10, true) != RT_EOK)
  118. {
  119. return -RT_ERROR;
  120. }
  121. return 0;
  122. }
  123. static rt_ssize_t _i2c_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num)
  124. {
  125. struct rt_i2c_msg *msg;
  126. rt_uint32_t i;
  127. struct ifx_i2c *i2c_obj;
  128. RT_ASSERT(bus != RT_NULL);
  129. RT_ASSERT(msgs != RT_NULL);
  130. i2c_obj = rt_container_of(bus, struct ifx_i2c, i2c_bus);
  131. for (i = 0; i < num; i++)
  132. {
  133. msg = &msgs[i];
  134. if (msg->flags & RT_I2C_RD)
  135. {
  136. if (ifx_i2c_read(i2c_obj, msg->addr, msg->buf, msg->len) != 0)
  137. {
  138. goto out;
  139. }
  140. }
  141. else
  142. {
  143. if (ifx_i2c_write(i2c_obj, msg->addr, msg->buf, msg->len) != 0)
  144. {
  145. goto out;
  146. }
  147. }
  148. }
  149. out:
  150. return i;
  151. }
  152. static const struct rt_i2c_bus_device_ops i2c_ops =
  153. {
  154. _i2c_xfer,
  155. RT_NULL,
  156. RT_NULL
  157. };
  158. void HAL_I2C_Init(struct ifx_i2c *obj)
  159. {
  160. cy_rslt_t result = CY_RSLT_SUCCESS;
  161. result = cyhal_i2c_init(&obj->mI2C, obj->config->sda_pin, obj->config->scl_pin, NULL);
  162. if (result != CY_RSLT_SUCCESS)
  163. {
  164. rt_kprintf("hal i2c init fail!\n");
  165. return;
  166. }
  167. result = cyhal_i2c_configure(&obj->mI2C, &obj->mI2C_cfg);
  168. if (result != CY_RSLT_SUCCESS)
  169. {
  170. rt_kprintf("hal i2c configure fail!\n");
  171. return;
  172. }
  173. }
  174. int rt_hw_i2c_init(void)
  175. {
  176. rt_err_t result = RT_EOK;
  177. for (int i = 0; i < sizeof(i2c_config) / sizeof(i2c_config[0]); i++)
  178. {
  179. i2c_objs[i].config = &i2c_config[i];
  180. i2c_objs[i].i2c_bus.parent.user_data = &i2c_config[i];
  181. i2c_objs[i].mI2C_cfg.is_slave = false;
  182. i2c_objs[i].mI2C_cfg.address = 0;
  183. i2c_objs[i].mI2C_cfg.frequencyhal_hz = (400000UL);
  184. i2c_objs[i].i2c_bus.ops = &i2c_ops;
  185. HAL_I2C_Init(&i2c_objs[i]);
  186. result = rt_i2c_bus_device_register(&i2c_objs[i].i2c_bus, i2c_config[i].name);
  187. RT_ASSERT(result == RT_EOK);
  188. }
  189. return 0;
  190. }
  191. INIT_DEVICE_EXPORT(rt_hw_i2c_init);
  192. #endif /* RT_USING_I2C */