drv_spi.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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_spi.h"
  11. #include "raspi.h"
  12. #ifdef RT_USING_SPI
  13. #define RPI_CORE_CLK_HZ 250000000
  14. #define BSP_SPI_MAX_HZ (30* 1000 *1000)
  15. #define SPITIMEOUT 0x0FFF
  16. void spi_gpio_write(rt_uint8_t pin, rt_uint8_t val)
  17. {
  18. if (val)
  19. BCM283X_GPIO_GPSET((pin / 32)) = 1 << (pin % 32);
  20. else
  21. BCM283X_GPIO_GPCLR((pin / 32)) = 1 << (pin % 32);
  22. }
  23. struct raspi_spi_hw_config
  24. {
  25. rt_uint8_t spi_num;
  26. raspi_gpio_pin sclk_pin;
  27. raspi_pin_select sclk_mode;
  28. raspi_gpio_pin mosi_pin;
  29. raspi_pin_select mosi_mode;
  30. raspi_gpio_pin miso_pin;
  31. raspi_pin_select miso_mode;
  32. #if defined (BSP_USING_SPI0_DEVICE0) || defined (BSP_USING_SPI1_DEVICE0)
  33. raspi_gpio_pin ce0_pin;
  34. raspi_pin_select ce0_mode;
  35. #endif
  36. #if defined (BSP_USING_SPI0_DEVICE1) || defined (BSP_USING_SPI1_DEVICE1)
  37. raspi_gpio_pin ce1_pin;
  38. raspi_pin_select ce1_mode;
  39. #endif
  40. #if defined (BSP_USING_SPI1_DEVICE2)
  41. raspi_gpio_pin ce2_pin;
  42. raspi_pin_select ce2_mode;
  43. #endif
  44. };
  45. struct raspi_spi_device
  46. {
  47. char *device_name;
  48. struct rt_spi_bus *spi_bus;
  49. struct rt_spi_device *spi_device;
  50. raspi_gpio_pin cs_pin;
  51. };
  52. static rt_err_t raspi_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
  53. {
  54. RT_ASSERT(cfg != RT_NULL);
  55. RT_ASSERT(device != RT_NULL);
  56. rt_uint16_t divider;
  57. // spi clear fifo
  58. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CLEAR;
  59. if (cfg->mode & RT_SPI_CPOL)
  60. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CPOL;
  61. if (cfg->mode & RT_SPI_CPHA)
  62. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CPHA;
  63. if (cfg->mode & RT_SPI_CS_HIGH)
  64. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CSPOL;
  65. //set clk
  66. if (cfg->max_hz > BSP_SPI_MAX_HZ)
  67. cfg->max_hz = BSP_SPI_MAX_HZ;
  68. divider = (rt_uint16_t) ((rt_uint32_t) RPI_CORE_CLK_HZ / cfg->max_hz);
  69. divider &= 0xFFFE;
  70. BCM283X_SPI0_CLK(BCM283X_SPI0_BASE) = divider;
  71. return RT_EOK;
  72. }
  73. rt_uint8_t correct_order(rt_uint8_t b, rt_uint8_t flag)
  74. {
  75. if (flag)
  76. return raspi_byte_reverse_table[b];
  77. else
  78. return b;
  79. }
  80. static rt_err_t spi_transfernb(rt_uint8_t* tbuf, rt_uint8_t* rbuf, rt_uint32_t len, rt_uint8_t flag)
  81. {
  82. rt_uint32_t TXCnt=0;
  83. rt_uint32_t RXCnt=0;
  84. /* Clear TX and RX fifos */
  85. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= (BCM283X_SPI0_CS_CLEAR & BCM283X_SPI0_CS_CLEAR);
  86. /* Set TA = 1 */
  87. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= (BCM283X_SPI0_CS_TA & BCM283X_SPI0_CS_TA);
  88. /* Use the FIFO's to reduce the interbyte times */
  89. while ((TXCnt < len) || (RXCnt < len))
  90. {
  91. /* TX fifo not full, so add some more bytes */
  92. while (((BCM283X_SPI0_CS(BCM283X_SPI0_BASE) & BCM283X_SPI0_CS_TXD)) && (TXCnt < len))
  93. {
  94. BCM283X_SPI0_FIFO(BCM283X_SPI0_BASE) = correct_order(tbuf[TXCnt],flag);
  95. TXCnt++;
  96. }
  97. /* Rx fifo not empty, so get the next received bytes */
  98. while (((BCM283X_SPI0_CS(BCM283X_SPI0_BASE) & BCM283X_SPI0_CS_RXD)) && (RXCnt < len))
  99. {
  100. rbuf[RXCnt] = correct_order(BCM283X_SPI0_FIFO(BCM283X_SPI0_BASE),flag);
  101. RXCnt++;
  102. }
  103. }
  104. /* Wait for DONE to be set */
  105. while (!(BCM283X_SPI0_CS(BCM283X_SPI0_BASE) & BCM283X_SPI0_CS_DONE));
  106. /* Set TA = 0, and also set the barrier */
  107. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= (0 & BCM283X_SPI0_CS_TA);
  108. return RT_EOK;
  109. }
  110. static rt_ssize_t raspi_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
  111. {
  112. RT_ASSERT(device != RT_NULL);
  113. RT_ASSERT(device->bus != RT_NULL);
  114. RT_ASSERT(device->parent.user_data != RT_NULL);
  115. RT_ASSERT(message->send_buf != RT_NULL || message->recv_buf != RT_NULL);
  116. rt_err_t res;
  117. rt_uint8_t flag;
  118. struct rt_spi_configuration config = device->config;
  119. raspi_gpio_pin cs_pin = (raspi_gpio_pin)device->parent.user_data;
  120. if (config.mode & RT_SPI_MSB)
  121. flag = 0;
  122. else
  123. flag = 1;
  124. if (message->cs_take);
  125. // (config.mode & RT_SPI_CS_HIGH)?
  126. // spi_gpio_write(cs_pin, 1):
  127. // spi_gpio_write(cs_pin, 0);
  128. /* deal data */
  129. res = spi_transfernb((rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf,
  130. (rt_int32_t)message->length, flag);
  131. if (message->cs_release)
  132. (config.mode & RT_SPI_CS_HIGH)?
  133. spi_gpio_write(cs_pin, 0):
  134. spi_gpio_write(cs_pin, 1);
  135. if (res != RT_EOK)
  136. return res;
  137. return message->length;
  138. }
  139. rt_err_t raspi_spi_bus_attach_device(const char *bus_name, struct raspi_spi_device *device)
  140. {
  141. rt_err_t ret;
  142. RT_ASSERT(device != RT_NULL);
  143. ret = rt_spi_bus_attach_device(device->spi_device, device->device_name, bus_name, (void *)(device->cs_pin));
  144. return ret;
  145. }
  146. rt_err_t raspi_spi_hw_init(struct raspi_spi_hw_config *hwcfg)
  147. {
  148. GPIO_FSEL(hwcfg->sclk_pin, hwcfg->sclk_mode);
  149. GPIO_FSEL(hwcfg->miso_pin, hwcfg->miso_mode);
  150. GPIO_FSEL(hwcfg->mosi_pin, hwcfg->mosi_mode);
  151. #if defined (BSP_USING_SPI0_DEVICE0)
  152. GPIO_FSEL(hwcfg->ce0_pin, hwcfg->ce0_mode);
  153. #endif
  154. #if defined (BSP_USING_SPI0_DEVICE1)
  155. GPIO_FSEL(hwcfg->ce1_pin, hwcfg->ce1_mode);
  156. #endif
  157. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) = 0;
  158. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) = BCM283X_SPI0_CS_CLEAR;
  159. //enable chip select
  160. #if defined (BSP_USING_SPI0_DEVICE0)
  161. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= 0;
  162. #endif
  163. #if defined (BSP_USING_SPI0_DEVICE1)
  164. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= 0x2;
  165. #endif
  166. #if defined (BSP_USING_SPI0_DEVICE0) && defined (BSP_USING_SPI0_DEVICE1)
  167. BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CS;
  168. #endif
  169. return RT_EOK;
  170. }
  171. static struct rt_spi_ops raspi_spi_ops =
  172. {
  173. .configure = raspi_spi_configure,
  174. .xfer = raspi_spi_xfer
  175. };
  176. #if defined (BSP_USING_SPI0_BUS)
  177. #define SPI0_BUS_NAME "spi0"
  178. #define SPI0_DEVICE0_NAME "spi0.0"
  179. #define SPI0_DEVICE1_NAME "spi0.1"
  180. struct rt_spi_bus spi0_bus;
  181. #if defined (BSP_USING_SPI0_DEVICE0)
  182. struct rt_spi_device spi0_device0;
  183. #endif
  184. #if defined (BSP_USING_SPI0_DEVICE1)
  185. static struct rt_spi_device spi0_device1;
  186. #endif
  187. struct raspi_spi_hw_config raspi_spi0_hw =
  188. {
  189. .spi_num = 0,
  190. .sclk_pin = RPI_GPIO_P1_23,
  191. .sclk_mode = BCM283X_GPIO_FSEL_ALT0,
  192. .mosi_pin = RPI_GPIO_P1_19,
  193. .mosi_mode = BCM283X_GPIO_FSEL_ALT0,
  194. .miso_pin = RPI_GPIO_P1_21,
  195. .miso_mode = BCM283X_GPIO_FSEL_ALT0,
  196. #if defined (BSP_USING_SPI0_DEVICE0)
  197. .ce0_pin = RPI_GPIO_P1_24,
  198. .ce0_mode = BCM283X_GPIO_FSEL_ALT0,
  199. #endif
  200. #if defined (BSP_USING_SPI0_DEVICE1)
  201. .ce1_pin = RPI_GPIO_P1_26,
  202. .ce1_mode = BCM283X_GPIO_FSEL_ALT0,
  203. #endif
  204. };
  205. #endif
  206. int rt_hw_spi_init(void)
  207. {
  208. #if defined (BSP_USING_SPI0_BUS)
  209. raspi_spi_hw_init(&raspi_spi0_hw);
  210. rt_spi_bus_register(&spi0_bus, SPI0_BUS_NAME, &raspi_spi_ops);
  211. #if defined (BSP_USING_SPI0_DEVICE0)
  212. struct raspi_spi_device raspi_spi0_device0 =
  213. {
  214. .device_name = SPI0_DEVICE0_NAME,
  215. .spi_bus = &spi0_bus,
  216. .spi_device = &spi0_device0,
  217. .cs_pin = raspi_spi0_hw.ce0_pin,
  218. };
  219. raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device0);
  220. #endif
  221. #if defined (BSP_USING_SPI0_DEVICE1)
  222. struct raspi_spi_device raspi_spi0_device1 =
  223. {
  224. .device_name = SPI0_DEVICE1_NAME,
  225. .spi_bus = &spi0_bus,
  226. .spi_device = &spi0_device1,
  227. .cs_pin = raspi_spi0_hw.ce1_pin,
  228. };
  229. raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device1);
  230. #endif
  231. #endif
  232. return RT_EOK;
  233. }
  234. INIT_DEVICE_EXPORT(rt_hw_spi_init);
  235. #endif