drv_spi.c 7.6 KB

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