drv_sw_i2c.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. * 2024-12-07 wumingzi first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #define LOG_TAG "drv.i2c"
  13. #ifdef RT_USING_I2C
  14. #ifdef BSP_USING_SW_I2C
  15. #include "rthw.h"
  16. #include "rttypes.h"
  17. #include <rtdbg.h>
  18. #include "driver/gpio.h"
  19. #include "drv_sw_i2c.h"
  20. #if defined(BSP_USING_SW_I2C0)
  21. #define SW_I2C0_BUS_CONFIG \
  22. { \
  23. .scl = BSP_SW_I2C0_SCL_PIN, \
  24. .sda = BSP_SW_I2C0_SDA_PIN, \
  25. .bus_name = "i2c0", \
  26. }
  27. #endif
  28. static const struct esp32c3_soft_i2c_config soft_i2c_config[] =
  29. {
  30. #if defined(BSP_USING_SW_I2C0)
  31. SW_I2C0_BUS_CONFIG,
  32. #endif
  33. };
  34. static struct esp32c3_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])];
  35. /**
  36. * @brief This function initializes the i2c pin.
  37. * @param i2c
  38. * @retval None
  39. */
  40. static void esp32c3_i2c_gpio_init(struct esp32c3_i2c *i2c)
  41. {
  42. struct esp32c3_soft_i2c_config* cfg = (struct esp32c3_soft_i2c_config*)i2c->ops.data;
  43. rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD);
  44. rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD);
  45. gpio_set_pull_mode(cfg->sda, GPIO_FLOATING);
  46. gpio_set_pull_mode(cfg->scl, GPIO_FLOATING);
  47. gpio_set_level(cfg->scl, PIN_HIGH);
  48. gpio_set_level(cfg->sda, PIN_HIGH);
  49. }
  50. /**
  51. * @brief This function sets the sda pin.
  52. * @param data, state
  53. * @retval None
  54. */
  55. static void esp32c3_set_sda(void *data, rt_int32_t state)
  56. {
  57. struct esp32c3_soft_i2c_config* cfg = (struct esp32c3_soft_i2c_config*)data;
  58. /*rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD);*/
  59. if (state)
  60. {
  61. gpio_set_level(cfg->sda, PIN_HIGH);
  62. }
  63. else
  64. {
  65. gpio_set_level(cfg->sda, PIN_LOW);
  66. }
  67. }
  68. /**
  69. * @brief This function sets the scl pin.
  70. * @param data, state
  71. * @retval None
  72. */
  73. static void esp32c3_set_scl(void *data, rt_int32_t state)
  74. {
  75. struct esp32c3_soft_i2c_config* cfg = (struct esp32c3_soft_i2c_config*)data;
  76. if (state)
  77. {
  78. gpio_set_level(cfg->scl, PIN_HIGH);
  79. }
  80. else
  81. {
  82. gpio_set_level(cfg->scl, PIN_LOW);
  83. }
  84. }
  85. /**
  86. * @brief This function gets the sda pin state.
  87. * @param data
  88. * @retval None
  89. */
  90. static rt_int32_t esp32c3_get_sda(void *data)
  91. {
  92. struct esp32c3_soft_i2c_config* cfg = (struct esp32c3_soft_i2c_config*)data;
  93. return gpio_get_level(cfg->sda);
  94. }
  95. /**
  96. * @brief This function gets the scl pin state.
  97. * @param data
  98. * @retval None
  99. */
  100. static rt_int32_t esp32c3_get_scl(void *data)
  101. {
  102. struct esp32c3_soft_i2c_config* cfg = (struct esp32c3_soft_i2c_config*)data;
  103. return gpio_get_level(cfg->scl);
  104. }
  105. /**
  106. * @brief The time delay function.
  107. * @param us
  108. * @retval None
  109. */
  110. static void esp32c3_udelay(rt_uint32_t us)
  111. {
  112. rt_hw_us_delay(us);
  113. }
  114. /*
  115. * if i2c is locked, this function will unlock it
  116. *
  117. * @param esp32 config class
  118. *
  119. * @return RT_EOK indicates successful unlock.
  120. */
  121. /* */
  122. static rt_err_t esp32c3_i2c_bus_unlock(const struct esp32c3_soft_i2c_config *cfg)
  123. {
  124. rt_int32_t i = 0;
  125. if (PIN_LOW == rt_pin_read(cfg->sda))
  126. {
  127. /* 输出9个时钟 解锁IIC死锁 */
  128. while (i++ < 9)
  129. {
  130. gpio_set_level(cfg->scl, PIN_HIGH);
  131. esp32c3_udelay(100);
  132. gpio_set_level(cfg->scl, PIN_LOW);
  133. esp32c3_udelay(100);
  134. }
  135. }
  136. if (PIN_LOW == gpio_get_level(cfg->sda))
  137. {
  138. return -RT_ERROR;
  139. }
  140. return RT_EOK;
  141. }
  142. static const struct rt_i2c_bit_ops esp32c3_bit_ops_default =
  143. {
  144. .data = RT_NULL,
  145. .set_sda = esp32c3_set_sda,
  146. .set_scl = esp32c3_set_scl,
  147. .get_sda = esp32c3_get_sda,
  148. .get_scl = esp32c3_get_scl,
  149. .udelay = esp32c3_udelay,
  150. .delay_us = 1,
  151. .timeout = 100
  152. };
  153. int rt_sw_i2c_init(void)
  154. {
  155. /* I2C设备数量 */
  156. rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct esp32c3_i2c);
  157. rt_err_t result;
  158. /* 循环初始化 */
  159. for (int i = 0; i < obj_num; i++)
  160. {
  161. /* 注册方法 */
  162. i2c_obj[i].ops = esp32c3_bit_ops_default;
  163. /* 设备硬件数据 */
  164. i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
  165. /* 保存设备方法 */
  166. i2c_obj[i].i2c_bus.priv = &i2c_obj[i].ops;
  167. esp32c3_i2c_gpio_init(&i2c_obj[i]);
  168. result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c_bus, soft_i2c_config[i].bus_name);
  169. RT_ASSERT(result == RT_EOK);
  170. esp32c3_i2c_bus_unlock(&soft_i2c_config[i]);
  171. LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
  172. soft_i2c_config[i].bus_name,
  173. soft_i2c_config[i].scl,
  174. soft_i2c_config[i].sda);
  175. }
  176. return RT_EOK;
  177. }
  178. INIT_APP_EXPORT(rt_sw_i2c_init);
  179. #endif /* BSP_USING_SW_I2C */
  180. #endif /* RT_USING_I2C */