drv_i2c.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-07-29 zdzn first version
  9. */
  10. #include "drv_i2c.h"
  11. rt_uint8_t i2c_read_or_write(volatile rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len, rt_uint8_t flag)
  12. {
  13. rt_uint32_t status;
  14. rt_uint32_t remaining = len;
  15. rt_uint32_t i = 0;
  16. rt_uint8_t reason = BCM283X_I2C_REASON_OK;
  17. /* Clear FIFO */
  18. BCM283X_BSC_C(base) |= (BSC_C_CLEAR_1 & BSC_C_CLEAR_1);
  19. /* Clear Status */
  20. BCM283X_BSC_S(base) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE;
  21. /* Set Data Length */
  22. BCM283X_BSC_DLEN(base) = len;
  23. if (flag)
  24. {
  25. /* Start read */
  26. BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST | BSC_C_READ;
  27. /* wait for transfer to complete */
  28. while (!(BCM283X_BSC_S(base) & BSC_S_DONE))
  29. {
  30. /* we must empty the FIFO as it is populated and not use any delay */
  31. while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD))
  32. {
  33. /* Read from FIFO, no barrier */
  34. buf[i] = BCM283X_BSC_FIFO(base);
  35. i++;
  36. remaining--;
  37. }
  38. }
  39. /* transfer has finished - grab any remaining stuff in FIFO */
  40. while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD))
  41. {
  42. /* Read from FIFO, no barrier */
  43. buf[i] = BCM283X_BSC_FIFO(base);
  44. i++;
  45. remaining--;
  46. }
  47. }
  48. else
  49. {
  50. /* pre populate FIFO with max buffer */
  51. while (remaining && (i < BSC_FIFO_SIZE))
  52. {
  53. BCM283X_BSC_FIFO(base) = buf[i];
  54. i++;
  55. remaining--;
  56. }
  57. /* Enable device and start transfer */
  58. BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST;
  59. /* Transfer is over when BCM2835_BSC_S_DONE */
  60. while (!(BCM283X_BSC_S(base) & BSC_S_DONE))
  61. {
  62. while (remaining && (BCM283X_BSC_S(base) & BSC_S_TXD))
  63. {
  64. /* Write to FIFO */
  65. BCM283X_BSC_FIFO(base) = buf[i];
  66. i++;
  67. remaining--;
  68. }
  69. }
  70. }
  71. status = BCM283X_BSC_S(base);
  72. if (status & BSC_S_ERR)
  73. {
  74. reason = BCM283X_I2C_REASON_ERROR_NACK;
  75. }
  76. else if (status & BSC_S_CLKT)
  77. {
  78. reason = BCM283X_I2C_REASON_ERROR_CLKT;
  79. }
  80. else if (remaining)
  81. {
  82. reason = BCM283X_I2C_REASON_ERROR_DATA;
  83. }
  84. BCM283X_BSC_C(base) |= (BSC_S_DONE & BSC_S_DONE);
  85. return reason;
  86. }
  87. struct raspi_i2c_hw_config
  88. {
  89. rt_uint8_t bsc_num;
  90. rt_uint8_t sdl_pin;
  91. rt_uint8_t scl_pin;
  92. rt_uint8_t sdl_mode;
  93. rt_uint8_t scl_mode;
  94. };
  95. #if (defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1))
  96. static rt_ssize_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  97. struct rt_i2c_msg msgs[],
  98. rt_uint32_t num);
  99. static rt_ssize_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
  100. struct rt_i2c_msg msgs[],
  101. rt_uint32_t num);
  102. static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus,
  103. int cmd,
  104. void *args);
  105. static rt_uint32_t i2c_byte_wait_us = 0;
  106. static rt_ssize_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
  107. struct rt_i2c_msg msgs[],
  108. rt_uint32_t num)
  109. {
  110. rt_size_t i;
  111. rt_uint8_t reason;
  112. RT_ASSERT(bus != RT_NULL);
  113. volatile rt_uint32_t base = (volatile rt_uint32_t)(bus->parent.user_data);
  114. if (bus->parent.user_data == 0)
  115. base = BCM283X_BSC0_BASE;
  116. else
  117. base = BCM283X_BSC1_BASE;
  118. BCM283X_BSC_A(base) = msgs->addr;
  119. for (i = 0; i < num; i++)
  120. {
  121. if (msgs[i].flags & RT_I2C_RD)
  122. reason = i2c_read_or_write(base, msgs->buf, msgs->len, 1);
  123. else
  124. reason = i2c_read_or_write(base, msgs->buf, msgs->len, 0);
  125. }
  126. return (reason == 0)? i : 0;
  127. }
  128. static rt_ssize_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
  129. struct rt_i2c_msg msgs[],
  130. rt_uint32_t num)
  131. {
  132. return 0;
  133. }
  134. static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus,
  135. int cmd,
  136. void *args)
  137. {
  138. return RT_EOK;
  139. }
  140. static const struct rt_i2c_bus_device_ops raspi_i2c_ops =
  141. {
  142. .master_xfer = raspi_i2c_mst_xfer,
  143. .slave_xfer = raspi_i2c_slv_xfer,
  144. .i2c_bus_control = raspi_i2c_bus_control,
  145. };
  146. static rt_err_t raspi_i2c_configure(struct raspi_i2c_hw_config *cfg)
  147. {
  148. RT_ASSERT(cfg != RT_NULL);
  149. volatile rt_uint32_t base = cfg->scl_mode ? BCM283X_BSC1_BASE : BCM283X_BSC0_BASE;
  150. GPIO_FSEL(cfg->sdl_pin, cfg->sdl_mode); /* SDA */
  151. GPIO_FSEL(cfg->scl_pin, cfg->scl_mode); /* SCL */
  152. /* use 0xFFFE mask to limit a max value and round down any odd number */
  153. rt_uint32_t divider = (BCM283X_CORE_CLK_HZ / 10000) & 0xFFFE;
  154. BCM283X_BSC_DIV(base) = (rt_uint16_t) divider;
  155. i2c_byte_wait_us = (divider * 1000000 * 9 / BCM283X_CORE_CLK_HZ);
  156. return RT_EOK;
  157. }
  158. #endif
  159. #if defined (BSP_USING_I2C0)
  160. #define I2C0_BUS_NAME "i2c0"
  161. static struct raspi_i2c_hw_config hw_device0 =
  162. {
  163. .bsc_num = 0,
  164. .sdl_pin = RPI_GPIO_P1_27,
  165. .scl_pin = RPI_GPIO_P1_28,
  166. .sdl_mode = BCM283X_GPIO_FSEL_ALT0,
  167. .scl_mode = BCM283X_GPIO_FSEL_ALT0,
  168. };
  169. struct rt_i2c_bus_device device0 =
  170. {
  171. .ops = &raspi_i2c_ops,
  172. };
  173. #endif
  174. #if defined (BSP_USING_I2C1)
  175. #define I2C1_BUS_NAME "i2c1"
  176. static struct raspi_i2c_hw_config hw_device1 =
  177. {
  178. .bsc_num = 1,
  179. .sdl_pin = RPI_GPIO_P1_03,
  180. .scl_pin = RPI_GPIO_P1_05,
  181. .sdl_mode = BCM283X_GPIO_FSEL_ALT0,
  182. .scl_mode = BCM283X_GPIO_FSEL_ALT0,
  183. };
  184. struct rt_i2c_bus_device device1 =
  185. {
  186. .ops = &raspi_i2c_ops,
  187. };
  188. #endif
  189. int rt_hw_i2c_init(void)
  190. {
  191. #if defined(BSP_USING_I2C0)
  192. device0.parent.user_data = (void *)0;
  193. raspi_i2c_configure(&hw_device0);
  194. rt_i2c_bus_device_register(&device0, I2C0_BUS_NAME);
  195. #endif
  196. #if defined(BSP_USING_I2C1)
  197. device1.parent.user_data = (void *)1;
  198. raspi_i2c_configure(&hw_device1);
  199. rt_i2c_bus_device_register(&device1, I2C1_BUS_NAME);
  200. #endif
  201. return 0;
  202. }
  203. INIT_DEVICE_EXPORT(rt_hw_i2c_init);