drv_qspi.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2019-3-30 bluebear233 first version
  9. */
  10. #include "NuMicro.h"
  11. #include <rtdevice.h>
  12. #ifdef RT_USING_SPI
  13. /* Private Define ---------------------------------------------------------------*/
  14. #define USEING_QSPI0
  15. /* Private Typedef --------------------------------------------------------------*/
  16. struct m487_qspi
  17. {
  18. struct rt_spi_bus dev;
  19. struct rt_spi_configuration configuration;
  20. QSPI_T *spi_base;
  21. rt_uint8_t init_gpio:1;
  22. };
  23. /* Private functions ------------------------------------------------------------*/
  24. static rt_err_t m487_qspi_bus_configure(struct rt_spi_device *device,
  25. struct rt_spi_configuration *configuration);
  26. static rt_uint32_t m487_qspi_bus_xfer(struct rt_spi_device *device,
  27. struct rt_spi_message *message);
  28. /* Private Variables ------------------------------------------------------------*/
  29. struct rt_spi_ops m487_spi_poll_ops =
  30. {
  31. .configure = m487_qspi_bus_configure,
  32. .xfer = m487_qspi_bus_xfer,
  33. };
  34. #ifdef USEING_QSPI0
  35. static struct m487_qspi qspi0 =
  36. {
  37. .spi_base = QSPI0,
  38. };
  39. #endif
  40. static rt_err_t m487_qspi_bus_configure(struct rt_spi_device *device,
  41. struct rt_spi_configuration *configuration) {
  42. struct m487_qspi *spi;
  43. uint32_t u32QSPIMode;
  44. uint32_t u32BusClock;
  45. rt_uint8_t init_bus;
  46. spi = (struct m487_qspi *) device->bus;
  47. init_bus = 0;
  48. if (!spi->init_gpio)
  49. {
  50. spi->init_gpio = 1;
  51. init_bus = 1;
  52. if(spi->spi_base == QSPI0)
  53. {
  54. /* Select PCLK0 as the clock source of QSPI0 */
  55. CLK_SetModuleClock(QSPI0_MODULE, CLK_CLKSEL2_QSPI0SEL_PLL,
  56. MODULE_NoMsk);
  57. /* Enable QSPI0 peripheral clock */
  58. CLK_EnableModuleClock(QSPI0_MODULE);
  59. /* Setup QSPI0 multi-function pins */
  60. SYS->GPC_MFPL &= ~(SYS_GPC_MFPL_PC0MFP_Msk | SYS_GPC_MFPL_PC1MFP_Msk
  61. | SYS_GPC_MFPL_PC2MFP_Msk | SYS_GPC_MFPL_PC3MFP_Msk);
  62. SYS->GPC_MFPL |= SYS_GPC_MFPL_PC0MFP_QSPI0_MOSI0 | SYS_GPC_MFPL_PC1MFP_QSPI0_MISO0
  63. | SYS_GPC_MFPL_PC2MFP_QSPI0_CLK | SYS_GPC_MFPL_PC3MFP_QSPI0_SS;
  64. /* Enable SPI0 clock pin (PC2) schmitt trigger */
  65. PC->SMTEN |= GPIO_SMTEN_SMTEN2_Msk;
  66. }
  67. }
  68. if(rt_memcmp(configuration, &spi->configuration, sizeof(*configuration)) != 0)
  69. {
  70. rt_memcpy(&spi->configuration, configuration, sizeof(*configuration));
  71. init_bus = 1;
  72. }
  73. if(init_bus)
  74. {
  75. switch(configuration->mode & RT_SPI_MODE_3)
  76. {
  77. case RT_SPI_MODE_0:u32QSPIMode = QSPI_MODE_0;break;
  78. case RT_SPI_MODE_1:u32QSPIMode = QSPI_MODE_1;break;
  79. case RT_SPI_MODE_2:u32QSPIMode = QSPI_MODE_2;break;
  80. case RT_SPI_MODE_3:u32QSPIMode = QSPI_MODE_3;break;
  81. default:RT_ASSERT(0);
  82. }
  83. u32BusClock = configuration->max_hz;
  84. if(u32BusClock > 50*1000*1000)
  85. {
  86. u32BusClock = 50*1000*1000;
  87. }
  88. QSPI_Open(spi->spi_base, QSPI_MASTER, u32QSPIMode, configuration->data_width, u32BusClock);
  89. QSPI_EnableAutoSS(spi->spi_base, QSPI_SS, QSPI_SS_ACTIVE_LOW);
  90. if(configuration->mode & RT_SPI_MSB)
  91. {
  92. QSPI_SET_MSB_FIRST(spi->spi_base);
  93. }
  94. else
  95. {
  96. QSPI_SET_LSB_FIRST(spi->spi_base);
  97. }
  98. }
  99. return RT_EOK;
  100. }
  101. /**
  102. * @brief SPI bus 轮询
  103. * @param dev : SPI总线设备结构体指针
  104. * @param send_addr : 发送缓冲区地址
  105. * @param recv_addr : 接收缓冲区地址
  106. * @param length : 数据长度
  107. */
  108. static void qspi_transmission_with_poll(struct m487_qspi *spi_bus,
  109. const uint8_t *send_addr, uint8_t *recv_addr, int length)
  110. {
  111. QSPI_T *spi_base = spi_bus->spi_base;
  112. // 写
  113. if (send_addr != RT_NULL && recv_addr == RT_NULL)
  114. {
  115. while (length--)
  116. {
  117. // 等待TX FIFO 为空
  118. while(QSPI_GET_TX_FIFO_FULL_FLAG(spi_base));
  119. // 输入数据
  120. QSPI_WRITE_TX(spi_base, *send_addr++);
  121. }
  122. // 等待SPI空闲
  123. while(QSPI_IS_BUSY(spi_base));
  124. }
  125. // 读写
  126. else if (send_addr != RT_NULL && recv_addr != RT_NULL)
  127. {
  128. // 清空读FIFO
  129. if(!QSPI_GET_RX_FIFO_EMPTY_FLAG(spi_base))
  130. {
  131. QSPI_ClearRxFIFO(spi_base);
  132. while(!QSPI_GET_RX_FIFO_EMPTY_FLAG(spi_base));
  133. }
  134. while (length--)
  135. {
  136. // 等待TX FIFO 为空
  137. while(QSPI_GET_TX_FIFO_FULL_FLAG(spi_base));
  138. // 输入数据
  139. QSPI_WRITE_TX(spi_base, *send_addr++);
  140. // 读取RX FIFO
  141. while(!QSPI_GET_RX_FIFO_EMPTY_FLAG(spi_base))
  142. {
  143. *recv_addr++ = QSPI_READ_RX(spi_base);
  144. }
  145. }
  146. // 等待SPI空闲
  147. while(QSPI_IS_BUSY(spi_base))
  148. {
  149. while(!QSPI_GET_RX_FIFO_EMPTY_FLAG(spi_base))
  150. {
  151. *recv_addr++ = QSPI_READ_RX(spi_base);
  152. }
  153. }
  154. }
  155. //读
  156. else
  157. {
  158. // 清空读FIFO
  159. if(!QSPI_GET_RX_FIFO_EMPTY_FLAG(spi_base))
  160. {
  161. QSPI_ClearRxFIFO(spi_base);
  162. while(!QSPI_GET_RX_FIFO_EMPTY_FLAG(spi_base));
  163. }
  164. while (length--)
  165. {
  166. // 等待TX FIFO 为空
  167. while(QSPI_GET_TX_FIFO_FULL_FLAG(spi_base));
  168. // 输入数据
  169. QSPI_WRITE_TX(spi_base, 0x00);
  170. // 读取RX FIFO
  171. while(!QSPI_GET_RX_FIFO_EMPTY_FLAG(spi_base))
  172. {
  173. *recv_addr++ = QSPI_READ_RX(spi_base);
  174. }
  175. }
  176. // 等待SPI空闲
  177. while(QSPI_IS_BUSY(spi_base))
  178. {
  179. while(!QSPI_GET_RX_FIFO_EMPTY_FLAG(spi_base))
  180. {
  181. *recv_addr++ = QSPI_READ_RX(spi_base);
  182. }
  183. }
  184. while(!QSPI_GET_RX_FIFO_EMPTY_FLAG(spi_base))
  185. {
  186. *recv_addr++ = QSPI_READ_RX(spi_base);
  187. }
  188. }
  189. }
  190. static rt_uint32_t m487_qspi_bus_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
  191. {
  192. struct m487_qspi *spi;
  193. spi = (struct m487_qspi *) device->bus;
  194. if (message->cs_take)
  195. {
  196. QSPI_SET_SS_LOW(spi->spi_base);
  197. }
  198. if (message->length > 0)
  199. {
  200. qspi_transmission_with_poll(spi, message->send_buf,
  201. message->recv_buf, message->length);
  202. }
  203. if (message->cs_release)
  204. {
  205. QSPI_SET_SS_HIGH(spi->spi_base);
  206. }
  207. return message->length;
  208. }
  209. static int m487_qspi_register_bus(struct m487_qspi *spi_bus, const char *name)
  210. {
  211. return rt_spi_bus_register(&spi_bus->dev, name, &m487_spi_poll_ops);
  212. }
  213. /**
  214. * 硬件QSPI注册
  215. */
  216. static int rt_hw_qspi_init(void)
  217. {
  218. #ifdef USEING_QSPI0
  219. m487_qspi_register_bus(&qspi0, "qspi0");
  220. #endif
  221. return 0;
  222. }
  223. INIT_DEVICE_EXPORT(rt_hw_qspi_init);
  224. #endif