drv_soft_i2c.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-04-28 CDT first version
  9. */
  10. /*******************************************************************************
  11. * Include files
  12. ******************************************************************************/
  13. #include "drv_soft_i2c.h"
  14. #include "board_config.h"
  15. #if defined(RT_USING_I2C)
  16. #if defined(BSP_USING_I2C1_SW) || defined(BSP_USING_I2C2_SW) || defined(BSP_USING_I2C3_SW) || \
  17. defined(BSP_USING_I2C4_SW) || defined(BSP_USING_I2C5_SW) || defined(BSP_USING_I2C6_SW)
  18. /*******************************************************************************
  19. * Local type definitions ('typedef')
  20. ******************************************************************************/
  21. /*******************************************************************************
  22. * Local pre-processor symbols/macros ('#define')
  23. ******************************************************************************/
  24. //#define DRV_DEBUG
  25. #define LOG_TAG "drv.i2c"
  26. #include <drv_log.h>
  27. /*******************************************************************************
  28. * Global variable definitions (declared in header file with 'extern')
  29. ******************************************************************************/
  30. /*******************************************************************************
  31. * Local function prototypes ('static')
  32. ******************************************************************************/
  33. /*******************************************************************************
  34. * Local variable definitions ('static')
  35. ******************************************************************************/
  36. static const struct hc32_soft_i2c_config soft_i2c_config[] =
  37. {
  38. #ifdef BSP_USING_I2C1_SW
  39. I2C1_BUS_CONFIG,
  40. #endif
  41. #ifdef BSP_USING_I2C2_SW
  42. I2C2_BUS_CONFIG,
  43. #endif
  44. #ifdef BSP_USING_I2C3_SW
  45. I2C3_BUS_CONFIG,
  46. #endif
  47. #ifdef BSP_USING_I2C4_SW
  48. I2C4_BUS_CONFIG,
  49. #endif
  50. #ifdef BSP_USING_I2C5_SW
  51. I2C5_BUS_CONFIG,
  52. #endif
  53. #ifdef BSP_USING_I2C6_SW
  54. I2C6_BUS_CONFIG,
  55. #endif
  56. };
  57. static struct hc32_soft_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])];
  58. /*******************************************************************************
  59. * Function implementation - global ('extern') and local ('static')
  60. ******************************************************************************/
  61. /**
  62. * This function initializes the i2c pin.
  63. *
  64. * @param Hc32 i2c driver class.
  65. */
  66. static void hc32_i2c_gpio_init(struct hc32_soft_i2c *i2c)
  67. {
  68. struct hc32_soft_i2c_config *cfg = (struct hc32_soft_i2c_config *)i2c->ops.data;
  69. rt_pin_mode(cfg->scl_pin, PIN_MODE_OUTPUT_OD);
  70. rt_pin_mode(cfg->sda_pin, PIN_MODE_OUTPUT_OD);
  71. rt_pin_write(cfg->scl_pin, PIN_HIGH);
  72. rt_pin_write(cfg->sda_pin, PIN_HIGH);
  73. }
  74. static void hc32_i2c_pin_init(void)
  75. {
  76. rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct hc32_soft_i2c);
  77. for (rt_size_t i = 0; i < obj_num; i++)
  78. {
  79. hc32_i2c_gpio_init(&i2c_obj[i]);
  80. }
  81. }
  82. /**
  83. * This function sets the sda pin.
  84. *
  85. * @param Hc32 config class.
  86. * @param The sda pin state.
  87. */
  88. static void hc32_set_sda(void *data, rt_int32_t state)
  89. {
  90. struct hc32_soft_i2c_config *cfg = (struct hc32_soft_i2c_config *)data;
  91. if (state)
  92. {
  93. rt_pin_write(cfg->sda_pin, PIN_HIGH);
  94. }
  95. else
  96. {
  97. rt_pin_write(cfg->sda_pin, PIN_LOW);
  98. }
  99. }
  100. /**
  101. * This function sets the scl pin.
  102. *
  103. * @param Hc32 config class.
  104. * @param The scl pin state.
  105. */
  106. static void hc32_set_scl(void *data, rt_int32_t state)
  107. {
  108. struct hc32_soft_i2c_config *cfg = (struct hc32_soft_i2c_config *)data;
  109. if (state)
  110. {
  111. rt_pin_write(cfg->scl_pin, PIN_HIGH);
  112. }
  113. else
  114. {
  115. rt_pin_write(cfg->scl_pin, PIN_LOW);
  116. }
  117. }
  118. /**
  119. * This function gets the sda pin state.
  120. *
  121. * @param The sda pin state.
  122. */
  123. static rt_int32_t hc32_get_sda(void *data)
  124. {
  125. struct hc32_soft_i2c_config *cfg = (struct hc32_soft_i2c_config *)data;
  126. return rt_pin_read(cfg->sda_pin);
  127. }
  128. /**
  129. * This function gets the scl pin state.
  130. *
  131. * @param The scl pin state.
  132. */
  133. static rt_int32_t hc32_get_scl(void *data)
  134. {
  135. struct hc32_soft_i2c_config *cfg = (struct hc32_soft_i2c_config *)data;
  136. return rt_pin_read(cfg->scl_pin);
  137. }
  138. /**
  139. * The time delay function.
  140. *
  141. * @param microseconds.
  142. */
  143. static void hc32_udelay(rt_uint32_t us)
  144. {
  145. rt_uint32_t ticks;
  146. rt_uint32_t told, tnow, tcnt = 0;
  147. rt_uint32_t reload = SysTick->LOAD;
  148. ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
  149. told = SysTick->VAL;
  150. while (1)
  151. {
  152. tnow = SysTick->VAL;
  153. if (tnow != told)
  154. {
  155. if (tnow < told)
  156. {
  157. tcnt += told - tnow;
  158. }
  159. else
  160. {
  161. tcnt += reload - tnow + told;
  162. }
  163. told = tnow;
  164. if (tcnt >= ticks)
  165. {
  166. break;
  167. }
  168. }
  169. }
  170. }
  171. static const struct rt_i2c_bit_ops hc32_bit_ops_default =
  172. {
  173. .data = RT_NULL,
  174. .pin_init = hc32_i2c_pin_init,
  175. .set_sda = hc32_set_sda,
  176. .set_scl = hc32_set_scl,
  177. .get_sda = hc32_get_sda,
  178. .get_scl = hc32_get_scl,
  179. .udelay = hc32_udelay,
  180. .delay_us = 1,
  181. .timeout = 100,
  182. .i2c_pin_init_flag = RT_FALSE
  183. };
  184. /**
  185. * if i2c is locked, this function will unlock it
  186. *
  187. * @param hc32 config class
  188. *
  189. * @return RT_EOK indicates successful unlock.
  190. */
  191. static rt_err_t hc32_i2c_bus_unlock(const struct hc32_soft_i2c_config *cfg)
  192. {
  193. rt_uint32_t i = 0;
  194. if (PIN_LOW == rt_pin_read(cfg->sda_pin))
  195. {
  196. while (i++ < 9)
  197. {
  198. rt_pin_write(cfg->scl_pin, PIN_HIGH);
  199. hc32_udelay(100);
  200. rt_pin_write(cfg->scl_pin, PIN_LOW);
  201. hc32_udelay(100);
  202. }
  203. }
  204. if (PIN_LOW == rt_pin_read(cfg->sda_pin))
  205. {
  206. return -RT_ERROR;
  207. }
  208. return RT_EOK;
  209. }
  210. /* I2C initialization function */
  211. int hc32_soft_i2c_init(void)
  212. {
  213. rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct hc32_soft_i2c);
  214. rt_err_t result;
  215. for (rt_size_t i = 0; i < obj_num; i++)
  216. {
  217. i2c_obj[i].ops = hc32_bit_ops_default;
  218. i2c_obj[i].ops.data = (void *)&soft_i2c_config[i];
  219. i2c_obj[i].i2c_bus.priv = &i2c_obj[i].ops;
  220. result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c_bus, soft_i2c_config[i].bus_name);
  221. RT_ASSERT(result == RT_EOK);
  222. hc32_i2c_bus_unlock(&soft_i2c_config[i]);
  223. }
  224. return RT_EOK;
  225. }
  226. INIT_BOARD_EXPORT(hc32_soft_i2c_init);
  227. #endif
  228. #endif /* RT_USING_I2C */
  229. /*******************************************************************************
  230. * EOF (not truncated)
  231. ******************************************************************************/