drv_soft_i2c.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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. static void bl_i2c_pin_init(void)
  133. {
  134. rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct bl_i2c);
  135. for(rt_size_t i = 0; i < obj_num; i++)
  136. {
  137. bl_i2c_gpio_init(&i2c_obj[i]);
  138. }
  139. }
  140. /**
  141. * This function sets the sda pin.
  142. *
  143. * @param bl config class.
  144. * @param The sda pin state.
  145. */
  146. static void bl_set_sda(void *data, rt_int32_t state)
  147. {
  148. struct bl_soft_i2c_config* cfg = (struct bl_soft_i2c_config*)data;
  149. if (state)
  150. {
  151. rt_pin_write(cfg->sda, PIN_HIGH);
  152. }
  153. else
  154. {
  155. rt_pin_write(cfg->sda, PIN_LOW);
  156. }
  157. }
  158. /**
  159. * This function sets the scl pin.
  160. *
  161. * @param bl config class.
  162. * @param The scl pin state.
  163. */
  164. static void bl_set_scl(void *data, rt_int32_t state)
  165. {
  166. struct bl_soft_i2c_config* cfg = (struct bl_soft_i2c_config*)data;
  167. if (state)
  168. {
  169. rt_pin_write(cfg->scl, PIN_HIGH);
  170. }
  171. else
  172. {
  173. rt_pin_write(cfg->scl, PIN_LOW);
  174. }
  175. }
  176. /**
  177. * This function gets the sda pin state.
  178. *
  179. * @param The sda pin state.
  180. */
  181. static rt_int32_t bl_get_sda(void *data)
  182. {
  183. struct bl_soft_i2c_config* cfg = (struct bl_soft_i2c_config*)data;
  184. return rt_pin_read(cfg->sda);
  185. }
  186. /**
  187. * This function gets the scl pin state.
  188. *
  189. * @param The scl pin state.
  190. */
  191. static rt_int32_t bl_get_scl(void *data)
  192. {
  193. struct bl_soft_i2c_config* cfg = (struct bl_soft_i2c_config*)data;
  194. return rt_pin_read(cfg->scl);
  195. }
  196. /**
  197. * The time delay function.
  198. *
  199. * @param microseconds.
  200. */
  201. static void bl_udelay(rt_uint32_t us)
  202. {
  203. bflb_mtimer_delay_us(us);
  204. }
  205. static const struct rt_i2c_bit_ops bl_bit_ops_default =
  206. {
  207. .data = RT_NULL,
  208. .pin_init = bl_i2c_pin_init,
  209. .set_sda = bl_set_sda,
  210. .set_scl = bl_set_scl,
  211. .get_sda = bl_get_sda,
  212. .get_scl = bl_get_scl,
  213. .udelay = bl_udelay,
  214. .delay_us = 1,
  215. .timeout = 100,
  216. .i2c_pin_init_flag = RT_FALSE
  217. };
  218. /**
  219. * if i2c is locked, this function will unlock it
  220. *
  221. * @param bl config class
  222. *
  223. * @return RT_EOK indicates successful unlock.
  224. */
  225. static rt_err_t bl_i2c_bus_unlock(const struct bl_soft_i2c_config *cfg)
  226. {
  227. rt_int32_t i = 0;
  228. if (PIN_LOW == rt_pin_read(cfg->sda))
  229. {
  230. while (i++ < 9)
  231. {
  232. rt_pin_write(cfg->scl, PIN_HIGH);
  233. bl_udelay(100);
  234. rt_pin_write(cfg->scl, PIN_LOW);
  235. bl_udelay(100);
  236. }
  237. }
  238. if (PIN_LOW == rt_pin_read(cfg->sda))
  239. {
  240. return -RT_ERROR;
  241. }
  242. return RT_EOK;
  243. }
  244. /* I2C initialization function */
  245. int rt_hw_i2c_init(void)
  246. {
  247. rt_err_t result;
  248. for (rt_size_t i = 0; i < sizeof(i2c_obj) / sizeof(struct bl_i2c); i++)
  249. {
  250. i2c_obj[i].ops = bl_bit_ops_default;
  251. i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
  252. i2c_obj[i].i2c_bus.priv = &i2c_obj[i].ops;
  253. result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c_bus, soft_i2c_config[i].bus_name);
  254. RT_ASSERT(result == RT_EOK);
  255. bl_i2c_bus_unlock(&soft_i2c_config[i]);
  256. LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
  257. soft_i2c_config[i].bus_name,
  258. soft_i2c_config[i].scl,
  259. soft_i2c_config[i].sda);
  260. }
  261. return RT_EOK;
  262. }
  263. INIT_BOARD_EXPORT(rt_hw_i2c_init);
  264. #endif /* BSP_USING_SOFT_I2C1 */