drv_spi.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  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. * 2018-11-5 SummerGift change to new framework
  9. */
  10. #include "board.h"
  11. #define RT_USING_SPI
  12. #ifdef RT_USING_SPI
  13. #define BSP_USING_SPI1
  14. #if defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3) || defined(BSP_USING_SPI4) || defined(BSP_USING_SPI5) || defined(BSP_USING_SPI6)
  15. /* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */
  16. #include "drv_spi.h"
  17. #include "drv_config.h"
  18. //#define DRV_DEBUG
  19. #define LOG_TAG "drv.spi"
  20. #include <drv_log.h>
  21. enum
  22. {
  23. #ifdef BSP_USING_SPI1
  24. SPI1_INDEX,
  25. #endif
  26. #ifdef BSP_USING_SPI2
  27. SPI2_INDEX,
  28. #endif
  29. #ifdef BSP_USING_SPI3
  30. SPI3_INDEX,
  31. #endif
  32. #ifdef BSP_USING_SPI4
  33. SPI4_INDEX,
  34. #endif
  35. #ifdef BSP_USING_SPI5
  36. SPI5_INDEX,
  37. #endif
  38. #ifdef BSP_USING_SPI6
  39. SPI6_INDEX,
  40. #endif
  41. };
  42. static struct stm32_spi_config spi_config[] =
  43. {
  44. #ifdef BSP_USING_SPI1
  45. SPI1_BUS_CONFIG,
  46. #endif
  47. #ifdef BSP_USING_SPI2
  48. SPI2_BUS_CONFIG,
  49. #endif
  50. #ifdef BSP_USING_SPI3
  51. SPI3_BUS_CONFIG,
  52. #endif
  53. #ifdef BSP_USING_SPI4
  54. SPI4_BUS_CONFIG,
  55. #endif
  56. #ifdef BSP_USING_SPI5
  57. SPI5_BUS_CONFIG,
  58. #endif
  59. #ifdef BSP_USING_SPI6
  60. SPI6_BUS_CONFIG,
  61. #endif
  62. };
  63. static struct stm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])];
  64. static rt_err_t stm32_spi_init(struct stm32_spi *spi_drv, struct rt_spi_configuration *cfg)
  65. {
  66. RT_ASSERT(spi_drv != RT_NULL);
  67. RT_ASSERT(cfg != RT_NULL);
  68. SPI_HandleTypeDef *spi_handle = &spi_drv->handle;
  69. if (cfg->mode & RT_SPI_SLAVE)
  70. {
  71. spi_handle->Init.Mode = SPI_MODE_SLAVE;
  72. }
  73. else
  74. {
  75. spi_handle->Init.Mode = SPI_MODE_MASTER;
  76. }
  77. if (cfg->mode & RT_SPI_3WIRE)
  78. {
  79. spi_handle->Init.Direction = SPI_DIRECTION_1LINE;
  80. }
  81. else
  82. {
  83. spi_handle->Init.Direction = SPI_DIRECTION_2LINES;
  84. }
  85. if (cfg->data_width == 8)
  86. {
  87. spi_handle->Init.DataSize = SPI_DATASIZE_8BIT;
  88. spi_handle->TxXferSize = 8;
  89. spi_handle->RxXferSize = 8;
  90. }
  91. else if (cfg->data_width == 16)
  92. {
  93. spi_handle->Init.DataSize = SPI_DATASIZE_16BIT;
  94. }
  95. else
  96. {
  97. return RT_EIO;
  98. }
  99. if (cfg->mode & RT_SPI_CPHA)
  100. {
  101. spi_handle->Init.CLKPhase = SPI_PHASE_2EDGE;
  102. }
  103. else
  104. {
  105. spi_handle->Init.CLKPhase = SPI_PHASE_1EDGE;
  106. }
  107. if (cfg->mode & RT_SPI_CPOL)
  108. {
  109. spi_handle->Init.CLKPolarity = SPI_POLARITY_HIGH;
  110. }
  111. else
  112. {
  113. spi_handle->Init.CLKPolarity = SPI_POLARITY_LOW;
  114. }
  115. if (cfg->mode & RT_SPI_NO_CS)
  116. {
  117. spi_handle->Init.NSS = SPI_NSS_SOFT;
  118. }
  119. else
  120. {
  121. spi_handle->Init.NSS = SPI_NSS_SOFT;
  122. }
  123. uint32_t SPI_APB_CLOCK;
  124. SPI_APB_CLOCK = HAL_RCC_GetPCLK2Freq();
  125. if (cfg->max_hz >= SPI_APB_CLOCK / 2)
  126. {
  127. spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  128. }
  129. else if (cfg->max_hz >= SPI_APB_CLOCK / 4)
  130. {
  131. spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  132. }
  133. else if (cfg->max_hz >= SPI_APB_CLOCK / 8)
  134. {
  135. spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  136. }
  137. else if (cfg->max_hz >= SPI_APB_CLOCK / 16)
  138. {
  139. spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
  140. }
  141. else if (cfg->max_hz >= SPI_APB_CLOCK / 32)
  142. {
  143. spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  144. }
  145. else if (cfg->max_hz >= SPI_APB_CLOCK / 64)
  146. {
  147. spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  148. }
  149. else if (cfg->max_hz >= SPI_APB_CLOCK / 128)
  150. {
  151. spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
  152. }
  153. else
  154. {
  155. /* min prescaler 256 */
  156. spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  157. }
  158. LOG_D("sys freq: %d, pclk2 freq: %d, SPI limiting freq: %d, BaudRatePrescaler: %d",
  159. HAL_RCC_GetSysClockFreq(),
  160. SPI_APB_CLOCK,
  161. cfg->max_hz,
  162. spi_handle->Init.BaudRatePrescaler);
  163. if (cfg->mode & RT_SPI_MSB)
  164. {
  165. spi_handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
  166. }
  167. else
  168. {
  169. spi_handle->Init.FirstBit = SPI_FIRSTBIT_LSB;
  170. }
  171. spi_handle->Init.TIMode = SPI_TIMODE_DISABLE;
  172. spi_handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  173. spi_handle->State = HAL_SPI_STATE_RESET;
  174. if (HAL_SPI_Init(spi_handle) != HAL_OK)
  175. {
  176. return RT_EIO;
  177. }
  178. #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7)
  179. SET_BIT(spi_handle->Instance->CR2, SPI_RXFIFO_THRESHOLD_HF);
  180. #endif
  181. __HAL_SPI_ENABLE(spi_handle);
  182. LOG_D("%s init done", spi_drv->config->bus_name);
  183. return RT_EOK;
  184. }
  185. #ifdef BSP_SPI_USING_DMA
  186. static uint8_t dummy = 0xFF;
  187. static void spi_dma_transfer_prepare(struct rt_spi_bus * spi_bus, struct rt_spi_message* message)
  188. {
  189. struct stm32_spi *spi_drv = rt_container_of(spi_bus, struct stm32_spi, spi_bus);
  190. DMA_HandleTypeDef * hdma_tx = (DMA_HandleTypeDef *)&spi_drv->dma.handle_tx;
  191. DMA_HandleTypeDef * hdma_rx = (DMA_HandleTypeDef *)&spi_drv->dma.handle_rx;
  192. HAL_DMA_DeInit(hdma_tx);
  193. HAL_DMA_DeInit(hdma_rx);
  194. /*
  195. * Check if the DMA Stream is disabled before enabling it.
  196. * Note that this step is useful when the same Stream is used multiple times.
  197. */
  198. #if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
  199. while (hdma_tx->Instance->CR & DMA_SxCR_EN);
  200. while (hdma_rx->Instance->CR & DMA_SxCR_EN);
  201. #endif
  202. if(message->recv_buf != RT_NULL)
  203. {
  204. hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
  205. }
  206. else
  207. {
  208. message->recv_buf = &dummy;
  209. hdma_rx->Init.MemInc = DMA_MINC_DISABLE;
  210. }
  211. HAL_DMA_Init(hdma_rx);
  212. __HAL_LINKDMA(&spi_drv->handle, hdmarx, spi_drv->dma.handle_rx);
  213. if(message->send_buf != RT_NULL)
  214. {
  215. hdma_tx->Init.MemInc = DMA_MINC_ENABLE;
  216. }
  217. else
  218. {
  219. dummy = 0xFF;
  220. message->send_buf = &dummy;
  221. hdma_tx->Init.MemInc = DMA_MINC_DISABLE;
  222. }
  223. HAL_DMA_Init(hdma_tx);
  224. /* link DMA with SPI */
  225. __HAL_LINKDMA(&spi_drv->handle, hdmatx, spi_drv->dma.handle_tx);
  226. LOG_D("%s RX Instance: %x, TX Instance: %x", spi_drv->config->bus_name, hdma_rx->Instance, hdma_tx->Instance);
  227. LOG_D("%s dma config done, TX dma_irq number: %d, RX dma_irq number: %d",
  228. spi_drv->config->bus_name,
  229. spi_drv->config->dma_tx.dma_irq,
  230. spi_drv->config->dma_rx.dma_irq);
  231. /* NVIC configuration for DMA transfer complete interrupt*/
  232. HAL_NVIC_SetPriority(spi_drv->config->dma_tx.dma_irq, 0, 1);
  233. HAL_NVIC_EnableIRQ(spi_drv->config->dma_tx.dma_irq);
  234. /* NVIC configuration for DMA transfer complete interrupt*/
  235. HAL_NVIC_SetPriority(spi_drv->config->dma_rx.dma_irq, 0, 0);
  236. HAL_NVIC_EnableIRQ(spi_drv->config->dma_rx.dma_irq);
  237. }
  238. #endif
  239. static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
  240. {
  241. RT_ASSERT(device != RT_NULL);
  242. RT_ASSERT(device->bus != RT_NULL);
  243. RT_ASSERT(device->bus->parent.user_data != RT_NULL);
  244. RT_ASSERT(message != RT_NULL);
  245. struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus);
  246. SPI_HandleTypeDef * spi_handle = &spi_drv->handle;
  247. struct stm32_hw_spi_cs *cs = device->parent.user_data;
  248. rt_int32_t length = message->length;
  249. rt_int32_t data_width = spi_drv->cfg->data_width;
  250. if (message->cs_take)
  251. {
  252. HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_RESET);
  253. }
  254. #ifdef BSP_SPI_USING_DMA
  255. if(message->length > 32)
  256. {
  257. if(data_width <= 8)
  258. {
  259. HAL_StatusTypeDef state;
  260. LOG_D("%s dma transfer prepare and start", spi_drv->config->bus_name);
  261. LOG_D("%s sendbuf: %X, recvbuf: %X, length: %d",
  262. spi_drv->config->bus_name,
  263. (uint32_t)message->send_buf,
  264. (uint32_t)message->recv_buf, message->length);
  265. spi_dma_transfer_prepare(device->bus, message);
  266. /* start once data exchange in DMA mode */
  267. state = HAL_SPI_TransmitReceive_DMA(spi_handle,
  268. (uint8_t*)message->send_buf,
  269. (uint8_t*)message->recv_buf,
  270. message->length);
  271. if (state != HAL_OK)
  272. {
  273. LOG_D("spi flash configuration error : %d", state);
  274. message->length = 0;
  275. //while(1);
  276. }
  277. else
  278. {
  279. LOG_D("%s dma transfer done", spi_drv->config->bus_name);
  280. }
  281. /* For simplicity reasons, this example is just waiting till the end of the
  282. transfer, but application may perform other tasks while transfer operation
  283. is ongoing. */
  284. while (HAL_SPI_GetState(spi_handle) != HAL_SPI_STATE_READY);
  285. LOG_D("%s get state done", spi_drv->config->bus_name);
  286. }
  287. else
  288. {
  289. // TODO
  290. }
  291. } else
  292. #endif
  293. {
  294. if (data_width == 8)
  295. {
  296. const rt_uint8_t * send_ptr = message->send_buf;
  297. rt_uint8_t * recv_ptr = message->recv_buf;
  298. while (length--)
  299. {
  300. rt_uint8_t data = ~0;
  301. if(send_ptr != RT_NULL)
  302. {
  303. data = *send_ptr++;
  304. }
  305. /* send data once */
  306. while (__HAL_SPI_GET_FLAG(spi_handle, SPI_FLAG_TXE) == RESET);
  307. *(volatile rt_uint8_t *)(&spi_handle->Instance->DR) = data;
  308. /* receive data once */
  309. #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7)
  310. SET_BIT(spi_handle->Instance->CR2, SPI_RXFIFO_THRESHOLD_HF);
  311. #endif
  312. while (__HAL_SPI_GET_FLAG(spi_handle, SPI_FLAG_RXNE) == RESET);
  313. data = *(volatile rt_uint8_t *)(&spi_handle->Instance->DR);
  314. if(recv_ptr != RT_NULL)
  315. {
  316. *recv_ptr++ = data;
  317. }
  318. }
  319. } else
  320. {
  321. const rt_uint16_t * send_ptr = message->send_buf;
  322. rt_uint16_t * recv_ptr = message->recv_buf;
  323. while (length--)
  324. {
  325. rt_uint16_t data = ~0;
  326. if(send_ptr != RT_NULL)
  327. {
  328. data = *send_ptr++;
  329. }
  330. /* send data once */
  331. while (__HAL_SPI_GET_FLAG(spi_handle, SPI_FLAG_TXE) == RESET);
  332. *(volatile rt_uint16_t *)(&spi_handle->Instance->DR) = data;
  333. /* receive data once */
  334. #if defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7)
  335. SET_BIT(spi_handle->Instance->CR2, SPI_RXFIFO_THRESHOLD_HF);
  336. #endif
  337. while (__HAL_SPI_GET_FLAG(spi_handle, SPI_FLAG_RXNE) == RESET);
  338. data = *(volatile rt_uint16_t *)(&spi_handle->Instance->DR);
  339. if(recv_ptr != RT_NULL)
  340. {
  341. *recv_ptr++ = data;
  342. }
  343. }
  344. }
  345. }
  346. /* Wait until Busy flag is reset before disabling SPI */
  347. while (__HAL_SPI_GET_FLAG(spi_handle, SPI_FLAG_BSY) == SET);
  348. if (message->cs_release)
  349. {
  350. HAL_GPIO_WritePin(cs->GPIOx, cs->GPIO_Pin, GPIO_PIN_SET);
  351. }
  352. return message->length;
  353. }
  354. static rt_err_t spi_configure(struct rt_spi_device *device,
  355. struct rt_spi_configuration *configuration)
  356. {
  357. RT_ASSERT(device != RT_NULL);
  358. RT_ASSERT(configuration != RT_NULL);
  359. struct stm32_spi *spi_drv = rt_container_of(device->bus, struct stm32_spi, spi_bus);
  360. spi_drv->cfg = configuration;
  361. return stm32_spi_init(spi_drv, configuration);
  362. }
  363. static const struct rt_spi_ops stm_spi_ops =
  364. {
  365. .configure = spi_configure,
  366. .xfer = spixfer,
  367. };
  368. static int rt_hw_spi_bus_init(void)
  369. {
  370. rt_err_t result;
  371. for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
  372. {
  373. spi_bus_obj[i].config = &spi_config[i];
  374. spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i];
  375. spi_bus_obj[i].handle.Instance = spi_config[i].Instance;
  376. #ifdef BSP_SPI_USING_DMA
  377. /* Configure the DMA handler for Transmission process */
  378. spi_bus_obj[i].dma.handle_tx.Instance = spi_config[i].dma_tx.Instance;
  379. #if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
  380. spi_bus_obj[i].dma.handle_tx.Init.Channel = spi_config[i].dma_tx.channel;
  381. #elif defined(SOC_SERIES_STM32L4)
  382. spi_bus_obj[i].dma.handle_tx.Init.Request = spi_config[i].dma_tx.request;
  383. #endif
  384. spi_bus_obj[i].dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  385. spi_bus_obj[i].dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  386. spi_bus_obj[i].dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  387. spi_bus_obj[i].dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  388. spi_bus_obj[i].dma.handle_tx.Init.Mode = DMA_NORMAL;
  389. spi_bus_obj[i].dma.handle_tx.Init.Priority = DMA_PRIORITY_LOW;
  390. #if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
  391. spi_bus_obj[i].dma.handle_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  392. spi_bus_obj[i].dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  393. spi_bus_obj[i].dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4;
  394. spi_bus_obj[i].dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4;
  395. #endif
  396. spi_bus_obj[i].dma.handle_rx.Instance = spi_config[i].dma_rx.Instance;
  397. #if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
  398. spi_bus_obj[i].dma.handle_rx.Init.Channel = spi_config[i].dma_rx.channel;
  399. #elif defined(SOC_SERIES_STM32L4)
  400. spi_bus_obj[i].dma.handle_rx.Init.Request = spi_config[i].dma_rx.request;
  401. #endif
  402. spi_bus_obj[i].dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  403. spi_bus_obj[i].dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  404. spi_bus_obj[i].dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  405. spi_bus_obj[i].dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  406. spi_bus_obj[i].dma.handle_rx.Init.Mode = DMA_NORMAL;
  407. spi_bus_obj[i].dma.handle_rx.Init.Priority = DMA_PRIORITY_HIGH;
  408. #if defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7)
  409. spi_bus_obj[i].dma.handle_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  410. spi_bus_obj[i].dma.handle_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  411. spi_bus_obj[i].dma.handle_rx.Init.MemBurst = DMA_MBURST_INC4;
  412. spi_bus_obj[i].dma.handle_rx.Init.PeriphBurst = DMA_PBURST_INC4;
  413. #endif
  414. {
  415. rt_uint32_t tmpreg = 0x00U;
  416. #if defined(SOC_SERIES_STM32F1)
  417. /* enable DMA clock && Delay after an RCC peripheral clock enabling*/
  418. SET_BIT(RCC->AHBENR, spi_config[i].dma_rx.dma_rcc);
  419. tmpreg = READ_BIT(RCC->AHBENR, spi_config[i].dma_rx.dma_rcc);
  420. #elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32L4)
  421. SET_BIT(RCC->AHB1ENR, spi_config[i].dma_rx.dma_rcc);
  422. /* Delay after an RCC peripheral clock enabling */
  423. tmpreg = READ_BIT(RCC->AHB1ENR, spi_config[i].dma_rx.dma_rcc);
  424. #endif
  425. UNUSED(tmpreg); /* To avoid compiler warnings */
  426. }
  427. LOG_D("%s DMA clock init done", spi_config[i].bus_name);
  428. #endif /* BSP_SPI_USING_DMA */
  429. result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &stm_spi_ops);
  430. RT_ASSERT(result == RT_EOK);
  431. LOG_D("%s bus init done", spi_config[i].bus_name);
  432. }
  433. return result;
  434. }
  435. /**
  436. * Attach the spi device to SPI bus, this function must be used after initialization.
  437. */
  438. rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_TypeDef* cs_gpiox, uint16_t cs_gpio_pin)
  439. {
  440. RT_ASSERT(bus_name != RT_NULL);
  441. RT_ASSERT(device_name != RT_NULL);
  442. rt_err_t result;
  443. struct rt_spi_device *spi_device;
  444. struct stm32_hw_spi_cs *cs_pin;
  445. /* initialize the cs pin && select the slave*/
  446. GPIO_InitTypeDef GPIO_Initure;
  447. GPIO_Initure.Pin = cs_gpio_pin;
  448. GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
  449. GPIO_Initure.Pull = GPIO_PULLUP;
  450. GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
  451. HAL_GPIO_Init(cs_gpiox, &GPIO_Initure);
  452. HAL_GPIO_WritePin(cs_gpiox, cs_gpio_pin, GPIO_PIN_SET);
  453. /* attach the device to spi bus*/
  454. spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
  455. RT_ASSERT(spi_device != RT_NULL);
  456. cs_pin = (struct stm32_hw_spi_cs *)rt_malloc(sizeof(struct stm32_hw_spi_cs));
  457. RT_ASSERT(cs_pin != RT_NULL);
  458. cs_pin->GPIOx = cs_gpiox;
  459. cs_pin->GPIO_Pin = cs_gpio_pin;
  460. result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
  461. if (result != RT_EOK)
  462. {
  463. LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
  464. }
  465. RT_ASSERT(result == RT_EOK);
  466. LOG_D("%s attach to %s done", device_name, bus_name);
  467. return result;
  468. }
  469. #if defined(BSP_USING_SPI1) && defined(BSP_SPI_USING_DMA)
  470. /**
  471. * @brief This function handles DMA Rx interrupt request.
  472. * @param None
  473. * @retval None
  474. */
  475. void SPI1_DMA_RX_IRQHandler(void)
  476. {
  477. /* enter interrupt */
  478. rt_interrupt_enter();
  479. HAL_DMA_IRQHandler(&spi_bus_obj[SPI1_INDEX].dma.handle_rx);
  480. /* leave interrupt */
  481. rt_interrupt_leave();
  482. }
  483. /**
  484. * @brief This function handles DMA Tx interrupt request.
  485. * @param None
  486. * @retval None
  487. */
  488. void SPI1_DMA_TX_IRQHandler(void)
  489. {
  490. /* enter interrupt */
  491. rt_interrupt_enter();
  492. HAL_DMA_IRQHandler(&spi_bus_obj[SPI1_INDEX].dma.handle_tx);
  493. /* leave interrupt */
  494. rt_interrupt_leave();
  495. }
  496. #endif /* defined(BSP_USING_SPI1) && defined(BSP_SPI_USING_DMA) */
  497. #if defined(BSP_USING_SPI2) && defined(BSP_SPI_USING_DMA)
  498. /**
  499. * @brief This function handles DMA Rx interrupt request.
  500. * @param None
  501. * @retval None
  502. */
  503. void SPI2_DMA_RX_IRQHandler(void)
  504. {
  505. /* enter interrupt */
  506. rt_interrupt_enter();
  507. HAL_DMA_IRQHandler(&spi_bus_obj[SPI2_INDEX].dma.handle_rx);
  508. /* leave interrupt */
  509. rt_interrupt_leave();
  510. }
  511. /**
  512. * @brief This function handles DMA Tx interrupt request.
  513. * @param None
  514. * @retval None
  515. */
  516. void SPI2_DMA_TX_IRQHandler(void)
  517. {
  518. /* enter interrupt */
  519. rt_interrupt_enter();
  520. HAL_DMA_IRQHandler(&spi_bus_obj[SPI2_INDEX].dma.handle_tx);
  521. /* leave interrupt */
  522. rt_interrupt_leave();
  523. }
  524. #endif /* defined(BSP_USING_SPI2) && defined(BSP_SPI_USING_DMA) */
  525. #if defined(BSP_USING_SPI3) && defined(BSP_SPI_USING_DMA)
  526. /**
  527. * @brief This function handles DMA Rx interrupt request.
  528. * @param None
  529. * @retval None
  530. */
  531. void SPI3_DMA_RX_IRQHandler(void)
  532. {
  533. /* enter interrupt */
  534. rt_interrupt_enter();
  535. HAL_DMA_IRQHandler(&spi_bus_obj[SPI3_INDEX].dma.handle_rx);
  536. /* leave interrupt */
  537. rt_interrupt_leave();
  538. }
  539. /**
  540. * @brief This function handles DMA Tx interrupt request.
  541. * @param None
  542. * @retval None
  543. */
  544. void SPI3_DMA_TX_IRQHandler(void)
  545. {
  546. /* enter interrupt */
  547. rt_interrupt_enter();
  548. HAL_DMA_IRQHandler(&spi_bus_obj[SPI3_INDEX].dma.handle_tx);
  549. /* leave interrupt */
  550. rt_interrupt_leave();
  551. }
  552. #endif /* defined(BSP_USING_SPI3) && defined(BSP_SPI_USING_DMA) */
  553. #if defined(BSP_USING_SPI4) && defined(BSP_SPI_USING_DMA)
  554. /**
  555. * @brief This function handles DMA Rx interrupt request.
  556. * @param None
  557. * @retval None
  558. */
  559. void SPI4_DMA_RX_IRQHandler(void)
  560. {
  561. /* enter interrupt */
  562. rt_interrupt_enter();
  563. HAL_DMA_IRQHandler(&spi_bus_obj[SPI4_INDEX].dma.handle_rx);
  564. /* leave interrupt */
  565. rt_interrupt_leave();
  566. }
  567. /**
  568. * @brief This function handles DMA Tx interrupt request.
  569. * @param None
  570. * @retval None
  571. */
  572. void SPI4_DMA_TX_IRQHandler(void)
  573. {
  574. /* enter interrupt */
  575. rt_interrupt_enter();
  576. HAL_DMA_IRQHandler(&spi_bus_obj[SPI4_INDEX].dma.handle_tx);
  577. /* leave interrupt */
  578. rt_interrupt_leave();
  579. }
  580. #endif /* defined(BSP_USING_SPI4) && defined(BSP_SPI_USING_DMA) */
  581. #if defined(BSP_USING_SPI5) && defined(BSP_SPI_USING_DMA)
  582. /**
  583. * @brief This function handles DMA Rx interrupt request.
  584. * @param None
  585. * @retval None
  586. */
  587. void SPI5_DMA_RX_IRQHandler(void)
  588. {
  589. /* enter interrupt */
  590. rt_interrupt_enter();
  591. HAL_DMA_IRQHandler(&spi_bus_obj[SPI5_INDEX].dma.handle_rx);
  592. /* leave interrupt */
  593. rt_interrupt_leave();
  594. }
  595. /**
  596. * @brief This function handles DMA Tx interrupt request.
  597. * @param None
  598. * @retval None
  599. */
  600. void SPI5_DMA_TX_IRQHandler(void)
  601. {
  602. /* enter interrupt */
  603. rt_interrupt_enter();
  604. HAL_DMA_IRQHandler(&spi_bus_obj[SPI5_INDEX].dma.handle_tx);
  605. /* leave interrupt */
  606. rt_interrupt_leave();
  607. }
  608. #endif /* defined(BSP_USING_SPI5) && defined(BSP_SPI_USING_DMA) */
  609. #if defined(BSP_USING_SPI6) && defined(BSP_SPI_USING_DMA)
  610. /**
  611. * @brief This function handles DMA Rx interrupt request.
  612. * @param None
  613. * @retval None
  614. */
  615. void SPI6_DMA_RX_IRQHandler(void)
  616. {
  617. /* enter interrupt */
  618. rt_interrupt_enter();
  619. HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].dma.handle_rx);
  620. /* leave interrupt */
  621. rt_interrupt_leave();
  622. }
  623. /**
  624. * @brief This function handles DMA Tx interrupt request.
  625. * @param None
  626. * @retval None
  627. */
  628. void SPI6_DMA_TX_IRQHandler(void)
  629. {
  630. /* enter interrupt */
  631. rt_interrupt_enter();
  632. HAL_DMA_IRQHandler(&spi_bus_obj[SPI6_INDEX].dma.handle_tx);
  633. /* leave interrupt */
  634. rt_interrupt_leave();
  635. }
  636. #endif /* defined(BSP_USING_SPI6) && defined(BSP_SPI_USING_DMA) */
  637. int rt_hw_spi_init(void)
  638. {
  639. return rt_hw_spi_bus_init();
  640. }
  641. INIT_BOARD_EXPORT(rt_hw_spi_init);
  642. #endif /* BSP_USING_SPI1 || BSP_USING_SPI2 || BSP_USING_SPI3 || BSP_USING_SPI4 || BSP_USING_SPI5 */
  643. #endif /* RT_USING_SPI */