1
0

drv_soft_i2c.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-09-13 AisinoChip first implementation.
  9. */
  10. #include <board.h>
  11. #ifdef RT_USING_I2C_BITOPS
  12. #include <rtdevice.h>
  13. #include <drivers/pin.h>
  14. #define I2C_BUS_NAME "i2cs"
  15. /* user should change this to adapt specific board */
  16. #define I2C_SCL_PIN GPIO_PIN_6
  17. #define I2C_SCL_PORT GPIOD
  18. #define I2C_SDA_PIN GPIO_PIN_7
  19. #define I2C_SDA_PORT GPIOD
  20. struct acm32_i2c_bit_data
  21. {
  22. struct
  23. {
  24. enum_GPIOx_t port;
  25. rt_uint32_t pin;
  26. } scl, sda;
  27. };
  28. static void _set_sda(void *data, rt_int32_t state)
  29. {
  30. struct acm32_i2c_bit_data* bd = data;
  31. if (state)
  32. {
  33. HAL_GPIO_WritePin(bd->sda.port, bd->sda.pin, GPIO_PIN_SET);
  34. }
  35. else
  36. {
  37. HAL_GPIO_WritePin(bd->sda.port, bd->sda.pin, GPIO_PIN_CLEAR);
  38. }
  39. }
  40. static void _set_scl(void *data, rt_int32_t state)
  41. {
  42. struct acm32_i2c_bit_data* bd = data;
  43. if (state)
  44. {
  45. HAL_GPIO_WritePin(bd->scl.port, bd->scl.pin, GPIO_PIN_SET);
  46. }
  47. else
  48. {
  49. HAL_GPIO_WritePin(bd->scl.port, bd->scl.pin, GPIO_PIN_CLEAR);
  50. }
  51. }
  52. static rt_int32_t _get_sda(void *data)
  53. {
  54. struct acm32_i2c_bit_data* bd = data;
  55. return HAL_GPIO_ReadPin(bd->sda.port, bd->sda.pin);
  56. }
  57. static rt_int32_t _get_scl(void *data)
  58. {
  59. struct acm32_i2c_bit_data* bd = data;
  60. return HAL_GPIO_ReadPin(bd->scl.port, bd->scl.pin);
  61. }
  62. static void acm32_udelay(rt_uint32_t us)
  63. {
  64. rt_uint32_t ticks;
  65. rt_uint32_t told, tnow, tcnt = 0;
  66. rt_uint32_t reload = SysTick->LOAD;
  67. ticks = us * reload / (1000000 / RT_TICK_PER_SECOND);
  68. told = SysTick->VAL;
  69. while (1)
  70. {
  71. tnow = SysTick->VAL;
  72. if (tnow != told)
  73. {
  74. if (tnow < told)
  75. {
  76. tcnt += told - tnow;
  77. }
  78. else
  79. {
  80. tcnt += reload - tnow + told;
  81. }
  82. told = tnow;
  83. if (tcnt >= ticks)
  84. {
  85. break;
  86. }
  87. }
  88. }
  89. }
  90. static void drv_i2c_gpio_init(const struct acm32_i2c_bit_data* bd)
  91. {
  92. GPIO_InitTypeDef GPIO_Handle;
  93. GPIO_Handle.Pin = bd->sda.pin;
  94. GPIO_Handle.Mode = GPIO_MODE_OUTPUT_OD;
  95. GPIO_Handle.Pull = GPIO_PULLUP;
  96. GPIO_Handle.Alternate = GPIO_FUNCTION_0;
  97. HAL_GPIO_Init(bd->sda.port, &GPIO_Handle);
  98. GPIO_Handle.Pin = bd->scl.pin;
  99. GPIO_Handle.Mode = GPIO_MODE_OUTPUT_OD;
  100. GPIO_Handle.Pull = GPIO_PULLUP;
  101. GPIO_Handle.Alternate = GPIO_FUNCTION_0;
  102. HAL_GPIO_Init(bd->scl.port, &GPIO_Handle);
  103. _set_sda((void*)bd, 1);
  104. _set_scl((void*)bd, 1);
  105. }
  106. int rt_soft_i2c_init(void)
  107. {
  108. static struct rt_i2c_bus_device i2c_device;
  109. static const struct acm32_i2c_bit_data _i2c_bdata =
  110. {
  111. /* SCL */
  112. { I2C_SCL_PORT, I2C_SCL_PIN},
  113. /* SDA */
  114. { I2C_SDA_PORT, I2C_SDA_PIN},
  115. };
  116. static const struct rt_i2c_bit_ops _i2c_bit_ops =
  117. {
  118. (void*)&_i2c_bdata,
  119. _set_sda,
  120. _set_scl,
  121. _get_sda,
  122. _get_scl,
  123. acm32_udelay,
  124. 1,
  125. 100
  126. };
  127. drv_i2c_gpio_init(&_i2c_bdata);
  128. i2c_device.priv = (void *)&_i2c_bit_ops;
  129. rt_i2c_bit_add_bus(&i2c_device, I2C_BUS_NAME);
  130. return 0;
  131. }
  132. INIT_DEVICE_EXPORT(rt_soft_i2c_init);
  133. #endif /* RT_USING_I2C_BITOPS */