drv_spi.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. /*
  2. * File : drv_spi.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2017 RT-Thread Develop Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2017-06-05 tanek first implementation.
  13. */
  14. #include "drv_spi.h"
  15. #include <board.h>
  16. #include <finsh.h>
  17. //#define DEBUG
  18. #ifdef DEBUG
  19. #define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__)
  20. #else
  21. #define DEBUG_PRINTF(...)
  22. #endif
  23. /* private rt-thread spi ops function */
  24. static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration);
  25. static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message);
  26. static struct rt_spi_ops stm32_spi_ops =
  27. {
  28. configure,
  29. xfer
  30. };
  31. #ifdef SPI_USE_DMA
  32. static uint8_t dummy = 0xFF;
  33. static void DMA_RxConfiguration(struct rt_spi_bus * spi_bus,
  34. struct rt_spi_message* message)
  35. {
  36. struct stm32f4_spi *f4_spi = (struct stm32f4_spi *)spi_bus->parent.user_data;
  37. DMA_HandleTypeDef * hdma_tx = &f4_spi->hdma_tx;
  38. DMA_HandleTypeDef * hdma_rx = &f4_spi->hdma_rx;
  39. HAL_DMA_DeInit(hdma_tx);
  40. HAL_DMA_DeInit(hdma_rx);
  41. /* Check if the DMA Stream is disabled before enabling it.
  42. Note that this step is useful when the same Stream is used multiple times:
  43. enabled, then disabled then re-enabled... In this case, the DMA Stream disable
  44. will be effective only at the end of the ongoing data transfer and it will
  45. not be possible to re-configure it before making sure that the Enable bit
  46. has been cleared by hardware. If the Stream is used only once, this step might
  47. be bypassed. */
  48. while (hdma_tx->Instance->CR & DMA_SxCR_EN);
  49. while (hdma_rx->Instance->CR & DMA_SxCR_EN);
  50. if(message->recv_buf != RT_NULL)
  51. {
  52. hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
  53. }
  54. else
  55. {
  56. message->recv_buf = &dummy;
  57. hdma_rx->Init.MemInc = DMA_MINC_DISABLE;
  58. }
  59. HAL_DMA_Init(hdma_rx);
  60. __HAL_LINKDMA(&f4_spi->spi_handle, hdmarx, f4_spi->hdma_rx);
  61. if(message->send_buf != RT_NULL)
  62. {
  63. hdma_tx->Init.MemInc = DMA_MINC_ENABLE;
  64. }
  65. else
  66. {
  67. dummy = 0xFF;
  68. message->send_buf = &dummy;
  69. hdma_tx->Init.MemInc = DMA_MINC_DISABLE;
  70. }
  71. HAL_DMA_Init(hdma_tx);
  72. __HAL_LINKDMA(&f4_spi->spi_handle, hdmatx, f4_spi->hdma_tx);
  73. /* NVIC configuration for DMA transfer complete interrupt*/
  74. HAL_NVIC_SetPriority(f4_spi->hdma_tx_irq, 0, 1);
  75. HAL_NVIC_EnableIRQ(f4_spi->hdma_tx_irq);
  76. /* NVIC configuration for DMA transfer complete interrupt*/
  77. HAL_NVIC_SetPriority(f4_spi->hdma_rx_irq, 0, 0);
  78. HAL_NVIC_EnableIRQ(f4_spi->hdma_rx_irq);
  79. }
  80. #endif
  81. static rt_err_t configure(struct rt_spi_device* device,
  82. struct rt_spi_configuration* configuration)
  83. {
  84. struct rt_spi_bus * spi_bus = (struct rt_spi_bus *)device->bus;
  85. struct stm32f4_spi *f4_spi = (struct stm32f4_spi *)spi_bus->parent.user_data;
  86. SPI_HandleTypeDef * SpiHandle = &f4_spi->spi_handle;
  87. RT_ASSERT(device != RT_NULL);
  88. RT_ASSERT(configuration != RT_NULL);
  89. /* data_width */
  90. if(configuration->data_width <= 8)
  91. {
  92. SpiHandle->Init.DataSize = SPI_DATASIZE_8BIT;
  93. }
  94. else if(configuration->data_width <= 16)
  95. {
  96. SpiHandle->Init.DataSize = SPI_DATASIZE_16BIT;
  97. }
  98. else
  99. {
  100. return RT_EIO;
  101. }
  102. /* baudrate */
  103. {
  104. uint32_t SPI_APB_CLOCK;
  105. uint32_t max_hz;
  106. max_hz = configuration->max_hz;
  107. DEBUG_PRINTF("sys freq: %d\n", HAL_RCC_GetSysClockFreq());
  108. DEBUG_PRINTF("pclk2 freq: %d\n", HAL_RCC_GetPCLK2Freq());
  109. SPI_APB_CLOCK = HAL_RCC_GetPCLK2Freq();
  110. if(max_hz >= SPI_APB_CLOCK/2)
  111. {
  112. SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  113. }
  114. else if(max_hz >= SPI_APB_CLOCK/4)
  115. {
  116. SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  117. }
  118. else if(max_hz >= SPI_APB_CLOCK/8)
  119. {
  120. SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  121. }
  122. else if(max_hz >= SPI_APB_CLOCK/16)
  123. {
  124. SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
  125. }
  126. else if(max_hz >= SPI_APB_CLOCK/32)
  127. {
  128. SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  129. }
  130. else if(max_hz >= SPI_APB_CLOCK/64)
  131. {
  132. SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  133. }
  134. else if(max_hz >= SPI_APB_CLOCK/128)
  135. {
  136. SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
  137. }
  138. else
  139. {
  140. /* min prescaler 256 */
  141. SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
  142. }
  143. } /* baudrate */
  144. /* CPOL */
  145. if(configuration->mode & RT_SPI_CPOL)
  146. {
  147. SpiHandle->Init.CLKPolarity = SPI_POLARITY_HIGH;
  148. }
  149. else
  150. {
  151. SpiHandle->Init.CLKPolarity = SPI_POLARITY_LOW;
  152. }
  153. /* CPHA */
  154. if(configuration->mode & RT_SPI_CPHA)
  155. {
  156. SpiHandle->Init.CLKPhase = SPI_PHASE_2EDGE;
  157. }
  158. else
  159. {
  160. SpiHandle->Init.CLKPhase = SPI_PHASE_1EDGE;
  161. }
  162. /* MSB or LSB */
  163. if(configuration->mode & RT_SPI_MSB)
  164. {
  165. SpiHandle->Init.FirstBit = SPI_FIRSTBIT_MSB;
  166. }
  167. else
  168. {
  169. SpiHandle->Init.FirstBit = SPI_FIRSTBIT_LSB;
  170. }
  171. SpiHandle->Init.Direction = SPI_DIRECTION_2LINES;
  172. SpiHandle->Init.Mode = SPI_MODE_MASTER;
  173. SpiHandle->Init.NSS = SPI_NSS_SOFT;
  174. SpiHandle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  175. SpiHandle->Init.TIMode = SPI_TIMODE_DISABLE;
  176. /* init SPI */
  177. if (HAL_SPI_Init(SpiHandle) != HAL_OK)
  178. {
  179. return RT_ERROR;
  180. }
  181. /* Enable SPI_MASTER */
  182. __HAL_SPI_ENABLE(SpiHandle);
  183. DEBUG_PRINTF("spi configuration\n");
  184. return RT_EOK;
  185. };
  186. static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message)
  187. {
  188. struct rt_spi_bus * stm32_spi_bus = (struct rt_spi_bus *)device->bus;
  189. struct stm32f4_spi *f4_spi = (struct stm32f4_spi *)stm32_spi_bus->parent.user_data;
  190. struct rt_spi_configuration * config = &device->config;
  191. SPI_TypeDef * SPI = f4_spi->spi_handle.Instance;
  192. struct stm32_spi_cs * stm32_spi_cs = device->parent.user_data;
  193. rt_uint32_t size = message->length;
  194. RT_ASSERT(device != NULL);
  195. RT_ASSERT(message != NULL);
  196. /* take CS */
  197. if(message->cs_take)
  198. {
  199. HAL_GPIO_WritePin(stm32_spi_cs->GPIOx, stm32_spi_cs->GPIO_Pin, GPIO_PIN_RESET);
  200. }
  201. #ifdef SPI_USE_DMA
  202. if(message->length > 32)
  203. {
  204. if(config->data_width <= 8)
  205. {
  206. HAL_StatusTypeDef state;
  207. DEBUG_PRINTF("spi dma transfer start\n");
  208. DMA_RxConfiguration(stm32_spi_bus, message);
  209. DEBUG_PRINTF("dma configuration finish , send buf %X, rec buf %X, length: %d\n",
  210. (uint32_t)message->send_buf, (uint32_t)message->recv_buf, message->length);
  211. state = HAL_SPI_TransmitReceive_DMA(&f4_spi->spi_handle,
  212. (uint8_t*)message->send_buf,
  213. (uint8_t*)message->recv_buf,
  214. message->length);
  215. if (state != HAL_OK)
  216. {
  217. DEBUG_PRINTF("spi flash configuration error : %d\n", state);
  218. message->length = 0;
  219. //while(1);
  220. }
  221. else
  222. {
  223. DEBUG_PRINTF("spi dma transfer finish\n");
  224. }
  225. while (HAL_SPI_GetState(&f4_spi->spi_handle) != HAL_SPI_STATE_READY);
  226. DEBUG_PRINTF("spi get state finish\n");
  227. }
  228. else
  229. {
  230. // Todo
  231. }
  232. }
  233. else
  234. #endif
  235. {
  236. if(config->data_width <= 8)
  237. {
  238. const rt_uint8_t * send_ptr = message->send_buf;
  239. rt_uint8_t * recv_ptr = message->recv_buf;
  240. while(size--)
  241. {
  242. rt_uint8_t data = 0xFF;
  243. if(send_ptr != RT_NULL)
  244. {
  245. data = *send_ptr++;
  246. }
  247. // Todo: replace register read/write by stm32f4 lib
  248. //Wait until the transmit buffer is empty
  249. while ((SPI->SR & SPI_FLAG_TXE) == RESET);
  250. // Send the byte
  251. SPI->DR = data;
  252. //Wait until a data is received
  253. while ((SPI->SR & SPI_FLAG_RXNE) == RESET);
  254. // Get the received data
  255. data = SPI->DR;
  256. if(recv_ptr != RT_NULL)
  257. {
  258. *recv_ptr++ = data;
  259. }
  260. }
  261. }
  262. else if(config->data_width <= 16)
  263. {
  264. const rt_uint16_t * send_ptr = message->send_buf;
  265. rt_uint16_t * recv_ptr = message->recv_buf;
  266. while(size--)
  267. {
  268. rt_uint16_t data = 0xFF;
  269. if(send_ptr != RT_NULL)
  270. {
  271. data = *send_ptr++;
  272. }
  273. //Wait until the transmit buffer is empty
  274. while ((SPI->SR & SPI_FLAG_TXE) == RESET);
  275. // Send the byte
  276. SPI->DR = data;
  277. //Wait until a data is received
  278. while ((SPI->SR & SPI_FLAG_RXNE) == RESET);
  279. // Get the received data
  280. data = SPI->DR;
  281. if(recv_ptr != RT_NULL)
  282. {
  283. *recv_ptr++ = data;
  284. }
  285. }
  286. }
  287. }
  288. /* release CS */
  289. if(message->cs_release)
  290. {
  291. //GPIO_SetBits(stm32_spi_cs->GPIOx, stm32_spi_cs->GPIO_Pin);
  292. HAL_GPIO_WritePin(stm32_spi_cs->GPIOx, stm32_spi_cs->GPIO_Pin, GPIO_PIN_SET);
  293. }
  294. return message->length;
  295. };
  296. #ifdef RT_USING_SPI1
  297. static struct stm32f4_spi stm32f4_spi1 =
  298. {
  299. /* .spi_handle = */{
  300. /* .Instance = */ SPI1,
  301. },
  302. /* .hdma_rx = */ {
  303. DMA2_Stream2,
  304. DMA_CHANNEL_3,
  305. },
  306. /* .hdma_rx_irq = */ DMA2_Stream2_IRQn,
  307. /* .hdma_tx = */{
  308. DMA2_Stream3,
  309. DMA_CHANNEL_3,
  310. },
  311. /* .hdma_tx_irq = */ DMA2_Stream3_IRQn,
  312. };
  313. static struct rt_spi_bus spi1_bus;
  314. /**
  315. * @brief This function handles DMA Rx interrupt request.
  316. * @param None
  317. * @retval None
  318. */
  319. void DMA2_Stream2_IRQHandler(void)
  320. {
  321. HAL_DMA_IRQHandler(stm32f4_spi1.spi_handle.hdmarx);
  322. }
  323. /**
  324. * @brief This function handles DMA Tx interrupt request.
  325. * @param None
  326. * @retval None
  327. */
  328. void DMA2_Stream3_IRQHandler(void)
  329. {
  330. HAL_DMA_IRQHandler(stm32f4_spi1.spi_handle.hdmatx);
  331. }
  332. #endif
  333. #ifdef RT_USING_SPI2
  334. struct stm32f4_spi stm32f4_spi2 =
  335. {
  336. /* .spi_handle = */{
  337. /* .Instance = */ SPI2,
  338. },
  339. /* .hdma_rx = */ {
  340. DMA1_Stream3,
  341. DMA_CHANNEL_0,
  342. },
  343. /* .hdma_rx_irq = */ DMA1_Stream3_IRQn,
  344. /* .hdma_tx = */{
  345. DMA1_Stream4,
  346. DMA_CHANNEL_0,
  347. },
  348. /* .hdma_tx_irq = */ DMA1_Stream4_IRQn,
  349. };
  350. static struct rt_spi_bus spi2_bus;
  351. /**
  352. * @brief This function handles DMA Rx interrupt request.
  353. * @param None
  354. * @retval None
  355. */
  356. void DMA1_Stream3_IRQHandler(void)
  357. {
  358. HAL_DMA_IRQHandler(stm32f4_spi2.spi_handle.hdmarx);
  359. }
  360. /**
  361. * @brief This function handles DMA Tx interrupt request.
  362. * @param None
  363. * @retval None
  364. */
  365. void DMA1_Stream4_IRQHandler(void)
  366. {
  367. HAL_DMA_IRQHandler(stm32f4_spi2.spi_handle.hdmatx);
  368. }
  369. #endif
  370. #ifdef RT_USING_SPI3
  371. struct stm32f4_spi stm32f4_spi3 =
  372. {
  373. /* .spi_handle = */{
  374. /* .Instance = */ SPI3,
  375. },
  376. /* .hdma_rx = */ {
  377. DMA1_Stream0,
  378. DMA_CHANNEL_0,
  379. },
  380. /* .hdma_rx_irq = */ DMA1_Stream0_IRQn,
  381. /* .hdma_tx = */{
  382. DMA1_Stream2,
  383. DMA_CHANNEL_0,
  384. },
  385. /* .hdma_tx_irq = */ DMA1_Stream2_IRQn,
  386. };
  387. static struct rt_spi_bus spi3_bus;
  388. /**
  389. * @brief This function handles DMA Rx interrupt request.
  390. * @param None
  391. * @retval None
  392. */
  393. void DMA1_Stream0_IRQHandler(void)
  394. {
  395. HAL_DMA_IRQHandler(stm32f4_spi3.spi_handle.hdmarx);
  396. }
  397. /**
  398. * @brief This function handles DMA Tx interrupt request.
  399. * @param None
  400. * @retval None
  401. */
  402. void DMA1_Stream2_IRQHandler(void)
  403. {
  404. HAL_DMA_IRQHandler(stm32f4_spi3.spi_handle.hdmatx);
  405. }
  406. #endif
  407. #ifdef RT_USING_SPI4
  408. struct stm32f4_spi stm32f4_spi4 =
  409. {
  410. /* .spi_handle = */{
  411. /* .Instance = */ SPI5,
  412. },
  413. /* .hdma_rx = */ {
  414. DMA2_Stream0,
  415. DMA_CHANNEL_4,
  416. },
  417. /* .hdma_rx_irq = */ DMA2_Stream0_IRQn,
  418. /* .hdma_tx = */{
  419. DMA2_Stream1,
  420. DMA_CHANNEL_4,
  421. },
  422. /* .hdma_tx_irq = */ DMA2_Stream1_IRQn,
  423. };
  424. static struct rt_spi_bus spi4_bus;
  425. /**
  426. * @brief This function handles DMA Rx interrupt request.
  427. * @param None
  428. * @retval None
  429. */
  430. void DMA2_Stream0_IRQHandler(void)
  431. {
  432. HAL_DMA_IRQHandler(stm32f4_spi4.spi_handle.hdmarx);
  433. }
  434. /**
  435. * @brief This function handles DMA Tx interrupt request.
  436. * @param None
  437. * @retval None
  438. */
  439. void DMA2_Stream1_IRQHandler(void)
  440. {
  441. HAL_DMA_IRQHandler(stm32f4_spi4.spi_handle.hdmatx);
  442. }
  443. #endif
  444. #ifdef RT_USING_SPI5
  445. struct stm32f4_spi stm32f4_spi5 =
  446. {
  447. /* .spi_handle = */{
  448. /* .Instance = */ SPI5,
  449. },
  450. /* .hdma_rx = */ {
  451. DMA2_Stream3,
  452. DMA_CHANNEL_2,
  453. },
  454. /* .hdma_rx_irq = */ DMA2_Stream3_IRQn,
  455. /* .hdma_tx = */{
  456. DMA2_Stream4,
  457. DMA_CHANNEL_2,
  458. },
  459. /* .hdma_tx_irq = */ DMA2_Stream4_IRQn,
  460. };
  461. static struct rt_spi_bus spi5_bus;
  462. /**
  463. * @brief This function handles DMA Rx interrupt request.
  464. * @param None
  465. * @retval None
  466. */
  467. void DMA2_Stream3_IRQHandler(void)
  468. {
  469. HAL_DMA_IRQHandler(stm32f4_spi5.spi_handle.hdmarx);
  470. }
  471. /**
  472. * @brief This function handles DMA Tx interrupt request.
  473. * @param None
  474. * @retval None
  475. */
  476. void DMA2_Stream4_IRQHandler(void)
  477. {
  478. HAL_DMA_IRQHandler(stm32f4_spi5.spi_handle.hdmatx);
  479. }
  480. #endif
  481. #ifdef RT_USING_SPI6
  482. struct stm32f4_spi stm32f4_spi6 =
  483. {
  484. /* .spi_handle = */{
  485. /* .Instance = */ SPI5,
  486. },
  487. /* .hdma_rx = */ {
  488. DMA2_Stream6,
  489. DMA_CHANNEL_2,
  490. },
  491. /* .hdma_rx_irq = */ DMA2_Stream6_IRQn,
  492. /* .hdma_tx = */{
  493. DMA2_Stream5,
  494. DMA_CHANNEL_2,
  495. },
  496. /* .hdma_tx_irq = */ DMA2_Stream5_IRQn,
  497. };
  498. static struct rt_spi_bus spi6_bus;
  499. /**
  500. * @brief This function handles DMA Rx interrupt request.
  501. * @param None
  502. * @retval None
  503. */
  504. void DMA2_Stream6_IRQHandler(void)
  505. {
  506. HAL_DMA_IRQHandler(stm32f4_spi6.spi_handle.hdmarx);
  507. }
  508. /**
  509. * @brief This function handles DMA Tx interrupt request.
  510. * @param None
  511. * @retval None
  512. */
  513. void DMA2_Stream5_IRQHandler(void)
  514. {
  515. HAL_DMA_IRQHandler(stm32f4_spi6.spi_handle.hdmatx);
  516. }
  517. #endif
  518. /** \brief init and register stm32 spi bus.
  519. *
  520. * \param SPI: STM32 SPI, e.g: SPI1,SPI2,SPI3.
  521. * \param spi_bus_name: spi bus name, e.g: "spi1"
  522. * \return
  523. *
  524. */
  525. rt_err_t stm32_spi_bus_register(SPI_TypeDef * SPI,
  526. //struct stm32_spi_bus * stm32_spi,
  527. const char * spi_bus_name)
  528. {
  529. struct stm32f4_spi * p_spi_bus;
  530. struct rt_spi_bus * spi_bus;
  531. RT_ASSERT(SPI != RT_NULL);
  532. //RT_ASSERT(stm32_spi != RT_NULL);
  533. RT_ASSERT(spi_bus_name != RT_NULL);
  534. #ifdef RT_USING_SPI1
  535. if(SPI == SPI1)
  536. {
  537. #ifdef SPI_USE_DMA
  538. __HAL_RCC_DMA2_CLK_ENABLE();
  539. p_spi_bus = &stm32f4_spi1;
  540. #endif
  541. __HAL_RCC_SPI1_CLK_ENABLE();
  542. spi_bus = &spi1_bus;
  543. }
  544. #endif
  545. #ifdef RT_USING_SPI2
  546. if(SPI == SPI2)
  547. {
  548. #ifdef SPI_USE_DMA
  549. __HAL_RCC_DMA1_CLK_ENABLE();
  550. p_spi_bus = &stm32f4_spi2;
  551. #endif
  552. __HAL_RCC_SPI2_CLK_ENABLE();
  553. spi_bus = &spi2_bus;
  554. }
  555. #endif
  556. #ifdef RT_USING_SPI3
  557. if(SPI == SPI3)
  558. {
  559. //stm32_spi->spi_handle.Instance = SPI3;
  560. #ifdef SPI_USE_DMA
  561. __HAL_RCC_DMA1_CLK_ENABLE();
  562. p_spi_bus = &stm32f4_spi3;
  563. #endif
  564. __HAL_RCC_SPI3_CLK_ENABLE();
  565. spi_bus = &spi3_bus;
  566. }
  567. #endif
  568. #ifdef RT_USING_SPI4
  569. if(SPI == SPI4)
  570. {
  571. #ifdef SPI_USE_DMA
  572. __HAL_RCC_DMA2_CLK_ENABLE();
  573. #endif
  574. __HAL_RCC_SPI4_CLK_ENABLE();
  575. spi_bus = &spi4_bus;
  576. }
  577. #endif
  578. #ifdef RT_USING_SPI5
  579. if(SPI == SPI5)
  580. {
  581. #ifdef SPI_USE_DMA
  582. __HAL_RCC_DMA2_CLK_ENABLE();
  583. p_spi_bus = &stm32f4_spi5;
  584. #endif
  585. __HAL_RCC_SPI5_CLK_ENABLE();
  586. spi_bus = &spi5_bus;
  587. }
  588. #endif
  589. #ifdef RT_USING_SPI6
  590. if(SPI == SPI6)
  591. {
  592. #ifdef SPI_USE_DMA
  593. __HAL_RCC_DMA2_CLK_ENABLE();
  594. p_spi_bus = &stm32f4_spi5;
  595. #endif
  596. __HAL_RCC_SPI6_CLK_ENABLE();
  597. spi_bus = &spi6_bus;
  598. }
  599. #endif
  600. if ( (SPI != SPI1) && (SPI != SPI2) && (SPI != SPI3)
  601. && (SPI != SPI4) && (SPI != SPI5) && (SPI != SPI6))
  602. {
  603. return RT_ENOSYS;
  604. }
  605. /* Configure the DMA handler for Transmission process */
  606. p_spi_bus->hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  607. p_spi_bus->hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  608. //p_spi_bus->hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
  609. p_spi_bus->hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  610. p_spi_bus->hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  611. p_spi_bus->hdma_tx.Init.Mode = DMA_NORMAL;
  612. p_spi_bus->hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
  613. p_spi_bus->hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  614. p_spi_bus->hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  615. p_spi_bus->hdma_tx.Init.MemBurst = DMA_MBURST_INC4;
  616. p_spi_bus->hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4;
  617. p_spi_bus->hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  618. p_spi_bus->hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  619. //p_spi_bus->hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
  620. p_spi_bus->hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  621. p_spi_bus->hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  622. p_spi_bus->hdma_rx.Init.Mode = DMA_NORMAL;
  623. p_spi_bus->hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
  624. p_spi_bus->hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  625. p_spi_bus->hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  626. p_spi_bus->hdma_rx.Init.MemBurst = DMA_MBURST_INC4;
  627. p_spi_bus->hdma_rx.Init.PeriphBurst = DMA_PBURST_INC4;
  628. spi_bus->parent.user_data = &stm32f4_spi5;
  629. return rt_spi_bus_register(spi_bus, spi_bus_name, &stm32_spi_ops);
  630. }