HAL_SPI.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  1. /*
  2. ******************************************************************************
  3. * @file HAL_Spi.c
  4. * @version V1.0.0
  5. * @date 2020
  6. * @brief SPI HAL module driver.
  7. * This file provides firmware functions to manage the following
  8. * functionalities of the Serial Peripheral Interface (SPI) peripheral.
  9. * @ Initialization and de-initialization functions
  10. * @ IO operation functions
  11. * @ Peripheral Control functions
  12. ******************************************************************************
  13. */
  14. #include "ACM32Fxx_HAL.h"
  15. #define SPI_RX_TIMEOUT 2000
  16. #define SPI_TX_DMA_TIMEOUT 2000
  17. volatile uint32_t lu32_ReceiveTimeOut = SPI_RX_TIMEOUT;
  18. volatile uint32_t lu32_TX_DMA_TimeOut = SPI_TX_DMA_TIMEOUT;
  19. /************************************************************************
  20. * function : HAL_SPI_IRQHandler
  21. * Description: This function handles SPI interrupt request.
  22. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  23. * the configuration information for SPI module
  24. ************************************************************************/
  25. __weak void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
  26. {
  27. /*
  28. NOTE : This function should be modified by the user.
  29. */
  30. if ( (hspi->Instance->STATUS & SPI_STATUS_RX_NOT_EMPTY) && ((hspi->Instance->IE) & SPI_STATUS_RX_NOT_EMPTY) )
  31. {
  32. /* In master mode */
  33. if (hspi->Instance->CTL & SPI_CTL_MST_MODE)
  34. {
  35. while (hspi->Instance->STATUS & SPI_STATUS_RX_NOT_EMPTY)
  36. {
  37. hspi->Rx_Buffer[hspi->Rx_Count++] = hspi->Instance->DAT;
  38. if (hspi->Rx_Count >= hspi->Rx_Size)
  39. {
  40. /* Wait Transmit Done */
  41. while (!(hspi->Instance->STATUS & SPI_STATUS_RX_BATCH_DONE));
  42. /* Clear Batch Done Flag */
  43. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_RX_BATCH_DONE);
  44. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  45. /* Rx Disable */
  46. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  47. /* Receive End */
  48. hspi->Instance->CS &= (~SPI_CS_CS0);
  49. /* Disable Rx Not Empty Interrupt */
  50. CLEAR_BIT(hspi->Instance->IE, SPI_STATUS_RX_NOT_EMPTY);
  51. if(hspi->Instance == SPI1)
  52. NVIC_ClearPendingIRQ(SPI1_IRQn);
  53. else if(hspi->Instance == SPI2)
  54. NVIC_ClearPendingIRQ(SPI2_IRQn);
  55. /* Clear Batch Done Flag */
  56. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_RX_BATCH_DONE);
  57. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  58. /* Set machine is DILE */
  59. hspi->RxState = SPI_RX_STATE_IDLE;
  60. }
  61. }
  62. }
  63. /* In Slave mode */
  64. else
  65. {
  66. while ((hspi->Rx_Count < hspi->Rx_Size) && (lu32_ReceiveTimeOut > 0) )
  67. {
  68. if (hspi->Instance->STATUS & SPI_STATUS_RX_NOT_EMPTY)
  69. {
  70. hspi->Rx_Buffer[hspi->Rx_Count++] = hspi->Instance->DAT;
  71. lu32_ReceiveTimeOut = SPI_RX_TIMEOUT; //If recieve data, Reset the timeout value
  72. }
  73. else
  74. {
  75. lu32_ReceiveTimeOut--;
  76. }
  77. }
  78. /* Rx Disable */
  79. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  80. /* Disable Rx Not Empty Interrupt */
  81. CLEAR_BIT(hspi->Instance->IE, SPI_STATUS_RX_NOT_EMPTY);
  82. if(hspi->Instance == SPI1)
  83. NVIC_ClearPendingIRQ(SPI1_IRQn);
  84. else if(hspi->Instance == SPI2)
  85. NVIC_ClearPendingIRQ(SPI2_IRQn);
  86. /* Clear Batch Done Flag */
  87. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_RX_BATCH_DONE);
  88. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  89. /* Set machine is DILE */
  90. hspi->RxState = SPI_RX_STATE_IDLE;
  91. }
  92. }
  93. if ( (hspi->Instance->STATUS & SPI_STATUS_TX_FIFO_HALF_EMPTY) && ((hspi->Instance->IE) & SPI_IE_TX_FIFO_HALF_EMPTY_EN) )
  94. {
  95. while (hspi->Tx_Count < hspi->Tx_Size)
  96. {
  97. if (!(hspi->Instance->STATUS & SPI_STATUS_TX_FIFO_FULL))
  98. {
  99. hspi->Instance->DAT = hspi->Tx_Buffer[hspi->Tx_Count++];
  100. }
  101. else
  102. {
  103. break;
  104. }
  105. }
  106. /* Clear Tx FIFO half empty Flag */
  107. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_TX_FIFO_HALF_EMPTY);
  108. if(hspi->Tx_Count == hspi->Tx_Size)
  109. {
  110. /* Disable Tx FIFO half empty Interrupt */
  111. CLEAR_BIT(hspi->Instance->IE, SPI_IE_TX_FIFO_HALF_EMPTY_EN);
  112. }
  113. }
  114. if ((hspi->Instance->STATUS & SPI_STATUS_TX_BATCH_DONE) && ((hspi->Instance->IE) & SPI_IE_TX_BATCH_DONE_EN) )
  115. {
  116. /* Clear Batch Done Flag */
  117. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_TX_BATCH_DONE);
  118. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  119. /* Disable TX Batch Done Interrupt */
  120. CLEAR_BIT(hspi->Instance->IE, SPI_STATUS_TX_BATCH_DONE);
  121. /* Disable Tx FIFO half empty Interrupt */
  122. CLEAR_BIT(hspi->Instance->IE, SPI_IE_TX_FIFO_HALF_EMPTY_EN);
  123. if(hspi->Instance == SPI1)
  124. NVIC_ClearPendingIRQ(SPI1_IRQn);
  125. else if(hspi->Instance == SPI2)
  126. NVIC_ClearPendingIRQ(SPI2_IRQn);
  127. lu32_TX_DMA_TimeOut = SPI_TX_DMA_TIMEOUT;
  128. while (hspi->Instance->STATUS & SPI_STATUS_TX_BUSY)
  129. {
  130. lu32_TX_DMA_TimeOut--;
  131. if(0 == lu32_TX_DMA_TimeOut)
  132. {
  133. break;
  134. }
  135. }
  136. /* Tx Disable */
  137. hspi->Instance->TX_CTL &= (~SPI_TX_CTL_EN);
  138. hspi->Instance->TX_CTL &= (~SPI_TX_CTL_DMA_REQ_EN);
  139. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  140. {
  141. /* Transmit End */
  142. hspi->Instance->CS &= (~SPI_CS_CS0);
  143. }
  144. /* Tx Disable */
  145. hspi->Instance->TX_CTL &= (~SPI_TX_CTL_EN);
  146. hspi->TxState = SPI_TX_STATE_IDLE;
  147. }
  148. if ( (hspi->Instance->STATUS & SPI_STATUS_RX_BATCH_DONE) && ((hspi->Instance->IE) & SPI_STATUS_RX_BATCH_DONE) )
  149. {
  150. /* Clear Batch Done Flag */
  151. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_RX_BATCH_DONE);
  152. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  153. /* Disable RX Batch Done Interrupt */
  154. CLEAR_BIT(hspi->Instance->IE, SPI_STATUS_RX_BATCH_DONE);
  155. if(hspi->Instance == SPI1)
  156. NVIC_ClearPendingIRQ(SPI1_IRQn);
  157. else if(hspi->Instance == SPI2)
  158. NVIC_ClearPendingIRQ(SPI2_IRQn);
  159. /* Rx Disable */
  160. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_DMA_REQ_EN);
  161. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  162. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  163. {
  164. /* Receive End */
  165. hspi->Instance->CS &= (~SPI_CS_CS0);
  166. }
  167. hspi->RxState = SPI_RX_STATE_IDLE;
  168. }
  169. }
  170. /************************************************************************
  171. * function : HAL_SPI_MspInit
  172. * Description:
  173. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  174. * the configuration information for SPI module
  175. ************************************************************************/
  176. __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
  177. {
  178. /*
  179. NOTE : This function should be modified by the user.
  180. */
  181. /* For Example */
  182. GPIO_InitTypeDef GPIO_Handle;
  183. /* SPI1 */
  184. if (hspi->Instance == SPI1)
  185. {
  186. }
  187. /* SPI2 */
  188. else if (hspi->Instance == SPI2)
  189. {
  190. /* Enable Clock */
  191. System_Module_Enable(EN_SPI2);
  192. /* SPI2 CS PB12 */
  193. /* SPI2 SCK PB13 */
  194. /* SPI2 MOSI PB15 */
  195. /* SPI2 MISO PB14 */
  196. GPIO_Handle.Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
  197. GPIO_Handle.Mode = GPIO_MODE_AF_PP;
  198. GPIO_Handle.Pull = GPIO_PULLUP;
  199. GPIO_Handle.Alternate = GPIO_FUNCTION_4;
  200. HAL_GPIO_Init(GPIOB, &GPIO_Handle);
  201. if (hspi->Init.X_Mode == SPI_4X_MODE)
  202. {
  203. /* SPI2 IO3 PC6 */
  204. /* SPI2 IO2 PC7 */
  205. GPIO_Handle.Pin = GPIO_PIN_6 | GPIO_PIN_7;
  206. GPIO_Handle.Mode = GPIO_MODE_AF_PP;
  207. GPIO_Handle.Pull = GPIO_PULLUP;
  208. GPIO_Handle.Alternate = GPIO_FUNCTION_2;
  209. HAL_GPIO_Init(GPIOC, &GPIO_Handle);
  210. }
  211. /* Clear Pending Interrupt */
  212. NVIC_ClearPendingIRQ(SPI2_IRQn);
  213. /* Enable External Interrupt */
  214. NVIC_EnableIRQ(SPI2_IRQn);
  215. }
  216. }
  217. /************************************************************************
  218. * function : HAL_SPI_MspDeInit
  219. * Description: SPI De-Initialize the SPI clock, GPIO, IRQ.
  220. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  221. * the configuration information for SPI module
  222. ************************************************************************/
  223. __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
  224. {
  225. /*
  226. NOTE : This function should be modified by the user.
  227. */
  228. /* For Example */
  229. /* SPI1 */
  230. if (hspi->Instance == SPI1)
  231. {
  232. }
  233. /* SPI2 */
  234. else if (hspi->Instance == SPI2)
  235. {
  236. /* Disable Clock */
  237. System_Module_Disable(EN_SPI2);
  238. /* Reset the used GPIO to analog */
  239. HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
  240. if (hspi->Init.X_Mode == SPI_4X_MODE)
  241. {
  242. HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6 | GPIO_PIN_7);
  243. }
  244. /* Clear Pending Interrupt */
  245. NVIC_ClearPendingIRQ(SPI2_IRQn);
  246. /* Disable External Interrupt */
  247. NVIC_DisableIRQ(SPI2_IRQn);
  248. }
  249. }
  250. /************************************************************************
  251. * function : HAL_SPI_Init
  252. * Description: SPI initial with parameters.
  253. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  254. * the configuration information for SPI module
  255. ************************************************************************/
  256. HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
  257. {
  258. /* Check SPI Parameter */
  259. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  260. if (!IS_SPI_ALL_MODE(hspi->Init.SPI_Mode)) return HAL_ERROR;
  261. if (!IS_SPI_WORK_MODE(hspi->Init.SPI_Work_Mode)) return HAL_ERROR;
  262. if (!IS_SPI_X_MODE(hspi->Init.X_Mode)) return HAL_ERROR;
  263. if (!IS_SPI_FIRST_BIT(hspi->Init.First_Bit)) return HAL_ERROR;
  264. if (!IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRate_Prescaler)) return HAL_ERROR;
  265. /* Init the low level hardware : GPIO, CLOCK, NVIC */
  266. HAL_SPI_MspInit(hspi);
  267. /* Automatic change direction */
  268. hspi->Instance->CTL |= (SPI_CTL_IO_MODE);
  269. /* Set SPI Work mode */
  270. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  271. {
  272. SET_BIT(hspi->Instance->CTL, SPI_CTL_MST_MODE);
  273. }
  274. else
  275. {
  276. CLEAR_BIT(hspi->Instance->CTL, SPI_CTL_MST_MODE);
  277. hspi->Instance->BATCH = (hspi->Instance->BATCH & (~0x000FFFFFU)) | (1 << 0);
  278. hspi->Instance->TX_CTL |= SPI_TX_CTL_MODE | (0x88 << 8); // dummy data = 0x88
  279. if (hspi->Init.X_Mode != SPI_1X_MODE)
  280. {
  281. hspi->Instance->CTL |= SPI_CTL_SFILTER;
  282. }
  283. /* Slave Alternate Enable */
  284. hspi->Instance->CTL |= SPI_CTL_SLAVE_EN;
  285. /* Slave Mode Enable Rx By Default */
  286. hspi->Instance->RX_CTL |= SPI_RX_CTL_EN;
  287. }
  288. /* Set SPI First Bit */
  289. if (hspi->Init.First_Bit == SPI_FIRSTBIT_LSB)
  290. SET_BIT(hspi->Instance->CTL, SPI_CTL_LSB_FIRST);
  291. else
  292. CLEAR_BIT(hspi->Instance->CTL, SPI_CTL_LSB_FIRST);
  293. /* Set SPI Work Mode */
  294. hspi->Instance->CTL = ((hspi->Instance->CTL) & (~(SPI_CTL_CPHA | SPI_CTL_CPOL))) | (hspi->Init.SPI_Work_Mode);
  295. /* Set SPI X_Mode */
  296. hspi->Instance->CTL = ((hspi->Instance->CTL) & (~SPI_CTL_X_MODE)) | (hspi->Init.X_Mode);
  297. /* Set SPI BaudRate Prescaler */
  298. hspi->Instance->BAUD = ((hspi->Instance->BAUD) & (~0x0000FFFF)) | (hspi->Init.BaudRate_Prescaler);
  299. /* Disable All Interrupt */
  300. hspi->Instance->IE = 0x00000000;
  301. return HAL_OK;
  302. }
  303. /************************************************************************
  304. * function : HAL_SPI_DeInit
  305. * Description: De-Initialize the SPI peripheral.
  306. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  307. * the configuration information for SPI module
  308. * return : HAL_StatusTypeDef : HAL status
  309. ************************************************************************/
  310. HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
  311. {
  312. /* Check the SPI handle allocation */
  313. if (hspi == NULL)
  314. {
  315. return HAL_ERROR;
  316. }
  317. /* Check SPI Instance parameter */
  318. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  319. hspi->RxState = SPI_RX_STATE_IDLE;
  320. hspi->TxState = SPI_TX_STATE_IDLE;
  321. /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
  322. HAL_SPI_MspDeInit(hspi);
  323. hspi->Rx_Size = 0;
  324. hspi->Tx_Size = 0;
  325. hspi->Rx_Count = 0;
  326. hspi->Tx_Count = 0;
  327. return HAL_OK;
  328. }
  329. /************************************************************************
  330. * function : HAL_SPI_Transmit
  331. * Description: Transmits an amount of data in blocking mode.
  332. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  333. * the configuration information for SPI module
  334. * pData : Pointer to data buffer
  335. * Size : Amount of data to be sent
  336. * Timeout : Transmit Timeout
  337. ************************************************************************/
  338. HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
  339. {
  340. HAL_StatusTypeDef Status = HAL_OK;
  341. __IO uint32_t uiTimeout;
  342. /* Check SPI Parameter */
  343. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  344. if(!Size) return HAL_ERROR;
  345. if (pData == NULL) return HAL_ERROR;
  346. hspi->Tx_Count = 0;
  347. hspi->Tx_Size = Size;
  348. hspi->Tx_Buffer = pData;
  349. uiTimeout = Timeout;
  350. /* Clear Batch Done Flag */
  351. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_TX_BATCH_DONE);
  352. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  353. /* Clear TX FIFO */
  354. SET_BIT(hspi->Instance->TX_CTL, SPI_TX_CTL_FIFO_RESET);
  355. CLEAR_BIT(hspi->Instance->TX_CTL, SPI_TX_CTL_FIFO_RESET);
  356. /* Set Data Size */
  357. hspi->Instance->BATCH = Size;
  358. /* Tx Enable */
  359. hspi->Instance->TX_CTL |= SPI_TX_CTL_EN;
  360. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  361. {
  362. /* Transmit Start */
  363. hspi->Instance->CS |= SPI_CS_CS0;
  364. }
  365. else
  366. {
  367. /* Rx Disable */
  368. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  369. }
  370. while(hspi->Tx_Size > 0)
  371. {
  372. /* Wait Tx FIFO Not Full */
  373. while (hspi->Instance->STATUS & SPI_STATUS_TX_FIFO_FULL)
  374. {
  375. if(uiTimeout)
  376. {
  377. uiTimeout--;
  378. if (uiTimeout == 0)
  379. {
  380. Status = HAL_TIMEOUT;
  381. goto End;
  382. }
  383. }
  384. }
  385. hspi->Instance->DAT = hspi->Tx_Buffer[hspi->Tx_Count++];
  386. hspi->Tx_Size--;
  387. uiTimeout = Timeout;
  388. }
  389. if (hspi->Init.SPI_Mode == SPI_MODE_SLAVE)
  390. {
  391. /* Wait Transmit Done */
  392. while (!(hspi->Instance->STATUS & SPI_STATUS_TX_BUSY));
  393. while (hspi->Instance->STATUS & SPI_STATUS_TX_BUSY)
  394. {
  395. if(uiTimeout)
  396. {
  397. uiTimeout--;
  398. if (uiTimeout == 0)
  399. {
  400. Status = HAL_TIMEOUT;
  401. goto End;
  402. }
  403. }
  404. }
  405. }
  406. else
  407. {
  408. /* Wait Transmit Done */
  409. while (!(hspi->Instance->STATUS & SPI_STATUS_TX_BATCH_DONE));
  410. Status = HAL_OK;
  411. }
  412. End:
  413. /* Clear Batch Done Flag */
  414. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_TX_BATCH_DONE);
  415. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  416. /* Tx Disable */
  417. hspi->Instance->TX_CTL &= (~SPI_TX_CTL_EN);
  418. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  419. {
  420. /* Transmit End */
  421. hspi->Instance->CS &= (~SPI_CS_CS0);
  422. }
  423. return Status;
  424. }
  425. /************************************************************************
  426. * function : HAL_SPI_Transmit_DMA
  427. * Description: Transmits an amount of data in blocking mode with DMA.
  428. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  429. * the configuration information for SPI module
  430. * pData : Pointer to data buffer
  431. * Size : Amount of data to be sent
  432. ************************************************************************/
  433. HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size)
  434. {
  435. /* Check SPI Parameter */
  436. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  437. /* Rx machine is running */
  438. if (hspi->TxState != SPI_TX_STATE_IDLE)
  439. {
  440. return HAL_ERROR;
  441. }
  442. /* Set machine is Sending */
  443. hspi->TxState = SPI_TX_STATE_SENDING;
  444. /* Clear Batch Done Flag */
  445. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_TX_BATCH_DONE);
  446. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  447. /* Enable Tx Batch Done Interrupt */
  448. SET_BIT(hspi->Instance->IE, SPI_STATUS_TX_BATCH_DONE);
  449. /* Set Data Size */
  450. hspi->Instance->BATCH = Size;
  451. /* Tx FIFO */
  452. hspi->Instance->TX_CTL &= ~SPI_TX_CTL_DMA_LEVEL;
  453. hspi->Instance->TX_CTL |= SPI_TX_CTL_DMA_LEVEL_0;
  454. /* Tx Enable */
  455. hspi->Instance->TX_CTL |= SPI_TX_CTL_EN;
  456. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  457. {
  458. /* Transmit Start */
  459. hspi->Instance->CS |= SPI_CS_CS0;
  460. }
  461. else
  462. {
  463. /* Rx Disable */
  464. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  465. }
  466. HAL_DMA_Start(hspi->HDMA_Tx, (uint32_t)pData, (uint32_t)&hspi->Instance->DAT, Size);
  467. hspi->Instance->TX_CTL |= SPI_TX_CTL_DMA_REQ_EN;
  468. return HAL_OK;
  469. }
  470. /************************************************************************
  471. * function : HAL_SPI_Receive
  472. * Description: Receive an amount of data in blocking mode.
  473. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  474. * the configuration information for SPI module
  475. * pData : Pointer to data buffer
  476. * Size : Amount of data to be Receive
  477. * Timeout : Receive Timeout
  478. ************************************************************************/
  479. HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
  480. {
  481. HAL_StatusTypeDef Status = HAL_OK;
  482. __IO uint32_t uiTimeout;
  483. /* Check SPI Parameter */
  484. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  485. if (pData == NULL) return HAL_ERROR;
  486. hspi->Rx_Count = 0;
  487. hspi->Rx_Size = Size;
  488. hspi->Rx_Buffer = pData;
  489. uiTimeout = Timeout;
  490. if (hspi->Init.SPI_Mode == SPI_MODE_SLAVE)
  491. {
  492. hspi->Instance->BATCH = 1;
  493. /* Rx Enable */
  494. hspi->Instance->RX_CTL |= SPI_RX_CTL_EN;
  495. while ( hspi->Rx_Size > 0)
  496. {
  497. while (READ_BIT(hspi->Instance->STATUS, SPI_STATUS_RX_FIFO_EMPTY))
  498. {
  499. if(uiTimeout)
  500. {
  501. uiTimeout--;
  502. if (uiTimeout == 0)
  503. {
  504. /* Rx Disable */
  505. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  506. return HAL_TIMEOUT;
  507. }
  508. }
  509. }
  510. hspi->Rx_Buffer[hspi->Rx_Count++] = hspi->Instance->DAT;
  511. hspi->Rx_Size--;
  512. uiTimeout = Timeout;
  513. }
  514. /* Rx Disable */
  515. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  516. return HAL_OK;
  517. }
  518. /* Clear Batch Done Flag */
  519. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_RX_BATCH_DONE);
  520. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  521. /* Set Data Size */
  522. hspi->Instance->BATCH = Size;
  523. /* Rx Enable */
  524. hspi->Instance->RX_CTL |= SPI_RX_CTL_EN;
  525. /* Receive Start */
  526. hspi->Instance->CS |= SPI_CS_CS0;
  527. while(hspi->Rx_Size > 0)
  528. {
  529. /* have no timeout */
  530. if (uiTimeout == 0)
  531. {
  532. /* Wait Rx FIFO Not Empty */
  533. while (hspi->Instance->STATUS & SPI_STATUS_RX_FIFO_EMPTY);
  534. }
  535. else
  536. {
  537. while (hspi->Instance->STATUS & SPI_STATUS_RX_FIFO_EMPTY)
  538. {
  539. if (uiTimeout-- == 0)
  540. {
  541. Status = HAL_TIMEOUT;
  542. goto End;
  543. }
  544. }
  545. }
  546. hspi->Rx_Buffer[hspi->Rx_Count++] = hspi->Instance->DAT;
  547. hspi->Rx_Size--;
  548. }
  549. Status = HAL_OK;
  550. /* Wait Transmit Done */
  551. while (!(hspi->Instance->STATUS & SPI_STATUS_RX_BATCH_DONE));
  552. End:
  553. /* Clear Batch Done Flag */
  554. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_RX_BATCH_DONE);
  555. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  556. /* Rx Disable */
  557. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  558. /* Receive End */
  559. hspi->Instance->CS &= (~SPI_CS_CS0);
  560. return Status;
  561. }
  562. /************************************************************************
  563. * function : HAL_SPI_Receive_DMA
  564. * Description: Receive an amount of data in blocking mode with DMA.
  565. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  566. * the configuration information for SPI module
  567. * pData : Pointer to data buffer
  568. * Size : Amount of data to be Receive
  569. ************************************************************************/
  570. HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size)
  571. {
  572. /* Check SPI Parameter */
  573. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  574. /* Rx machine is running */
  575. if (hspi->RxState != SPI_RX_STATE_IDLE)
  576. {
  577. return HAL_ERROR;
  578. }
  579. /* Set Slave machine is receiving */
  580. hspi->RxState = SPI_RX_STATE_RECEIVING;
  581. /* Clear Batch Done Flag */
  582. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_RX_BATCH_DONE);
  583. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  584. /* Enable Rx Batch Done Interrupt */
  585. SET_BIT(hspi->Instance->IE, SPI_STATUS_RX_BATCH_DONE);
  586. /* Set Data Size */
  587. hspi->Instance->BATCH = Size;
  588. /* Rx Enable */
  589. hspi->Instance->RX_CTL |= SPI_RX_CTL_EN;
  590. /* Rx FIFO */
  591. hspi->Instance->RX_CTL |= SPI_RX_CTL_DMA_LEVEL_0;
  592. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  593. {
  594. /* Receive Start */
  595. hspi->Instance->CS |= SPI_CS_CS0;
  596. }
  597. HAL_DMA_Start(hspi->HDMA_Rx, (uint32_t)&hspi->Instance->DAT, (uint32_t)pData, Size);
  598. hspi->Instance->RX_CTL |= SPI_RX_CTL_DMA_REQ_EN;
  599. return HAL_OK;
  600. }
  601. /************************************************************************
  602. * function : HAL_SPI_Wire_Config
  603. * Description: SPI Wire Config
  604. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  605. * the configuration information for SPI module
  606. * Mode : This parameter can be a value of @ref X_MODE
  607. ************************************************************************/
  608. HAL_StatusTypeDef HAL_SPI_Wire_Config(SPI_HandleTypeDef *hspi, uint32_t X_Mode)
  609. {
  610. /* Check SPI Parameter */
  611. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  612. /* Set SPI X_Mode */
  613. hspi->Instance->CTL = ((hspi->Instance->CTL) & (~SPI_CTL_X_MODE)) | X_Mode;
  614. return HAL_OK;
  615. }
  616. /************************************************************************
  617. * function : HAL_SPI_Transmit_IT
  618. * Description: Transmit an amount of data in blocking mode with interrupt.
  619. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  620. * the configuration information for SPI module
  621. * pData : Pointer to data buffer
  622. ************************************************************************/
  623. HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size)
  624. {
  625. /* Check SPI Parameter */
  626. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  627. /* Tx machine is running */
  628. if (hspi->TxState != SPI_TX_STATE_IDLE)
  629. {
  630. return HAL_ERROR;
  631. }
  632. hspi->Tx_Size = Size;
  633. hspi->Tx_Buffer = pData;
  634. hspi->Tx_Count = 0;
  635. /* Set machine is Sending */
  636. hspi->TxState = SPI_TX_STATE_SENDING;
  637. /* Clear TX FIFO */
  638. SET_BIT(hspi->Instance->TX_CTL, SPI_TX_CTL_FIFO_RESET);
  639. CLEAR_BIT(hspi->Instance->TX_CTL, SPI_TX_CTL_FIFO_RESET);
  640. /* Clear Batch Done Flag */
  641. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_TX_BATCH_DONE);
  642. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  643. /* Set Data Size */
  644. hspi->Instance->BATCH = Size;
  645. /* Tx Enable */
  646. hspi->Instance->TX_CTL |= SPI_TX_CTL_EN;
  647. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  648. {
  649. /* Transmit Start */
  650. hspi->Instance->CS |= SPI_CS_CS0;
  651. }
  652. else
  653. {
  654. /* Rx Disable */
  655. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  656. }
  657. while (hspi->Tx_Count < hspi->Tx_Size)
  658. {
  659. if (!(hspi->Instance->STATUS & SPI_STATUS_TX_FIFO_FULL))
  660. hspi->Instance->DAT = hspi->Tx_Buffer[hspi->Tx_Count++];
  661. else
  662. break;
  663. }
  664. /* Clear Tx FIFO half empty Flag */
  665. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_TX_FIFO_HALF_EMPTY);
  666. /* Enable Tx FIFO half empty Interrupt and Tx batch done Interrupt*/
  667. SET_BIT(hspi->Instance->IE, (SPI_IE_TX_FIFO_HALF_EMPTY_EN | SPI_IE_TX_BATCH_DONE_EN));
  668. return HAL_OK;
  669. }
  670. /************************************************************************
  671. * function : HAL_SPI_Receive_IT
  672. * Description: Receive an amount of data in blocking mode with interrupt.
  673. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  674. * the configuration information for SPI module
  675. * pData : Pointer to data buffer
  676. ************************************************************************/
  677. HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size)
  678. {
  679. /* Check SPI Parameter */
  680. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  681. /* Rx machine is running */
  682. if (hspi->RxState != SPI_RX_STATE_IDLE)
  683. {
  684. return HAL_ERROR;
  685. }
  686. /* Set Slave machine is receiving */
  687. hspi->RxState = SPI_RX_STATE_RECEIVING;
  688. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  689. {
  690. /* Clear Batch Done Flag */
  691. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_RX_BATCH_DONE);
  692. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  693. /* Set Data Size */
  694. hspi->Instance->BATCH = Size;
  695. /* Rx Enable */
  696. hspi->Instance->RX_CTL |= SPI_RX_CTL_EN;
  697. /* Receive Start */
  698. hspi->Instance->CS |= SPI_CS_CS0;
  699. }
  700. else
  701. {
  702. /* Reset BATCH register */
  703. hspi->Instance->BATCH = 1;
  704. hspi->Instance->RX_CTL |= SPI_RX_CTL_EN;
  705. }
  706. hspi->Rx_Size = Size;
  707. hspi->Rx_Buffer = pData;
  708. hspi->Rx_Count = 0;
  709. lu32_ReceiveTimeOut = SPI_RX_TIMEOUT;
  710. /* Enable Rx FIFO Not Empty Interrupt */
  711. SET_BIT(hspi->Instance->IE, SPI_STATUS_RX_NOT_EMPTY);
  712. return HAL_OK;
  713. }
  714. /************************************************************************
  715. * function : HAL_SPI_TransmitReceive
  716. * Description: Transmits and recieve an amount of data in blocking mode.
  717. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  718. * the configuration information for SPI module
  719. * pTxData : Pointer to transmit data buffer
  720. * pRxData : Pointer to recieve data buffer
  721. * Size : Amount of data to be sent
  722. * Timeout : TransmitReceive Timeout
  723. ************************************************************************/
  724. HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint32_t Size, uint32_t Timeout)
  725. {
  726. __IO uint32_t TxFlag = 1U, uiTimeout, uiRegTemp;
  727. HAL_StatusTypeDef Status = HAL_OK;
  728. /* Check SPI Parameter */
  729. if (!IS_SPI_ALL_INSTANCE(hspi->Instance)) return HAL_ERROR;
  730. if ((pTxData == NULL)||(pRxData == NULL)) return HAL_ERROR;
  731. hspi->Tx_Count = 0;
  732. hspi->Rx_Count = 0;
  733. hspi->Tx_Buffer = pTxData;
  734. hspi->Rx_Buffer = pRxData;
  735. hspi->Tx_Size = Size;
  736. hspi->Rx_Size = Size;
  737. uiTimeout = Timeout;
  738. /* Clear Batch Done Flag */
  739. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_TX_BATCH_DONE);
  740. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  741. /* Tx Enable */
  742. hspi->Instance->TX_CTL |= SPI_TX_CTL_EN;
  743. /* Rx Enable */
  744. hspi->Instance->RX_CTL |= SPI_RX_CTL_EN;
  745. /* Clear TX FIFO */
  746. SET_BIT(hspi->Instance->TX_CTL, SPI_TX_CTL_FIFO_RESET);
  747. CLEAR_BIT(hspi->Instance->TX_CTL, SPI_TX_CTL_FIFO_RESET);
  748. if (hspi->Init.SPI_Mode == SPI_MODE_SLAVE)
  749. {
  750. while((!(hspi->Instance->STATUS & SPI_STATUS_TX_FIFO_FULL)) && (hspi->Tx_Size>0))
  751. {
  752. hspi->Instance->DAT = hspi->Tx_Buffer[hspi->Tx_Count++];
  753. hspi->Tx_Size--;
  754. }
  755. TxFlag = 0;
  756. }
  757. else
  758. {
  759. /* Set Data Size */
  760. hspi->Instance->BATCH = hspi->Tx_Size;
  761. /* Transmit Start */
  762. hspi->Instance->CS |= SPI_CS_CS0;
  763. TxFlag = 1;
  764. }
  765. while((hspi->Tx_Size>0) || (hspi->Rx_Size>0))
  766. {
  767. uiRegTemp = hspi->Instance->STATUS;
  768. if (hspi->Init.SPI_Mode == SPI_MODE_SLAVE)
  769. {
  770. /* Wait Rx FIFO Not Empty */
  771. if((!(uiRegTemp & SPI_STATUS_RX_FIFO_EMPTY)) && (hspi->Rx_Size>0))
  772. {
  773. hspi->Rx_Buffer[hspi->Rx_Count++] = hspi->Instance->DAT;
  774. hspi->Rx_Size--;
  775. TxFlag = 1U;
  776. }
  777. /* Wait Tx FIFO Not Full */
  778. if(((uiRegTemp & SPI_STATUS_TX_FIFO_HALF_EMPTY)) && (hspi->Tx_Size>0) && (TxFlag == 1U))
  779. {
  780. while((!(hspi->Instance->STATUS & SPI_STATUS_TX_FIFO_FULL)) && (hspi->Tx_Size>0))
  781. {
  782. hspi->Instance->DAT = hspi->Tx_Buffer[hspi->Tx_Count++];
  783. hspi->Tx_Size--;
  784. }
  785. TxFlag = 0;
  786. }
  787. }
  788. else
  789. {
  790. /* Wait Tx FIFO Not Full */
  791. if((!(uiRegTemp & SPI_STATUS_TX_FIFO_FULL)) && (hspi->Tx_Size>0) && (TxFlag == 1U))
  792. {
  793. hspi->Instance->DAT = hspi->Tx_Buffer[hspi->Tx_Count++];
  794. hspi->Tx_Size--;
  795. TxFlag = 0;
  796. }
  797. /* Wait Rx FIFO Not Empty */
  798. if((!(uiRegTemp & SPI_STATUS_RX_FIFO_EMPTY)) && (hspi->Rx_Size>0))
  799. {
  800. hspi->Rx_Buffer[hspi->Rx_Count++] = hspi->Instance->DAT;
  801. hspi->Rx_Size--;
  802. TxFlag = 1U;
  803. }
  804. }
  805. /* Wait Timeout */
  806. if(uiTimeout)
  807. {
  808. uiTimeout--;
  809. if(uiTimeout == 0)
  810. {
  811. Status = HAL_TIMEOUT;
  812. goto End;
  813. }
  814. }
  815. }
  816. /* Wait Transmit Done */
  817. while (!(hspi->Instance->STATUS & SPI_STATUS_TX_BATCH_DONE));
  818. Status = HAL_OK;
  819. End:
  820. /* Clear Batch Done Flag */
  821. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_TX_BATCH_DONE);
  822. SET_BIT(hspi->Instance->STATUS, SPI_STATUS_BATCH_DONE);
  823. /* Tx Disable */
  824. hspi->Instance->TX_CTL &= (~SPI_TX_CTL_EN);
  825. /* Rx Disable */
  826. hspi->Instance->RX_CTL &= (~SPI_RX_CTL_EN);
  827. if (hspi->Init.SPI_Mode == SPI_MODE_MASTER)
  828. {
  829. /* Transmit End */
  830. hspi->Instance->CS &= (~SPI_CS_CS0);
  831. }
  832. return Status;
  833. }
  834. /************************************************************************
  835. * function : HAL_SPI_GetTxState
  836. * Description: Get Tx state.
  837. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  838. * the configuration information for SPI module
  839. ************************************************************************/
  840. uint8_t HAL_SPI_GetTxState(SPI_HandleTypeDef *hspi)
  841. {
  842. return hspi->TxState;
  843. }
  844. /************************************************************************
  845. * function : HAL_SPI_GetRxState
  846. * Description: Get Rx state.
  847. * input : hspi : pointer to a SPI_HandleTypeDef structure that contains
  848. * the configuration information for SPI module
  849. ************************************************************************/
  850. uint8_t HAL_SPI_GetRxState(SPI_HandleTypeDef *hspi)
  851. {
  852. return hspi->RxState;
  853. }