drv_soft_i2c.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023/04/15 chushicheng first version
  9. */
  10. #include "drv_soft_i2c.h"
  11. #include "bflb_gpio.h"
  12. #include "bflb_common.h"
  13. #ifdef BSP_USING_SOFT_I2C1
  14. #define DBG_LEVEL DBG_LOG
  15. #include <rtdbg.h>
  16. #define LOG_TAG "DRV.I2C"
  17. // i2c1
  18. #ifdef SOFT_I2C1_SCL_USING_GPIO0
  19. #define BSP_I2C1_SCL_PIN GPIO_PIN_0
  20. #elif defined(SOFT_I2C1_SCL_USING_GPIO2)
  21. #define BSP_I2C1_SCL_PIN GPIO_PIN_2
  22. #elif defined(SOFT_I2C1_SCL_USING_GPIO4)
  23. #define BSP_I2C1_SCL_PIN GPIO_PIN_4
  24. #elif defined(SOFT_I2C1_SCL_USING_GPIO6)
  25. #define BSP_I2C1_SCL_PIN GPIO_PIN_6
  26. #elif defined(SOFT_I2C1_SCL_USING_GPIO8)
  27. #define BSP_I2C1_SCL_PIN GPIO_PIN_8
  28. #elif defined(SOFT_I2C1_SCL_USING_GPIO10)
  29. #define BSP_I2C1_SCL_PIN GPIO_PIN_10
  30. #elif defined(SOFT_I2C1_SCL_USING_GPIO12)
  31. #define BSP_I2C1_SCL_PIN GPIO_PIN_12
  32. #elif defined(SOFT_I2C1_SCL_USING_GPIO14)
  33. #define BSP_I2C1_SCL_PIN GPIO_PIN_14
  34. #elif defined(SOFT_I2C1_SCL_USING_GPIO16)
  35. #define BSP_I2C1_SCL_PIN GPIO_PIN_16
  36. #elif defined(SOFT_I2C1_SCL_USING_GPIO18)
  37. #define BSP_I2C1_SCL_PIN GPIO_PIN_18
  38. #elif defined(SOFT_I2C1_SCL_USING_GPIO20)
  39. #define BSP_I2C1_SCL_PIN GPIO_PIN_20
  40. #elif defined(SOFT_I2C1_SCL_USING_GPIO22)
  41. #define BSP_I2C1_SCL_PIN GPIO_PIN_22
  42. #elif defined(SOFT_I2C1_SCL_USING_GPIO24)
  43. #define BSP_I2C1_SCL_PIN GPIO_PIN_24
  44. #elif defined(SOFT_I2C1_SCL_USING_GPIO26)
  45. #define BSP_I2C1_SCL_PIN GPIO_PIN_26
  46. #elif defined(SOFT_I2C1_SCL_USING_GPIO28)
  47. #define BSP_I2C1_SCL_PIN GPIO_PIN_28
  48. #elif defined(SOFT_I2C1_SCL_USING_GPIO30)
  49. #define BSP_I2C1_SCL_PIN GPIO_PIN_30
  50. #elif defined(SOFT_I2C1_SCL_USING_GPIO32)
  51. #define BSP_I2C1_SCL_PIN GPIO_PIN_32
  52. #elif defined(SOFT_I2C1_SCL_USING_GPIO34)
  53. #define BSP_I2C1_SCL_PIN GPIO_PIN_34
  54. #elif defined(SOFT_I2C1_SCL_USING_GPIO36)
  55. #define BSP_I2C1_SCL_PIN GPIO_PIN_36
  56. #elif defined(SOFT_I2C1_SCL_USING_GPIO38)
  57. #define BSP_I2C1_SCL_PIN GPIO_PIN_38
  58. #elif defined(SOFT_I2C1_SCL_USING_GPIO40)
  59. #define BSP_I2C1_SCL_PIN GPIO_PIN_40
  60. #elif defined(SOFT_I2C1_SCL_USING_GPIO42)
  61. #define BSP_I2C1_SCL_PIN GPIO_PIN_42
  62. #elif defined(SOFT_I2C1_SCL_USING_GPIO44)
  63. #define BSP_I2C1_SCL_PIN GPIO_PIN_44
  64. #endif
  65. #ifdef SOFT_I2C1_SDA_USING_GPIO1
  66. #define BSP_I2C1_SDA_PIN GPIO_PIN_1
  67. #elif defined(SOFT_I2C1_SDA_USING_GPIO3)
  68. #define BSP_I2C1_SDA_PIN GPIO_PIN_3
  69. #elif defined(SOFT_I2C1_SDA_USING_GPIO5)
  70. #define BSP_I2C1_SDA_PIN GPIO_PIN_5
  71. #elif defined(SOFT_I2C1_SDA_USING_GPIO7)
  72. #define BSP_I2C1_SDA_PIN GPIO_PIN_7
  73. #elif defined(SOFT_I2C1_SDA_USING_GPIO9)
  74. #define BSP_I2C1_SDA_PIN GPIO_PIN_9
  75. #elif defined(SOFT_I2C1_SDA_USING_GPIO11)
  76. #define BSP_I2C1_SDA_PIN GPIO_PIN_11
  77. #elif defined(SOFT_I2C1_SDA_USING_GPIO13)
  78. #define BSP_I2C1_SDA_PIN GPIO_PIN_13
  79. #elif defined(SOFT_I2C1_SDA_USING_GPIO15)
  80. #define BSP_I2C1_SDA_PIN GPIO_PIN_15
  81. #elif defined(SOFT_I2C1_SDA_USING_GPIO17)
  82. #define BSP_I2C1_SDA_PIN GPIO_PIN_17
  83. #elif defined(SOFT_I2C1_SDA_USING_GPIO19)
  84. #define BSP_I2C1_SDA_PIN GPIO_PIN_19
  85. #elif defined(SOFT_I2C1_SDA_USING_GPIO21)
  86. #define BSP_I2C1_SDA_PIN GPIO_PIN_21
  87. #elif defined(SOFT_I2C1_SDA_USING_GPIO23)
  88. #define BSP_I2C1_SDA_PIN GPIO_PIN_23
  89. #elif defined(SOFT_I2C1_SDA_USING_GPIO25)
  90. #define BSP_I2C1_SDA_PIN GPIO_PIN_25
  91. #elif defined(SOFT_I2C1_SDA_USING_GPIO27)
  92. #define BSP_I2C1_SDA_PIN GPIO_PIN_27
  93. #elif defined(SOFT_I2C1_SDA_USING_GPIO29)
  94. #define BSP_I2C1_SDA_PIN GPIO_PIN_29
  95. #elif defined(SOFT_I2C1_SDA_USING_GPIO31)
  96. #define BSP_I2C1_SDA_PIN GPIO_PIN_31
  97. #elif defined(SOFT_I2C1_SDA_USING_GPIO33)
  98. #define BSP_I2C1_SDA_PIN GPIO_PIN_33
  99. #elif defined(SOFT_I2C1_SDA_USING_GPIO35)
  100. #define BSP_I2C1_SDA_PIN GPIO_PIN_35
  101. #elif defined(SOFT_I2C1_SDA_USING_GPIO37)
  102. #define BSP_I2C1_SDA_PIN GPIO_PIN_37
  103. #elif defined(SOFT_I2C1_SDA_USING_GPIO39)
  104. #define BSP_I2C1_SDA_PIN GPIO_PIN_39
  105. #elif defined(SOFT_I2C1_SDA_USING_GPIO41)
  106. #define BSP_I2C1_SDA_PIN GPIO_PIN_41
  107. #elif defined(SOFT_I2C1_SDA_USING_GPIO43)
  108. #define BSP_I2C1_SDA_PIN GPIO_PIN_43
  109. #elif defined(SOFT_I2C1_SDA_USING_GPIO45)
  110. #define BSP_I2C1_SDA_PIN GPIO_PIN_45
  111. #endif
  112. static const struct bl_soft_i2c_config soft_i2c_config[] =
  113. {
  114. #ifdef BSP_USING_SOFT_I2C1
  115. I2C1_BUS_CONFIG,
  116. #endif
  117. };
  118. static struct bl_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])];
  119. /**
  120. * This function initializes the i2c pin.
  121. *
  122. * @param bl i2c dirver class.
  123. */
  124. static void bl_i2c_gpio_init(struct bl_i2c *i2c)
  125. {
  126. struct bl_soft_i2c_config* cfg = (struct bl_soft_i2c_config*)i2c->ops.data;
  127. rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD);
  128. rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD);
  129. rt_pin_write(cfg->scl, PIN_HIGH);
  130. rt_pin_write(cfg->sda, PIN_HIGH);
  131. }
  132. /**
  133. * This function sets the sda pin.
  134. *
  135. * @param bl config class.
  136. * @param The sda pin state.
  137. */
  138. static void bl_set_sda(void *data, rt_int32_t state)
  139. {
  140. struct bl_soft_i2c_config* cfg = (struct bl_soft_i2c_config*)data;
  141. if (state)
  142. {
  143. rt_pin_write(cfg->sda, PIN_HIGH);
  144. }
  145. else
  146. {
  147. rt_pin_write(cfg->sda, PIN_LOW);
  148. }
  149. }
  150. /**
  151. * This function sets the scl pin.
  152. *
  153. * @param bl config class.
  154. * @param The scl pin state.
  155. */
  156. static void bl_set_scl(void *data, rt_int32_t state)
  157. {
  158. struct bl_soft_i2c_config* cfg = (struct bl_soft_i2c_config*)data;
  159. if (state)
  160. {
  161. rt_pin_write(cfg->scl, PIN_HIGH);
  162. }
  163. else
  164. {
  165. rt_pin_write(cfg->scl, PIN_LOW);
  166. }
  167. }
  168. /**
  169. * This function gets the sda pin state.
  170. *
  171. * @param The sda pin state.
  172. */
  173. static rt_int32_t bl_get_sda(void *data)
  174. {
  175. struct bl_soft_i2c_config* cfg = (struct bl_soft_i2c_config*)data;
  176. return rt_pin_read(cfg->sda);
  177. }
  178. /**
  179. * This function gets the scl pin state.
  180. *
  181. * @param The scl pin state.
  182. */
  183. static rt_int32_t bl_get_scl(void *data)
  184. {
  185. struct bl_soft_i2c_config* cfg = (struct bl_soft_i2c_config*)data;
  186. return rt_pin_read(cfg->scl);
  187. }
  188. /**
  189. * The time delay function.
  190. *
  191. * @param microseconds.
  192. */
  193. static void bl_udelay(rt_uint32_t us)
  194. {
  195. bflb_mtimer_delay_us(us);
  196. }
  197. static const struct rt_i2c_bit_ops bl_bit_ops_default =
  198. {
  199. .data = RT_NULL,
  200. .set_sda = bl_set_sda,
  201. .set_scl = bl_set_scl,
  202. .get_sda = bl_get_sda,
  203. .get_scl = bl_get_scl,
  204. .udelay = bl_udelay,
  205. .delay_us = 1,
  206. .timeout = 100
  207. };
  208. /**
  209. * if i2c is locked, this function will unlock it
  210. *
  211. * @param bl config class
  212. *
  213. * @return RT_EOK indicates successful unlock.
  214. */
  215. static rt_err_t bl_i2c_bus_unlock(const struct bl_soft_i2c_config *cfg)
  216. {
  217. rt_int32_t i = 0;
  218. if (PIN_LOW == rt_pin_read(cfg->sda))
  219. {
  220. while (i++ < 9)
  221. {
  222. rt_pin_write(cfg->scl, PIN_HIGH);
  223. bl_udelay(100);
  224. rt_pin_write(cfg->scl, PIN_LOW);
  225. bl_udelay(100);
  226. }
  227. }
  228. if (PIN_LOW == rt_pin_read(cfg->sda))
  229. {
  230. return -RT_ERROR;
  231. }
  232. return RT_EOK;
  233. }
  234. /* I2C initialization function */
  235. int rt_hw_i2c_init(void)
  236. {
  237. rt_err_t result;
  238. for (rt_size_t i = 0; i < sizeof(i2c_obj) / sizeof(struct bl_i2c); i++)
  239. {
  240. i2c_obj[i].ops = bl_bit_ops_default;
  241. i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
  242. i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
  243. bl_i2c_gpio_init(&i2c_obj[i]);
  244. result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name);
  245. RT_ASSERT(result == RT_EOK);
  246. bl_i2c_bus_unlock(&soft_i2c_config[i]);
  247. LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
  248. soft_i2c_config[i].bus_name,
  249. soft_i2c_config[i].scl,
  250. soft_i2c_config[i].sda);
  251. }
  252. return RT_EOK;
  253. }
  254. INIT_BOARD_EXPORT(rt_hw_i2c_init);
  255. #endif /* BSP_USING_SOFT_I2C1 */