Improve generic & stm32f4 demos
[lwext4.git] / demos / stm32f429_disco / stm / stm32f4_spl / src / stm32f4xx_hal_spi.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32f4xx_hal_spi.c\r
4   * @author  MCD Application Team\r
5   * @version V1.0.0\r
6   * @date    18-February-2014\r
7   * @brief   SPI HAL module driver.\r
8   *    \r
9   *          This file provides firmware functions to manage the following \r
10   *          functionalities of the Serial Peripheral Interface (SPI) peripheral:\r
11   *           + Initialization and de-initialization functions\r
12   *           + IO operation functions\r
13   *           + Peripheral Control functions \r
14   *           + Peripheral State functions\r
15   @verbatim\r
16   ==============================================================================\r
17                         ##### How to use this driver #####\r
18   ==============================================================================\r
19     [..]\r
20       The SPI HAL driver can be used as follows:\r
21 \r
22       (#) Declare a SPI_HandleTypeDef handle structure, for example:\r
23           SPI_HandleTypeDef  hspi; \r
24 \r
25       (#)Initialize the SPI low level resources by implement the HAL_SPI_MspInit ()API:\r
26           (##) Enable the SPIx interface clock \r
27           (##) SPI pins configuration\r
28               (+++) Enable the clock for the SPI GPIOs \r
29               (+++) Configure these SPI pins as alternate function push-pull\r
30           (##) NVIC configuration if you need to use interrupt process\r
31               (+++) Configure the SPIx interrupt priority\r
32               (+++) Enable the NVIC SPI IRQ handle\r
33           (##) DMA Configuration if you need to use DMA process\r
34               (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream\r
35               (+++) Enable the DMAx interface clock using \r
36               (+++) Configure the DMA handle parameters \r
37               (+++) Configure the DMA Tx or Rx Stream\r
38               (+++) Associate the initilalized hdma_tx handle to the hspi DMA Tx or Rx handle\r
39               (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Stream\r
40 \r
41       (#) Program the Mode, Direction , Data size, Baudrate Prescaler, NSS \r
42           management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.\r
43 \r
44       (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:\r
45           (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)\r
46               by calling the customed HAL_SPI_MspInit(&hspi) API.\r
47             \r
48   @endverbatim\r
49   ******************************************************************************\r
50   * @attention\r
51   *\r
52   * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>\r
53   *\r
54   * Redistribution and use in source and binary forms, with or without modification,\r
55   * are permitted provided that the following conditions are met:\r
56   *   1. Redistributions of source code must retain the above copyright notice,\r
57   *      this list of conditions and the following disclaimer.\r
58   *   2. Redistributions in binary form must reproduce the above copyright notice,\r
59   *      this list of conditions and the following disclaimer in the documentation\r
60   *      and/or other materials provided with the distribution.\r
61   *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
62   *      may be used to endorse or promote products derived from this software\r
63   *      without specific prior written permission.\r
64   *\r
65   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
66   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
67   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
68   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
69   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
70   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
71   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
72   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
73   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
74   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
75   *\r
76   ******************************************************************************\r
77   */\r
78 \r
79 /* Includes ------------------------------------------------------------------*/\r
80 #include "stm32f4xx_hal.h"\r
81 \r
82 /** @addtogroup STM32F4xx_HAL_Driver\r
83   * @{\r
84   */\r
85 \r
86 /** @defgroup SPI \r
87   * @brief SPI HAL module driver\r
88   * @{\r
89   */\r
90 \r
91 #ifdef HAL_SPI_MODULE_ENABLED\r
92 \r
93 /* Private typedef -----------------------------------------------------------*/\r
94 /* Private define ------------------------------------------------------------*/\r
95 #define SPI_TIMEOUT_VALUE  10\r
96 /* Private macro -------------------------------------------------------------*/\r
97 /* Private variables ---------------------------------------------------------*/\r
98 /* Private function prototypes -----------------------------------------------*/\r
99 static void SPI_TxCloseIRQHandler(SPI_HandleTypeDef *hspi);\r
100 static void SPI_TxISR(SPI_HandleTypeDef *hspi);\r
101 static void SPI_RxCloseIRQHandler(SPI_HandleTypeDef *hspi);\r
102 static void SPI_2LinesRxISR(SPI_HandleTypeDef *hspi);\r
103 static void SPI_RxISR(SPI_HandleTypeDef *hspi);\r
104 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);\r
105 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);\r
106 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);\r
107 static void SPI_DMAError(DMA_HandleTypeDef *hdma);\r
108 static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status, uint32_t Timeout);\r
109 \r
110 /* Private functions ---------------------------------------------------------*/\r
111 \r
112 /** @defgroup SPI_Private_Functions\r
113   * @{\r
114   */\r
115 \r
116 /** @defgroup SPI_Group1 Initialization and de-initialization functions \r
117  *  @brief    Initialization and Configuration functions \r
118  *\r
119 @verbatim\r
120  ===============================================================================\r
121               ##### Initialization and de-initialization functions #####\r
122  ===============================================================================\r
123     [..]  This subsection provides a set of functions allowing to initialize and \r
124           de-initialiaze the SPIx peripheral:\r
125 \r
126       (+) User must Implement HAL_SPI_MspInit() function in which he configures \r
127           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).\r
128 \r
129       (+) Call the function HAL_SPI_Init() to configure the selected device with \r
130           the selected configuration:\r
131         (++) Mode\r
132         (++) Direction \r
133         (++) Data Size\r
134         (++) Clock Polarity and Phase\r
135         (++) NSS Management\r
136         (++) BaudRate Prescaler\r
137         (++) FirstBit\r
138         (++) TIMode\r
139         (++) CRC Calculation\r
140         (++) CRC Polynomial if CRC enabled\r
141 \r
142       (+) Call the function HAL_SPI_DeInit() to restore the default configuration \r
143           of the selected SPIx periperal.       \r
144 \r
145 @endverbatim\r
146   * @{\r
147   */\r
148 \r
149 /**\r
150   * @brief  Initializes the SPI according to the specified parameters \r
151   *         in the SPI_InitTypeDef and create the associated handle.\r
152   * @param  hspi: SPI handle\r
153   * @retval HAL status\r
154   */\r
155 HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)\r
156 {\r
157   /* Check the SPI handle allocation */\r
158   if(hspi == NULL)\r
159   {\r
160     return HAL_ERROR;\r
161   }\r
162 \r
163   /* Check the parameters */\r
164   assert_param(IS_SPI_MODE(hspi->Init.Mode));\r
165   assert_param(IS_SPI_DIRECTION_MODE(hspi->Init.Direction));\r
166   assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));\r
167   assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));\r
168   assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));\r
169   assert_param(IS_SPI_NSS(hspi->Init.NSS));\r
170   assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));\r
171   assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));\r
172   assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));\r
173   assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));\r
174   assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));\r
175 \r
176   if(hspi->State == HAL_SPI_STATE_RESET)\r
177   {\r
178     /* Init the low level hardware : GPIO, CLOCK, NVIC... */\r
179     HAL_SPI_MspInit(hspi);\r
180   }\r
181   \r
182   hspi->State = HAL_SPI_STATE_BUSY;\r
183 \r
184   /* Disble the selected SPI peripheral */\r
185   __HAL_SPI_DISABLE(hspi);\r
186 \r
187   /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/\r
188   /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,\r
189   Communication speed, First bit and CRC calculation state */\r
190   hspi->Instance->CR1 = (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |\r
191                          hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |\r
192                          hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit  | hspi->Init.CRCCalculation);\r
193 \r
194   /* Configure : NSS management */\r
195   hspi->Instance->CR2 = (((hspi->Init.NSS >> 16) & SPI_CR2_SSOE) | hspi->Init.TIMode);\r
196 \r
197   /*---------------------------- SPIx CRCPOLY Configuration ------------------*/\r
198   /* Configure : CRC Polynomial */\r
199   hspi->Instance->CRCPR = hspi->Init.CRCPolynomial;\r
200 \r
201   /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */\r
202   hspi->Instance->I2SCFGR &= (uint32_t)(~SPI_I2SCFGR_I2SMOD);\r
203 \r
204   hspi->ErrorCode = HAL_SPI_ERROR_NONE;\r
205   hspi->State = HAL_SPI_STATE_READY;\r
206   \r
207   return HAL_OK;\r
208 }\r
209 \r
210 /**\r
211   * @brief  DeInitializes the SPI peripheral \r
212   * @param  hspi: SPI handle\r
213   * @retval HAL status\r
214   */\r
215 HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)\r
216 {\r
217   /* Check the SPI handle allocation */\r
218   if(hspi == NULL)\r
219   {\r
220     return HAL_ERROR;\r
221   }\r
222 \r
223   /* Disable the SPI Peripheral Clock */\r
224   __HAL_SPI_DISABLE(hspi);\r
225 \r
226   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */\r
227   HAL_SPI_MspDeInit(hspi);\r
228 \r
229   hspi->ErrorCode = HAL_SPI_ERROR_NONE;\r
230   hspi->State = HAL_SPI_STATE_RESET;\r
231 \r
232   /* Release Lock */\r
233   __HAL_UNLOCK(hspi);\r
234 \r
235   return HAL_OK;\r
236 }\r
237 \r
238 /**\r
239   * @brief SPI MSP Init\r
240   * @param hspi: SPI handle\r
241   * @retval None\r
242   */\r
243  __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)\r
244  {\r
245    /* NOTE : This function Should not be modified, when the callback is needed,\r
246             the HAL_SPI_MspInit could be implenetd in the user file\r
247    */\r
248 }\r
249 \r
250 /**\r
251   * @brief SPI MSP DeInit\r
252   * @param hspi: SPI handle\r
253   * @retval None\r
254   */\r
255  __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)\r
256 {\r
257   /* NOTE : This function Should not be modified, when the callback is needed,\r
258             the HAL_SPI_MspDeInit could be implenetd in the user file\r
259    */\r
260 }\r
261 \r
262 /**\r
263   * @}\r
264   */\r
265 \r
266 /** @defgroup SPI_Group2 IO operation functions\r
267  *  @brief   Data transfers functions\r
268  *\r
269 @verbatim\r
270   ==============================================================================\r
271                       ##### IO operation functions #####\r
272  ===============================================================================\r
273     This subsection provides a set of functions allowing to manage the SPI\r
274     data transfers.\r
275 \r
276     [..] The SPI supports master and slave mode :\r
277 \r
278     (#) There are two mode of transfer:\r
279        (++) Blocking mode: The communication is performed in polling mode.\r
280             The HAL status of all data processing is returned by the same function\r
281             after finishing transfer.\r
282        (++) No-Blocking mode: The communication is performed using Interrupts\r
283            or DMA, These API's return the HAL status.\r
284            The end of the data processing will be indicated through the \r
285            dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when \r
286            using DMA mode.\r
287            The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks \r
288            will be executed respectivelly at the end of the transmit or Receive process\r
289            The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected\r
290 \r
291     (#) Blocking mode API's are :\r
292         (++) HAL_SPI_Transmit()in 1Line (simplex) and 2Lines (full duplex) mode\r
293         (++) HAL_SPI_Receive() in 1Line (simplex) and 2Lines (full duplex) mode\r
294         (++) HAL_SPI_TransmitReceive() in full duplex mode\r
295 \r
296     (#) Non-Blocking mode API's with Interrupt are :\r
297         (++) HAL_SPI_Transmit_IT()in 1Line (simplex) and 2Lines (full duplex) mode\r
298         (++) HAL_SPI_Receive_IT() in 1Line (simplex) and 2Lines (full duplex) mode\r
299         (++) HAL_SPI_TransmitReceive_IT()in full duplex mode\r
300         (++) HAL_SPI_IRQHandler()\r
301 \r
302     (#) No-Blocking mode functions with DMA are :\r
303         (++) HAL_SPI_Transmit_DMA()in 1Line (simplex) and 2Lines (full duplex) mode\r
304         (++) HAL_SPI_Receive_DMA() in 1Line (simplex) and 2Lines (full duplex) mode\r
305         (++) HAL_SPI_TransmitReceie_DMA() in full duplex mode\r
306 \r
307     (#) A set of Transfer Complete Callbacks are provided in No_Blocking mode:\r
308         (++) HAL_SPI_TxCpltCallback()\r
309         (++) HAL_SPI_RxCpltCallback()\r
310         (++) HAL_SPI_ErrorCallback()\r
311         (++) HAL_SPI_TxRxCpltCallback()\r
312 \r
313 @endverbatim\r
314   * @{\r
315   */\r
316 \r
317 /**\r
318   * @brief  Transmit an amount of data in blocking mode\r
319   * @param  hspi: SPI handle\r
320   * @param  pData: pointer to data buffer\r
321   * @param  Size: amount of data to be sent\r
322   * @param  Timeout: Timeout duration\r
323   * @retval HAL status\r
324   */\r
325 HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)\r
326 {\r
327 \r
328   if(hspi->State == HAL_SPI_STATE_READY)\r
329   {\r
330     if((pData == NULL ) || (Size == 0)) \r
331     {\r
332       return  HAL_ERROR;\r
333     }\r
334 \r
335     /* Check the parameters */\r
336     assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));\r
337 \r
338     /* Process Locked */\r
339     __HAL_LOCK(hspi);\r
340 \r
341     /* Configure communication */\r
342     hspi->State = HAL_SPI_STATE_BUSY_TX;\r
343     hspi->ErrorCode   = HAL_SPI_ERROR_NONE;\r
344 \r
345     hspi->pTxBuffPtr = pData;\r
346     hspi->TxXferSize = Size;\r
347     hspi->TxXferCount = Size;\r
348 \r
349     /*Init field not used in handle to zero */\r
350     hspi->TxISR = 0;\r
351     hspi->RxISR = 0;\r
352     hspi->RxXferSize   = 0;\r
353     hspi->RxXferCount  = 0;\r
354 \r
355     /* Reset CRC Calculation */\r
356     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
357     {\r
358       __HAL_SPI_RESET_CRC(hspi);\r
359     }\r
360 \r
361     if(hspi->Init.Direction == SPI_DIRECTION_1LINE)\r
362     {\r
363       /* Configure communication direction : 1Line */\r
364       __HAL_SPI_1LINE_TX(hspi);\r
365     }\r
366 \r
367     /* Check if the SPI is already enabled */ \r
368     if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)\r
369     {\r
370       /* Enable SPI peripheral */\r
371       __HAL_SPI_ENABLE(hspi);\r
372     }\r
373 \r
374     /* Transmit data in 8 Bit mode */\r
375     if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)\r
376     {\r
377 \r
378       hspi->Instance->DR = (*hspi->pTxBuffPtr++);\r
379       hspi->TxXferCount--;\r
380 \r
381       while(hspi->TxXferCount > 0)\r
382       {\r
383         /* Wait until TXE flag is set to send data */\r
384         if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)\r
385         { \r
386           return HAL_TIMEOUT;\r
387         }\r
388         hspi->Instance->DR = (*hspi->pTxBuffPtr++);\r
389         hspi->TxXferCount--;\r
390       }\r
391       /* Enable CRC Transmission */\r
392       if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED) \r
393       {\r
394         hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;\r
395       }\r
396     }\r
397     /* Transmit data in 16 Bit mode */\r
398     else\r
399     {\r
400       hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);\r
401       hspi->pTxBuffPtr+=2;\r
402       hspi->TxXferCount--;\r
403 \r
404       while(hspi->TxXferCount > 0)\r
405       {\r
406         /* Wait until TXE flag is set to send data */\r
407         if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)\r
408         { \r
409           return HAL_TIMEOUT;\r
410         }\r
411         hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);\r
412         hspi->pTxBuffPtr+=2;\r
413         hspi->TxXferCount--;\r
414       }\r
415       /* Enable CRC Transmission */\r
416       if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED) \r
417       {\r
418         hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;\r
419       }\r
420     }\r
421 \r
422     /* Wait until TXE flag is set to send data */\r
423     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)\r
424     {\r
425       hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
426       return HAL_TIMEOUT;\r
427     }\r
428 \r
429     /* Wait until Busy flag is reset before disabling SPI */\r
430     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, Timeout) != HAL_OK)\r
431     { \r
432       hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
433       return HAL_TIMEOUT;\r
434     }\r
435  \r
436     /* Clear OVERUN flag in 2 Lines communication mode because received is not read */\r
437     if(hspi->Init.Direction == SPI_DIRECTION_2LINES)\r
438     {\r
439       __HAL_SPI_CLEAR_OVRFLAG(hspi);\r
440     }\r
441 \r
442     hspi->State = HAL_SPI_STATE_READY; \r
443 \r
444     /* Process Unlocked */\r
445     __HAL_UNLOCK(hspi);\r
446 \r
447     return HAL_OK;\r
448   }\r
449   else\r
450   {\r
451     return HAL_BUSY;\r
452   }\r
453 }\r
454 \r
455 /**\r
456   * @brief  Receive an amount of data in blocking mode \r
457   * @param  hspi: SPI handle\r
458   * @param  pData: pointer to data buffer\r
459   * @param  Size: amount of data to be sent\r
460   * @param  Timeout: Timeout duration\r
461   * @retval HAL status\r
462   */\r
463 HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)\r
464 {\r
465   __IO uint16_t tmpreg = 0;\r
466   (void)tmpreg;\r
467   uint32_t tmp = 0;\r
468 \r
469   if(hspi->State == HAL_SPI_STATE_READY)\r
470   {\r
471     if((pData == NULL ) || (Size == 0)) \r
472     {\r
473       return  HAL_ERROR;\r
474     }\r
475 \r
476     /* Process Locked */\r
477     __HAL_LOCK(hspi);\r
478 \r
479     /* Configure communication */\r
480     hspi->State       = HAL_SPI_STATE_BUSY_RX;\r
481     hspi->ErrorCode   = HAL_SPI_ERROR_NONE;\r
482 \r
483     hspi->pRxBuffPtr  = pData;\r
484     hspi->RxXferSize  = Size;\r
485     hspi->RxXferCount = Size;\r
486 \r
487     /*Init field not used in handle to zero */\r
488     hspi->RxISR = 0;\r
489     hspi->TxISR = 0;\r
490     hspi->TxXferSize   = 0;\r
491     hspi->TxXferCount  = 0;\r
492 \r
493     /* Configure communication direction : 1Line */\r
494     if(hspi->Init.Direction == SPI_DIRECTION_1LINE)\r
495     {\r
496       __HAL_SPI_1LINE_RX(hspi);\r
497     }\r
498 \r
499     /* Reset CRC Calculation */\r
500     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
501     {\r
502       __HAL_SPI_RESET_CRC(hspi);\r
503     }\r
504     \r
505     if((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))\r
506     {\r
507       /* Process Unlocked */\r
508       __HAL_UNLOCK(hspi);\r
509 \r
510       /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */\r
511       return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout);\r
512     }\r
513 \r
514     /* Check if the SPI is already enabled */ \r
515     if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)\r
516     {\r
517       /* Enable SPI peripheral */\r
518       __HAL_SPI_ENABLE(hspi);\r
519     }\r
520 \r
521     /* Receive data in 8 Bit mode */\r
522     if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)\r
523     {\r
524       while(hspi->RxXferCount > 1)\r
525       {\r
526         /* Wait until RXNE flag is set */\r
527         if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
528         { \r
529           return HAL_TIMEOUT;\r
530         }\r
531 \r
532         (*hspi->pRxBuffPtr++) = hspi->Instance->DR;\r
533         hspi->RxXferCount--;\r
534       }\r
535       /* Enable CRC Transmission */\r
536       if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED) \r
537       {\r
538         hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;\r
539       }\r
540     }\r
541     /* Receive data in 16 Bit mode */\r
542     else\r
543     {\r
544       while(hspi->RxXferCount > 1)\r
545       {\r
546         /* Wait until RXNE flag is set to read data */\r
547         if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
548         { \r
549           return HAL_TIMEOUT;\r
550         }\r
551 \r
552         *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;\r
553         hspi->pRxBuffPtr+=2;\r
554         hspi->RxXferCount--;\r
555       }\r
556       /* Enable CRC Transmission */\r
557       if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED) \r
558       {\r
559         hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;\r
560       }\r
561     }\r
562 \r
563     /* Wait until RXNE flag is set */\r
564     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
565     { \r
566       return HAL_TIMEOUT;\r
567     }\r
568 \r
569     /* Receive last data in 8 Bit mode */\r
570     if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)\r
571     {\r
572       (*hspi->pRxBuffPtr++) = hspi->Instance->DR;\r
573     }\r
574     /* Receive last data in 16 Bit mode */\r
575     else\r
576     {\r
577       *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;\r
578       hspi->pRxBuffPtr+=2;\r
579     }\r
580     hspi->RxXferCount--;\r
581 \r
582     /* Wait until RXNE flag is set: CRC Received */\r
583     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
584     {\r
585       if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
586       {\r
587         hspi->ErrorCode |= HAL_SPI_ERROR_CRC;\r
588         return HAL_TIMEOUT;\r
589       }\r
590 \r
591       /* Read CRC to Flush RXNE flag */\r
592       tmpreg = hspi->Instance->DR;\r
593     }\r
594     \r
595     if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))\r
596     {\r
597       /* Disable SPI peripheral */\r
598       __HAL_SPI_DISABLE(hspi);\r
599     }\r
600 \r
601     hspi->State = HAL_SPI_STATE_READY;\r
602 \r
603     tmp = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR);\r
604     /* Check if CRC error occurred */\r
605     if((hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED) && (tmp != RESET))\r
606     {  \r
607       hspi->ErrorCode |= HAL_SPI_ERROR_CRC;\r
608 \r
609       /* Reset CRC Calculation */\r
610       __HAL_SPI_RESET_CRC(hspi);\r
611 \r
612       /* Process Unlocked */\r
613       __HAL_UNLOCK(hspi);\r
614 \r
615       return HAL_ERROR; \r
616     }\r
617 \r
618     /* Process Unlocked */\r
619     __HAL_UNLOCK(hspi);\r
620 \r
621     return HAL_OK;\r
622   }\r
623   else\r
624   {\r
625     return HAL_BUSY;\r
626   }\r
627 }\r
628 \r
629 /**\r
630   * @brief  Transmit and Receive an amount of data in blocking mode \r
631   * @param  hspi: SPI handle\r
632   * @param  pTxData: pointer to transmission data buffer\r
633   * @param  pRxData: pointer to reception data buffer to be\r
634   * @param  Size: amount of data to be sent\r
635   * @param  Timeout: Timeout duration\r
636   * @retval HAL status\r
637   */\r
638 HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)\r
639 {\r
640   __IO uint16_t tmpreg = 0;\r
641   (void)tmpreg;\r
642   uint32_t tmp = 0;\r
643   \r
644   tmp = hspi->State; \r
645   if((tmp == HAL_SPI_STATE_READY) || (tmp == HAL_SPI_STATE_BUSY_RX))\r
646   {\r
647     if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))\r
648     {\r
649       return  HAL_ERROR;\r
650     }\r
651 \r
652     /* Check the parameters */\r
653     assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));\r
654 \r
655     /* Process Locked */\r
656     __HAL_LOCK(hspi);\r
657  \r
658     /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */\r
659     if(hspi->State == HAL_SPI_STATE_READY)\r
660     {\r
661       hspi->State = HAL_SPI_STATE_BUSY_TX_RX;\r
662     }\r
663 \r
664      /* Configure communication */   \r
665     hspi->ErrorCode   = HAL_SPI_ERROR_NONE;\r
666 \r
667     hspi->pRxBuffPtr  = pRxData;\r
668     hspi->RxXferSize  = Size;\r
669     hspi->RxXferCount = Size;  \r
670     \r
671     hspi->pTxBuffPtr  = pTxData;\r
672     hspi->TxXferSize  = Size; \r
673     hspi->TxXferCount = Size;\r
674 \r
675     /*Init field not used in handle to zero */\r
676     hspi->RxISR = 0;\r
677     hspi->TxISR = 0;\r
678 \r
679     /* Reset CRC Calculation */\r
680     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
681     {\r
682       __HAL_SPI_RESET_CRC(hspi);\r
683     }\r
684 \r
685     /* Check if the SPI is already enabled */ \r
686     if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)\r
687     {\r
688       /* Enable SPI peripheral */\r
689       __HAL_SPI_ENABLE(hspi);\r
690     }\r
691 \r
692     /* Transmit and Receive data in 16 Bit mode */\r
693     if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)\r
694     {\r
695       hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);\r
696       hspi->pTxBuffPtr+=2;\r
697       hspi->TxXferCount--;\r
698 \r
699       if(hspi->TxXferCount == 0)\r
700       {\r
701         /* Enable CRC Transmission */\r
702         if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
703         {\r
704           hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;\r
705         }\r
706 \r
707         /* Wait until RXNE flag is set */\r
708         if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
709         { \r
710           return HAL_TIMEOUT;\r
711         }\r
712 \r
713         *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;\r
714         hspi->pRxBuffPtr+=2;\r
715         hspi->RxXferCount--;\r
716       }\r
717       else\r
718       {\r
719         while(hspi->TxXferCount > 0)\r
720         {\r
721           /* Wait until TXE flag is set to send data */\r
722           if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)\r
723           { \r
724             return HAL_TIMEOUT;\r
725           }\r
726 \r
727           hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);\r
728           hspi->pTxBuffPtr+=2;\r
729           hspi->TxXferCount--;\r
730 \r
731           /* Enable CRC Transmission */\r
732           if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED))\r
733           {\r
734             hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;\r
735           }\r
736 \r
737           /* Wait until RXNE flag is set */\r
738           if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
739           { \r
740             return HAL_TIMEOUT;\r
741           }\r
742 \r
743           *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;\r
744           hspi->pRxBuffPtr+=2;\r
745           hspi->RxXferCount--;\r
746         }\r
747 \r
748         /* Wait until RXNE flag is set */\r
749         if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
750         {\r
751           return HAL_TIMEOUT;\r
752         }\r
753 \r
754         *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;\r
755         hspi->pRxBuffPtr+=2;\r
756         hspi->RxXferCount--;\r
757       }\r
758     }\r
759     /* Transmit and Receive data in 8 Bit mode */\r
760     else\r
761     {\r
762 \r
763       hspi->Instance->DR = (*hspi->pTxBuffPtr++);\r
764       hspi->TxXferCount--;\r
765 \r
766       if(hspi->TxXferCount == 0)\r
767       {\r
768         /* Enable CRC Transmission */\r
769         if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
770         {\r
771           hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;\r
772         }\r
773 \r
774         /* Wait until RXNE flag is set */\r
775         if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
776         {\r
777           return HAL_TIMEOUT;\r
778         }\r
779 \r
780         (*hspi->pRxBuffPtr) = hspi->Instance->DR;\r
781         hspi->RxXferCount--;\r
782       }\r
783       else\r
784       {\r
785         while(hspi->TxXferCount > 0)\r
786         {\r
787           /* Wait until TXE flag is set to send data */\r
788           if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, Timeout) != HAL_OK)\r
789           {\r
790             return HAL_TIMEOUT;\r
791           }\r
792 \r
793           hspi->Instance->DR = (*hspi->pTxBuffPtr++);\r
794           hspi->TxXferCount--;\r
795 \r
796           /* Enable CRC Transmission */\r
797           if((hspi->TxXferCount == 0) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED))\r
798           {\r
799             hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;\r
800           }\r
801 \r
802           /* Wait until RXNE flag is set */\r
803           if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
804           {\r
805             return HAL_TIMEOUT;\r
806           }\r
807 \r
808           (*hspi->pRxBuffPtr++) = hspi->Instance->DR;\r
809           hspi->RxXferCount--;\r
810         }\r
811 \r
812         /* Wait until RXNE flag is set */\r
813         if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
814         {\r
815           return HAL_TIMEOUT;\r
816         }\r
817 \r
818         (*hspi->pRxBuffPtr++) = hspi->Instance->DR;\r
819         hspi->RxXferCount--;\r
820       }\r
821     }\r
822 \r
823     /* Read CRC from DR to close CRC calculation process */\r
824     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
825     {\r
826       /* Wait until RXNE flag is set */\r
827       if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout) != HAL_OK)\r
828       {\r
829         hspi->ErrorCode |= HAL_SPI_ERROR_CRC;\r
830         return HAL_TIMEOUT;\r
831       }\r
832       /* Read CRC */\r
833       tmpreg = hspi->Instance->DR;\r
834     }\r
835 \r
836     /* Wait until Busy flag is reset before disabling SPI */\r
837     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, Timeout) != HAL_OK)\r
838     {\r
839       hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
840       return HAL_TIMEOUT;\r
841     }\r
842     \r
843     hspi->State = HAL_SPI_STATE_READY;\r
844 \r
845     tmp = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR);\r
846     /* Check if CRC error occurred */\r
847     if((hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED) && (tmp != RESET))\r
848     {\r
849       hspi->ErrorCode |= HAL_SPI_ERROR_CRC;\r
850 \r
851       /* Reset CRC Calculation */\r
852       if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
853       {\r
854         __HAL_SPI_RESET_CRC(hspi);\r
855       }\r
856 \r
857       /* Process Unlocked */\r
858       __HAL_UNLOCK(hspi);\r
859       \r
860       return HAL_ERROR; \r
861     }\r
862 \r
863     /* Process Unlocked */\r
864     __HAL_UNLOCK(hspi);\r
865 \r
866     return HAL_OK;\r
867   }\r
868   else\r
869   {\r
870     return HAL_BUSY;\r
871   }\r
872 }\r
873 \r
874 /**\r
875   * @brief  Transmit an amount of data in no-blocking mode with Interrupt\r
876   * @param  hspi: SPI handle\r
877   * @param  pData: pointer to data buffer\r
878   * @param  Size: amount of data to be sent\r
879   * @retval HAL status\r
880   */\r
881 HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)\r
882 {\r
883   if(hspi->State == HAL_SPI_STATE_READY)\r
884   {\r
885     if((pData == NULL) || (Size == 0))\r
886     {\r
887       return  HAL_ERROR;\r
888     }\r
889 \r
890     /* Check the parameters */\r
891     assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));\r
892 \r
893     /* Process Locked */\r
894     __HAL_LOCK(hspi);\r
895 \r
896     /* Configure communication */\r
897     hspi->State        = HAL_SPI_STATE_BUSY_TX;\r
898     hspi->ErrorCode    = HAL_SPI_ERROR_NONE;\r
899 \r
900     hspi->TxISR = &SPI_TxISR;\r
901     hspi->pTxBuffPtr   = pData;\r
902     hspi->TxXferSize   = Size;\r
903     hspi->TxXferCount  = Size;\r
904 \r
905     /*Init field not used in handle to zero */\r
906     hspi->RxISR = 0;\r
907     hspi->RxXferSize   = 0;\r
908     hspi->RxXferCount  = 0;\r
909 \r
910     /* Configure communication direction : 1Line */\r
911     if(hspi->Init.Direction == SPI_DIRECTION_1LINE)\r
912     {\r
913       __HAL_SPI_1LINE_TX(hspi);\r
914     }\r
915 \r
916     /* Reset CRC Calculation */\r
917     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
918     {\r
919       __HAL_SPI_RESET_CRC(hspi);\r
920     }\r
921 \r
922     if (hspi->Init.Direction == SPI_DIRECTION_2LINES)\r
923     {\r
924       __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE));\r
925     }else\r
926     {\r
927       /* Enable TXE and ERR interrupt */\r
928       __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));\r
929     }\r
930     /* Process Unlocked */\r
931     __HAL_UNLOCK(hspi);\r
932 \r
933     /* Check if the SPI is already enabled */ \r
934     if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)\r
935     {\r
936       /* Enable SPI peripheral */\r
937       __HAL_SPI_ENABLE(hspi);\r
938     }\r
939 \r
940     return HAL_OK;\r
941   }\r
942   else\r
943   {\r
944     return HAL_BUSY;\r
945   }\r
946 }\r
947 \r
948 /**\r
949   * @brief  Receive an amount of data in no-blocking mode with Interrupt\r
950   * @param  hspi: SPI handle\r
951   * @param  pData: pointer to data buffer\r
952   * @param  Size: amount of data to be sent\r
953   * @retval HAL status\r
954   */\r
955 HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)\r
956 {\r
957   if(hspi->State == HAL_SPI_STATE_READY)\r
958   {\r
959     if((pData == NULL) || (Size == 0)) \r
960     {\r
961       return  HAL_ERROR;\r
962     }\r
963 \r
964     /* Process Locked */\r
965     __HAL_LOCK(hspi);\r
966 \r
967     /* Configure communication */\r
968     hspi->State        = HAL_SPI_STATE_BUSY_RX;\r
969     hspi->ErrorCode    = HAL_SPI_ERROR_NONE;\r
970 \r
971     hspi->RxISR = &SPI_RxISR;\r
972     hspi->pRxBuffPtr   = pData;\r
973     hspi->RxXferSize   = Size;\r
974     hspi->RxXferCount  = Size ; \r
975 \r
976    /*Init field not used in handle to zero */\r
977     hspi->TxISR = 0;\r
978     hspi->TxXferSize   = 0;\r
979     hspi->TxXferCount  = 0;\r
980 \r
981     /* Configure communication direction : 1Line */\r
982     if(hspi->Init.Direction == SPI_DIRECTION_1LINE)\r
983     {\r
984        __HAL_SPI_1LINE_RX(hspi);\r
985     }\r
986     else if((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))\r
987     {\r
988        /* Process Unlocked */\r
989        __HAL_UNLOCK(hspi);\r
990 \r
991        /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */\r
992        return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size);\r
993     }\r
994 \r
995     /* Reset CRC Calculation */\r
996     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
997     {\r
998       __HAL_SPI_RESET_CRC(hspi);\r
999     }\r
1000 \r
1001     /* Enable TXE and ERR interrupt */\r
1002     __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));\r
1003 \r
1004     /* Process Unlocked */\r
1005     __HAL_UNLOCK(hspi);\r
1006 \r
1007     /* Note : The SPI must be enabled after unlocking current process \r
1008               to avoid the risk of SPI interrupt handle execution before current\r
1009               process unlock */\r
1010 \r
1011         /* Check if the SPI is already enabled */ \r
1012     if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)\r
1013     {\r
1014       /* Enable SPI peripheral */\r
1015       __HAL_SPI_ENABLE(hspi);\r
1016     }\r
1017 \r
1018     return HAL_OK;\r
1019   }\r
1020   else\r
1021   {\r
1022     return HAL_BUSY; \r
1023   }\r
1024 }\r
1025 \r
1026 /**\r
1027   * @brief  Transmit and Receive an amount of data in no-blocking mode with Interrupt \r
1028   * @param  hspi: SPI handle\r
1029   * @param  pTxData: pointer to transmission data buffer\r
1030   * @param  pRxData: pointer to reception data buffer to be\r
1031   * @param  Size: amount of data to be sent\r
1032   * @retval HAL status\r
1033   */\r
1034 HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)\r
1035 {\r
1036  uint32_t tmp = 0;\r
1037 \r
1038  tmp = hspi->State;\r
1039  if((tmp == HAL_SPI_STATE_READY) || (tmp == HAL_SPI_STATE_BUSY_RX))\r
1040   {\r
1041     if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0)) \r
1042     {\r
1043       return  HAL_ERROR;\r
1044     }\r
1045 \r
1046     /* Check the parameters */\r
1047     assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));\r
1048 \r
1049     /* Process locked */\r
1050     __HAL_LOCK(hspi);\r
1051 \r
1052     /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */\r
1053     if(hspi->State == HAL_SPI_STATE_READY)\r
1054     {\r
1055       hspi->State = HAL_SPI_STATE_BUSY_TX_RX;\r
1056     }\r
1057 \r
1058     /* Configure communication */\r
1059     hspi->ErrorCode    = HAL_SPI_ERROR_NONE;\r
1060 \r
1061     hspi->TxISR = &SPI_TxISR;\r
1062     hspi->pTxBuffPtr   = pTxData;\r
1063     hspi->TxXferSize   = Size;\r
1064     hspi->TxXferCount  = Size;\r
1065 \r
1066     hspi->RxISR = &SPI_2LinesRxISR;\r
1067     hspi->pRxBuffPtr   = pRxData;\r
1068     hspi->RxXferSize   = Size;\r
1069     hspi->RxXferCount  = Size;\r
1070 \r
1071     /* Reset CRC Calculation */\r
1072     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
1073     {\r
1074       __HAL_SPI_RESET_CRC(hspi);\r
1075     }\r
1076 \r
1077     /* Enable TXE, RXNE and ERR interrupt */\r
1078     __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));\r
1079 \r
1080     /* Process Unlocked */\r
1081     __HAL_UNLOCK(hspi);\r
1082 \r
1083     /* Check if the SPI is already enabled */ \r
1084     if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)\r
1085     {\r
1086       /* Enable SPI peripheral */\r
1087       __HAL_SPI_ENABLE(hspi);\r
1088     }\r
1089 \r
1090     return HAL_OK;\r
1091   }\r
1092   else\r
1093   {\r
1094     return HAL_BUSY; \r
1095   }\r
1096 }\r
1097 \r
1098 /**\r
1099   * @brief  Transmit an amount of data in no-blocking mode with DMA\r
1100   * @param  hspi: SPI handle\r
1101   * @param  pData: pointer to data buffer\r
1102   * @param  Size: amount of data to be sent\r
1103   * @retval HAL status\r
1104   */\r
1105 HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)\r
1106 {\r
1107   if(hspi->State == HAL_SPI_STATE_READY)\r
1108   {\r
1109     if((pData == NULL) || (Size == 0))\r
1110     {\r
1111       return  HAL_ERROR;\r
1112     }\r
1113 \r
1114     /* Check the parameters */\r
1115     assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));\r
1116 \r
1117     /* Process Locked */\r
1118     __HAL_LOCK(hspi);\r
1119 \r
1120     /* Configure communication */\r
1121     hspi->State       = HAL_SPI_STATE_BUSY_TX;\r
1122     hspi->ErrorCode   = HAL_SPI_ERROR_NONE;\r
1123 \r
1124     hspi->pTxBuffPtr  = pData;\r
1125     hspi->TxXferSize  = Size;\r
1126     hspi->TxXferCount = Size;\r
1127 \r
1128     /*Init field not used in handle to zero */\r
1129     hspi->TxISR = 0;\r
1130     hspi->RxISR = 0;\r
1131     hspi->RxXferSize   = 0;\r
1132     hspi->RxXferCount  = 0;\r
1133 \r
1134     /* Configure communication direction : 1Line */\r
1135     if(hspi->Init.Direction == SPI_DIRECTION_1LINE)\r
1136     {\r
1137       __HAL_SPI_1LINE_TX(hspi);\r
1138     }\r
1139 \r
1140     /* Reset CRC Calculation */\r
1141     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
1142     {\r
1143       __HAL_SPI_RESET_CRC(hspi);\r
1144     }\r
1145 \r
1146     /* Set the SPI TxDMA transfer complete callback */\r
1147     hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;\r
1148 \r
1149     /* Set the DMA error callback */\r
1150     hspi->hdmatx->XferErrorCallback = SPI_DMAError;\r
1151 \r
1152     /* Enable the Tx DMA Stream */\r
1153     HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);\r
1154 \r
1155     /* Enable Tx DMA Request */\r
1156     hspi->Instance->CR2 |= SPI_CR2_TXDMAEN;\r
1157 \r
1158     /* Process Unlocked */\r
1159     __HAL_UNLOCK(hspi);\r
1160 \r
1161     /* Check if the SPI is already enabled */ \r
1162     if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)\r
1163     {\r
1164       /* Enable SPI peripheral */\r
1165       __HAL_SPI_ENABLE(hspi);\r
1166     }\r
1167 \r
1168     return HAL_OK;\r
1169   }\r
1170   else\r
1171   {\r
1172     return HAL_BUSY;\r
1173   }\r
1174 }\r
1175 \r
1176 /**\r
1177   * @brief  Receive an amount of data in no-blocking mode with DMA \r
1178   * @param  hspi: SPI handle\r
1179   * @param  pData: pointer to data buffer\r
1180   * @note  When the CRC feature is enabled the pData Length must be Size + 1. \r
1181   * @param  Size: amount of data to be sent\r
1182   * @retval HAL status\r
1183   */\r
1184 HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)\r
1185 {\r
1186   if(hspi->State == HAL_SPI_STATE_READY)\r
1187   {\r
1188     if((pData == NULL) || (Size == 0))\r
1189     {\r
1190       return  HAL_ERROR;\r
1191     }\r
1192 \r
1193     /* Process Locked */\r
1194     __HAL_LOCK(hspi);\r
1195 \r
1196     /* Configure communication */\r
1197     hspi->State       = HAL_SPI_STATE_BUSY_RX;\r
1198     hspi->ErrorCode   = HAL_SPI_ERROR_NONE;\r
1199 \r
1200     hspi->pRxBuffPtr  = pData;\r
1201     hspi->RxXferSize  = Size;\r
1202     hspi->RxXferCount = Size;\r
1203 \r
1204     /*Init field not used in handle to zero */\r
1205     hspi->RxISR = 0;\r
1206     hspi->TxISR = 0;\r
1207     hspi->TxXferSize   = 0;\r
1208     hspi->TxXferCount  = 0;\r
1209 \r
1210     /* Configure communication direction : 1Line */\r
1211     if(hspi->Init.Direction == SPI_DIRECTION_1LINE)\r
1212     {\r
1213        __HAL_SPI_1LINE_RX(hspi);\r
1214     }\r
1215     else if((hspi->Init.Direction == SPI_DIRECTION_2LINES)&&(hspi->Init.Mode == SPI_MODE_MASTER))\r
1216     {\r
1217        /* Process Unlocked */\r
1218        __HAL_UNLOCK(hspi);\r
1219 \r
1220        /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */\r
1221        return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size);\r
1222     }\r
1223 \r
1224     /* Reset CRC Calculation */\r
1225     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
1226     {\r
1227       __HAL_SPI_RESET_CRC(hspi);\r
1228     }\r
1229 \r
1230     /* Set the SPI Rx DMA transfer complete callback */\r
1231     hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;\r
1232 \r
1233     /* Set the DMA error callback */\r
1234     hspi->hdmarx->XferErrorCallback = SPI_DMAError;\r
1235 \r
1236     /* Enable the Rx DMA Stream */\r
1237     HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);\r
1238 \r
1239     /* Enable Rx DMA Request */  \r
1240     hspi->Instance->CR2 |= SPI_CR2_RXDMAEN;  \r
1241 \r
1242     /* Process Unlocked */\r
1243     __HAL_UNLOCK(hspi);\r
1244 \r
1245     /* Check if the SPI is already enabled */ \r
1246     if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)\r
1247     {\r
1248       /* Enable SPI peripheral */\r
1249       __HAL_SPI_ENABLE(hspi);\r
1250     }\r
1251 \r
1252     return HAL_OK;\r
1253   }\r
1254   else\r
1255   {\r
1256     return HAL_BUSY;\r
1257   }\r
1258 }\r
1259 \r
1260 /**\r
1261   * @brief  Transmit and Receive an amount of data in no-blocking mode with DMA \r
1262   * @param  hspi: SPI handle\r
1263   * @param  pTxData: pointer to transmission data buffer\r
1264   * @param  pRxData: pointer to reception data buffer\r
1265   * @note  When the CRC feature is enabled the pRxData Length must be Size + 1 \r
1266   * @param  Size: amount of data to be sent\r
1267   * @retval HAL status\r
1268   */\r
1269 HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)\r
1270 {\r
1271   uint32_t tmpstate = 0;\r
1272   tmpstate = hspi->State;\r
1273   if((tmpstate == HAL_SPI_STATE_READY) || (tmpstate == HAL_SPI_STATE_BUSY_RX))\r
1274   {\r
1275     if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))\r
1276     {\r
1277       return  HAL_ERROR;\r
1278     }\r
1279 \r
1280     /* Check the parameters */\r
1281     assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));\r
1282     \r
1283     /* Process locked */\r
1284     __HAL_LOCK(hspi);\r
1285 \r
1286     /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */\r
1287     if(hspi->State == HAL_SPI_STATE_READY)\r
1288     {\r
1289       hspi->State = HAL_SPI_STATE_BUSY_TX_RX;\r
1290     }\r
1291 \r
1292     /* Configure communication */\r
1293     hspi->ErrorCode   = HAL_SPI_ERROR_NONE;\r
1294 \r
1295     hspi->pTxBuffPtr  = (uint8_t*)pTxData;\r
1296     hspi->TxXferSize  = Size;\r
1297     hspi->TxXferCount = Size;\r
1298 \r
1299     hspi->pRxBuffPtr  = (uint8_t*)pRxData;\r
1300     hspi->RxXferSize  = Size;\r
1301     hspi->RxXferCount = Size;\r
1302 \r
1303     /*Init field not used in handle to zero */\r
1304     hspi->RxISR = 0;\r
1305     hspi->TxISR = 0;\r
1306 \r
1307     /* Reset CRC Calculation */\r
1308     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
1309     {\r
1310       __HAL_SPI_RESET_CRC(hspi);\r
1311     }\r
1312 \r
1313     /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */\r
1314     if(hspi->State == HAL_SPI_STATE_BUSY_RX)\r
1315     {\r
1316       hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;\r
1317     }\r
1318     else\r
1319     {\r
1320       hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;\r
1321     }\r
1322 \r
1323     /* Set the DMA error callback */\r
1324     hspi->hdmarx->XferErrorCallback = SPI_DMAError;\r
1325 \r
1326     /* Enable the Rx DMA Stream */\r
1327     HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);\r
1328 \r
1329     /* Enable Rx DMA Request */  \r
1330     hspi->Instance->CR2 |= SPI_CR2_RXDMAEN;\r
1331 \r
1332     /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing\r
1333     is performed in DMA reception complete callback  */\r
1334     hspi->hdmatx->XferCpltCallback = NULL;\r
1335 \r
1336     /* Set the DMA error callback */\r
1337     hspi->hdmatx->XferErrorCallback = SPI_DMAError;\r
1338 \r
1339     /* Enable the Tx DMA Stream */\r
1340     HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);\r
1341 \r
1342     /* Enable Tx DMA Request */  \r
1343     hspi->Instance->CR2 |= SPI_CR2_TXDMAEN;\r
1344 \r
1345     /* Process Unlocked */\r
1346     __HAL_UNLOCK(hspi);\r
1347 \r
1348         /* Check if the SPI is already enabled */ \r
1349     if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)\r
1350     {\r
1351       /* Enable SPI peripheral */\r
1352       __HAL_SPI_ENABLE(hspi);\r
1353     }\r
1354 \r
1355     return HAL_OK;\r
1356   }\r
1357   else\r
1358   {\r
1359     return HAL_BUSY;\r
1360   }\r
1361 }\r
1362 \r
1363 /**\r
1364   * @brief  This function handles SPI interrupt request.\r
1365   * @param  hspi: SPI handle\r
1366   * @retval HAL status\r
1367   */\r
1368 void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)\r
1369 {\r
1370   uint32_t tmp1 = 0, tmp2 = 0, tmp3 = 0;\r
1371 \r
1372   tmp1 = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE);\r
1373   tmp2 = __HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_RXNE);\r
1374   tmp3 = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR);\r
1375   /* SPI in mode Receiver and Overrun not occurred ---------------------------*/\r
1376   if((tmp1 != RESET) && (tmp2 != RESET) && (tmp3 == RESET))\r
1377   {\r
1378     hspi->RxISR(hspi);\r
1379     return;\r
1380   } \r
1381 \r
1382   tmp1 = __HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE);\r
1383   tmp2 = __HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_TXE);\r
1384   /* SPI in mode Tramitter ---------------------------------------------------*/\r
1385   if((tmp1 != RESET) && (tmp2 != RESET))\r
1386   {\r
1387     hspi->TxISR(hspi);\r
1388     return;\r
1389   }\r
1390 \r
1391   if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_ERR) != RESET)\r
1392   {\r
1393     /* SPI CRC error interrupt occured ---------------------------------------*/\r
1394     if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)\r
1395     {\r
1396       hspi->ErrorCode |= HAL_SPI_ERROR_CRC;\r
1397       __HAL_SPI_CLEAR_CRCERRFLAG(hspi);\r
1398     }\r
1399     /* SPI Mode Fault error interrupt occured --------------------------------*/\r
1400     if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_MODF) != RESET)\r
1401     {\r
1402       hspi->ErrorCode |= HAL_SPI_ERROR_MODF;\r
1403       __HAL_SPI_CLEAR_MODFFLAG(hspi);\r
1404     }\r
1405     \r
1406     /* SPI Overrun error interrupt occured -----------------------------------*/\r
1407     if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_OVR) != RESET)\r
1408     {\r
1409       if(hspi->State != HAL_SPI_STATE_BUSY_TX)\r
1410       {\r
1411         hspi->ErrorCode |= HAL_SPI_ERROR_OVR;\r
1412         __HAL_SPI_CLEAR_OVRFLAG(hspi);      \r
1413       }\r
1414     }\r
1415 \r
1416     /* SPI Frame error interrupt occured -------------------------------------*/\r
1417     if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_FRE) != RESET)\r
1418     {\r
1419       hspi->ErrorCode |= HAL_SPI_ERROR_FRE;\r
1420       __HAL_SPI_CLEAR_FREFLAG(hspi);\r
1421     }\r
1422 \r
1423     /* Call the Error call Back in case of Errors */\r
1424     if(hspi->ErrorCode!=HAL_SPI_ERROR_NONE)\r
1425     {\r
1426       hspi->State = HAL_SPI_STATE_READY;\r
1427       HAL_SPI_ErrorCallback(hspi);\r
1428     }\r
1429   }\r
1430 }\r
1431 \r
1432 /**\r
1433   * @brief Tx Transfer completed callbacks\r
1434   * @param hspi: SPI handle\r
1435   * @retval None\r
1436   */\r
1437 __weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)\r
1438 {\r
1439   /* NOTE : This function Should not be modified, when the callback is needed,\r
1440             the HAL_SPI_TxCpltCallback could be implenetd in the user file\r
1441    */\r
1442 }\r
1443 \r
1444 /**\r
1445   * @brief Rx Transfer completed callbacks\r
1446   * @param hspi: SPI handle\r
1447   * @retval None\r
1448   */\r
1449 __weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)\r
1450 {\r
1451   /* NOTE : This function Should not be modified, when the callback is needed,\r
1452             the HAL_SPI_RxCpltCallback() could be implenetd in the user file\r
1453    */\r
1454 }\r
1455 \r
1456 /**\r
1457   * @brief Tx and Rx Transfer completed callbacks\r
1458   * @param hspi: SPI handle\r
1459   * @retval None\r
1460   */\r
1461 __weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)\r
1462 {\r
1463   /* NOTE : This function Should not be modified, when the callback is needed,\r
1464             the HAL_SPI_TxRxCpltCallback() could be implenetd in the user file\r
1465    */\r
1466 }\r
1467 \r
1468 /**\r
1469   * @brief SPI error callbacks\r
1470   * @param hspi: SPI handle\r
1471   * @retval None\r
1472   */\r
1473  __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)\r
1474 {\r
1475   /* NOTE : - This function Should not be modified, when the callback is needed,\r
1476             the HAL_SPI_ErrorCallback() could be implenetd in the user file.\r
1477             - The ErrorCode parameter in the hspi handle is updated by the SPI processes\r
1478             and user can use HAL_SPI_GetError() API to check the latest error occured.\r
1479    */\r
1480 }\r
1481 \r
1482 /**\r
1483   * @}\r
1484   */\r
1485 \r
1486 /** @defgroup SPI_Group3 Peripheral State and Errors functions \r
1487   *  @brief   SPI control functions \r
1488   *\r
1489 @verbatim\r
1490  ===============================================================================\r
1491                       ##### Peripheral State and Errors functions #####\r
1492  ===============================================================================  \r
1493     [..]\r
1494     This subsection provides a set of functions allowing to control the SPI.\r
1495      (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral\r
1496      (+) HAL_SPI_GetError() check in run-time Errors occurring during communication\r
1497 @endverbatim\r
1498   * @{\r
1499   */\r
1500 \r
1501 /**\r
1502   * @brief  Return the SPI state\r
1503   * @param  hspi : SPI handle\r
1504   * @retval SPI state\r
1505   */\r
1506 HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi)\r
1507 {\r
1508   return hspi->State;\r
1509 }\r
1510 \r
1511 /**\r
1512   * @brief  Return the SPI error code\r
1513   * @param  hspi : SPI handle\r
1514   * @retval SPI Error Code\r
1515   */\r
1516 HAL_SPI_ErrorTypeDef HAL_SPI_GetError(SPI_HandleTypeDef *hspi)\r
1517 {\r
1518   return hspi->ErrorCode;\r
1519 }\r
1520 \r
1521 /**\r
1522   * @}\r
1523   */\r
1524 \r
1525   /**\r
1526   * @brief  Interrupt Handler to close Tx transfer \r
1527   * @param  hspi: SPI handle\r
1528   * @retval void\r
1529   */\r
1530 static void SPI_TxCloseIRQHandler(SPI_HandleTypeDef *hspi)\r
1531 {\r
1532   /* Wait until TXE flag is set to send data */\r
1533   if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1534   {\r
1535     hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1536   }\r
1537 \r
1538   /* Disable TXE interrupt */\r
1539   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE ));\r
1540 \r
1541   /* Disable ERR interrupt if Receive process is finished */\r
1542   if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_RXNE) == RESET)\r
1543   {\r
1544     __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_ERR));\r
1545 \r
1546     /* Wait until Busy flag is reset before disabling SPI */\r
1547     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1548     {\r
1549       hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1550     }\r
1551 \r
1552     /* Clear OVERUN flag in 2 Lines communication mode because received is not read */\r
1553     if(hspi->Init.Direction == SPI_DIRECTION_2LINES)\r
1554     {\r
1555       __HAL_SPI_CLEAR_OVRFLAG(hspi);\r
1556     }\r
1557     \r
1558     /* Check if Errors has been detected during transfer */\r
1559     if(hspi->ErrorCode ==  HAL_SPI_ERROR_NONE)\r
1560     {\r
1561       /* Check if we are in Tx or in Rx/Tx Mode */\r
1562       if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX)\r
1563       {\r
1564         /* Set state to READY before run the Callback Complete */\r
1565         hspi->State = HAL_SPI_STATE_READY;\r
1566         HAL_SPI_TxRxCpltCallback(hspi);\r
1567       }\r
1568       else\r
1569       {\r
1570         /* Set state to READY before run the Callback Complete */\r
1571         hspi->State = HAL_SPI_STATE_READY;\r
1572         HAL_SPI_TxCpltCallback(hspi);\r
1573       }\r
1574     }\r
1575     else\r
1576     {\r
1577       /* Set state to READY before run the Callback Complete */\r
1578       hspi->State = HAL_SPI_STATE_READY;\r
1579       /* Call Error call back in case of Error */\r
1580       HAL_SPI_ErrorCallback(hspi);\r
1581     }\r
1582   }\r
1583 }\r
1584 \r
1585 /**\r
1586   * @brief  Interrupt Handler to transmit amount of data in no-blocking mode \r
1587   * @param  hspi: SPI handle\r
1588   * @retval void\r
1589   */\r
1590 static void SPI_TxISR(SPI_HandleTypeDef *hspi)\r
1591 {\r
1592   /* Transmit data in 8 Bit mode */\r
1593   if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)\r
1594   {\r
1595     hspi->Instance->DR = (*hspi->pTxBuffPtr++);\r
1596   }\r
1597   /* Transmit data in 16 Bit mode */\r
1598   else\r
1599   {\r
1600     hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);\r
1601     hspi->pTxBuffPtr+=2;\r
1602   }\r
1603   hspi->TxXferCount--;\r
1604 \r
1605   if(hspi->TxXferCount == 0)\r
1606   {\r
1607     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
1608     {\r
1609       /* calculate and transfer CRC on Tx line */\r
1610       hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;\r
1611     }\r
1612     SPI_TxCloseIRQHandler(hspi);\r
1613   }\r
1614 }\r
1615 \r
1616 /**\r
1617   * @brief  Interrupt Handler to close Rx transfer \r
1618   * @param  hspi: SPI handle\r
1619   * @retval void\r
1620   */\r
1621 static void SPI_RxCloseIRQHandler(SPI_HandleTypeDef *hspi)\r
1622 {\r
1623   __IO uint16_t tmpreg = 0;\r
1624   (void)tmpreg;\r
1625   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
1626   {\r
1627     /* Wait until RXNE flag is set to send data */\r
1628     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1629     {\r
1630       hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1631     }\r
1632 \r
1633     /* Read CRC to reset RXNE flag */\r
1634     tmpreg = hspi->Instance->DR;\r
1635 \r
1636     /* Wait until RXNE flag is set to send data */\r
1637     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1638     {\r
1639       hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1640     }\r
1641 \r
1642     /* Check if CRC error occurred */\r
1643     if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)\r
1644     {\r
1645       hspi->ErrorCode |= HAL_SPI_ERROR_CRC;\r
1646 \r
1647       /* Reset CRC Calculation */\r
1648       __HAL_SPI_RESET_CRC(hspi);\r
1649     }\r
1650   }\r
1651 \r
1652   /* Disable RXNE and ERR interrupt */\r
1653   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE));\r
1654 \r
1655   /* if Transmit process is finished */\r
1656   if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_TXE) == RESET)\r
1657   {\r
1658     /* Disable ERR interrupt */\r
1659     __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_ERR));\r
1660 \r
1661     if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))\r
1662     {\r
1663       /* Disable SPI peripheral */\r
1664       __HAL_SPI_DISABLE(hspi);\r
1665     }\r
1666     \r
1667     /* Check if Errors has been detected during transfer */\r
1668     if(hspi->ErrorCode ==  HAL_SPI_ERROR_NONE)\r
1669     {\r
1670       /* Check if we are in Rx or in Rx/Tx Mode */\r
1671       if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX)\r
1672       {\r
1673         /* Set state to READY before run the Callback Complete */\r
1674         hspi->State = HAL_SPI_STATE_READY;\r
1675         HAL_SPI_TxRxCpltCallback(hspi);\r
1676       }else\r
1677       {\r
1678         /* Set state to READY before run the Callback Complete */\r
1679         hspi->State = HAL_SPI_STATE_READY;\r
1680         HAL_SPI_RxCpltCallback(hspi);\r
1681       }\r
1682     }\r
1683     else\r
1684     {\r
1685       /* Set state to READY before run the Callback Complete */\r
1686       hspi->State = HAL_SPI_STATE_READY;\r
1687       /* Call Error call back in case of Error */\r
1688       HAL_SPI_ErrorCallback(hspi);\r
1689     }\r
1690   }\r
1691 }\r
1692 \r
1693 /**\r
1694   * @brief  Interrupt Handler to receive amount of data in 2Lines mode \r
1695   * @param  hspi: SPI handle\r
1696   * @retval void\r
1697   */\r
1698 static void SPI_2LinesRxISR(SPI_HandleTypeDef *hspi)\r
1699 {\r
1700   /* Receive data in 8 Bit mode */\r
1701   if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)\r
1702   {\r
1703     (*hspi->pRxBuffPtr++) = hspi->Instance->DR;\r
1704   }\r
1705   /* Receive data in 16 Bit mode */\r
1706   else\r
1707   {\r
1708     *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;\r
1709     hspi->pRxBuffPtr+=2;\r
1710   }\r
1711   hspi->RxXferCount--;\r
1712 \r
1713   if(hspi->RxXferCount==0)\r
1714   {\r
1715     SPI_RxCloseIRQHandler(hspi);\r
1716   }\r
1717 }\r
1718 \r
1719 /**\r
1720   * @brief  Interrupt Handler to receive amount of data in no-blocking mode \r
1721   * @param  hspi: SPI handle\r
1722   * @retval void\r
1723   */\r
1724 static void SPI_RxISR(SPI_HandleTypeDef *hspi)\r
1725 {\r
1726   /* Receive data in 8 Bit mode */\r
1727   if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)\r
1728   {\r
1729     (*hspi->pRxBuffPtr++) = hspi->Instance->DR;\r
1730   }\r
1731   /* Receive data in 16 Bit mode */\r
1732   else\r
1733   {\r
1734     *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;\r
1735     hspi->pRxBuffPtr+=2;\r
1736   }\r
1737     hspi->RxXferCount--;\r
1738 \r
1739   /* Enable CRC Transmission */\r
1740   if((hspi->RxXferCount == 1) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED))\r
1741   {\r
1742     /* Set CRC Next to calculate CRC on Rx side */\r
1743     hspi->Instance->CR1 |= SPI_CR1_CRCNEXT;  \r
1744   }\r
1745 \r
1746   if(hspi->RxXferCount == 0)\r
1747   {\r
1748     SPI_RxCloseIRQHandler(hspi);\r
1749   }\r
1750 }\r
1751 \r
1752 /**\r
1753   * @brief DMA SPI transmit process complete callback \r
1754   * @param hdma : DMA handle\r
1755   * @retval None\r
1756   */\r
1757 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)\r
1758 {\r
1759   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
1760 \r
1761   /* Wait until TXE flag is set to send data */\r
1762   if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1763   {\r
1764     hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1765   }\r
1766 \r
1767   /* Disable Tx DMA Request */\r
1768   hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);\r
1769 \r
1770   /* Wait until Busy flag is reset before disabling SPI */\r
1771   if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1772   {\r
1773     hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1774   }\r
1775 \r
1776   hspi->TxXferCount = 0;\r
1777 \r
1778   hspi->State = HAL_SPI_STATE_READY;\r
1779 \r
1780   /* Clear OVERUN flag in 2 Lines communication mode because received is not read */\r
1781   if(hspi->Init.Direction == SPI_DIRECTION_2LINES)\r
1782   {\r
1783     __HAL_SPI_CLEAR_OVRFLAG(hspi);\r
1784   }\r
1785 \r
1786   /* Check if Errors has been detected during transfer */\r
1787   if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)\r
1788   {\r
1789     HAL_SPI_ErrorCallback(hspi);\r
1790   }\r
1791   else\r
1792   {\r
1793     HAL_SPI_TxCpltCallback(hspi);\r
1794   }\r
1795 }\r
1796 \r
1797 /**\r
1798   * @brief DMA SPI receive process complete callback \r
1799   * @param hdma : DMA handle\r
1800   * @retval None\r
1801   */\r
1802 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)\r
1803 {\r
1804   __IO uint16_t tmpreg = 0;\r
1805   (void)tmpreg;\r
1806   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
1807 \r
1808   if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))\r
1809   {\r
1810     /* Disable SPI peripheral */\r
1811     __HAL_SPI_DISABLE(hspi);\r
1812   }\r
1813 \r
1814   /* Disable Rx DMA Request */\r
1815   hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);\r
1816 \r
1817   /* Reset CRC Calculation */\r
1818   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
1819   {\r
1820     /* Wait until RXNE flag is set to send data */\r
1821     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1822     {\r
1823       hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1824     }\r
1825 \r
1826     /* Read CRC */\r
1827     tmpreg = hspi->Instance->DR;\r
1828 \r
1829     /* Wait until RXNE flag is set to send data */\r
1830     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1831     {\r
1832       hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1833     }\r
1834   }\r
1835 \r
1836   hspi->RxXferCount = 0;\r
1837   hspi->State = HAL_SPI_STATE_READY;\r
1838 \r
1839   /* Check if CRC error occurred */\r
1840   if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)\r
1841   {\r
1842     hspi->ErrorCode |= HAL_SPI_ERROR_CRC;\r
1843     __HAL_SPI_CLEAR_CRCERRFLAG(hspi);\r
1844   }\r
1845 \r
1846   /* Check if Errors has been detected during transfer */\r
1847   if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)\r
1848   {\r
1849     HAL_SPI_ErrorCallback(hspi);\r
1850   }\r
1851   else\r
1852   {\r
1853     HAL_SPI_RxCpltCallback(hspi);\r
1854   }\r
1855 }\r
1856 \r
1857 /**\r
1858   * @brief DMA SPI transmit receive process complete callback \r
1859   * @param hdma : DMA handle\r
1860   * @retval None\r
1861   */\r
1862 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)   \r
1863 {\r
1864   __IO uint16_t tmpreg = 0;\r
1865   (void)tmpreg;\r
1866   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
1867 \r
1868   /* Reset CRC Calculation */\r
1869   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
1870   {\r
1871     /* Check if CRC is done on going (RXNE flag set) */\r
1872     if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) == HAL_OK)\r
1873     {\r
1874       /* Wait until RXNE flag is set to send data */\r
1875       if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1876       {\r
1877         hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1878       }\r
1879     }\r
1880     /* Read CRC */\r
1881     tmpreg = hspi->Instance->DR;\r
1882   }\r
1883 \r
1884   /* Wait until TXE flag is set to send data */\r
1885   if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1886   {\r
1887     hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1888   }\r
1889   /* Disable Tx DMA Request */\r
1890   hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);\r
1891 \r
1892   /* Wait until Busy flag is reset before disabling SPI */\r
1893   if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK)\r
1894   {\r
1895     hspi->ErrorCode |= HAL_SPI_ERROR_FLAG;\r
1896   }\r
1897 \r
1898   /* Disable Rx DMA Request */\r
1899   hspi->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);\r
1900 \r
1901   hspi->TxXferCount = 0;\r
1902   hspi->RxXferCount = 0;\r
1903 \r
1904   hspi->State = HAL_SPI_STATE_READY;\r
1905 \r
1906   /* Check if CRC error occurred */\r
1907   if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)\r
1908   {\r
1909     hspi->ErrorCode |= HAL_SPI_ERROR_CRC;\r
1910     __HAL_SPI_CLEAR_CRCERRFLAG(hspi);\r
1911   }\r
1912 \r
1913   /* Check if Errors has been detected during transfer */\r
1914   if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)\r
1915   {\r
1916     HAL_SPI_ErrorCallback(hspi);\r
1917   }\r
1918   else\r
1919   {\r
1920     HAL_SPI_TxRxCpltCallback(hspi);\r
1921   }\r
1922 }\r
1923 \r
1924 /**\r
1925   * @brief DMA SPI communication error callback \r
1926   * @param hdma : DMA handle\r
1927   * @retval None\r
1928   */\r
1929 static void SPI_DMAError(DMA_HandleTypeDef *hdma)\r
1930 {\r
1931   SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;\r
1932   hspi->TxXferCount = 0;\r
1933   hspi->RxXferCount = 0;\r
1934   hspi->State= HAL_SPI_STATE_READY;\r
1935   hspi->ErrorCode |= HAL_SPI_ERROR_DMA;\r
1936   HAL_SPI_ErrorCallback(hspi);\r
1937 }\r
1938 \r
1939 /**\r
1940   * @brief This function handles SPI Communication Timeout.\r
1941   * @param hspi: SPI handle\r
1942   * @retval HAL status\r
1943   */\r
1944 static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status, uint32_t Timeout)  \r
1945 {\r
1946   uint32_t timeout = 0;\r
1947 \r
1948   timeout = HAL_GetTick() + Timeout;\r
1949 \r
1950   /* Wait until flag is set */\r
1951   if(Status == RESET)\r
1952   {\r
1953     while(__HAL_SPI_GET_FLAG(hspi, Flag) == RESET)\r
1954     {\r
1955       if(Timeout != HAL_MAX_DELAY)\r
1956       {\r
1957         if(HAL_GetTick() >= timeout)\r
1958         {\r
1959           /* Disable the SPI and reset the CRC: the CRC value should be cleared\r
1960              on both master and slave sides in order to resynchronize the master\r
1961              and slave for their respective CRC calculation */\r
1962 \r
1963           /* Disable TXE, RXNE and ERR interrupts for the interrupt process */\r
1964           __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));\r
1965 \r
1966           /* Disable SPI peripheral */\r
1967           __HAL_SPI_DISABLE(hspi);\r
1968 \r
1969           /* Reset CRC Calculation */\r
1970           if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
1971           {\r
1972             __HAL_SPI_RESET_CRC(hspi);\r
1973           }\r
1974 \r
1975           hspi->State= HAL_SPI_STATE_READY;\r
1976 \r
1977           /* Process Unlocked */\r
1978           __HAL_UNLOCK(hspi);\r
1979 \r
1980           return HAL_TIMEOUT;\r
1981         }\r
1982       }\r
1983     }\r
1984   }\r
1985   else\r
1986   {\r
1987     while(__HAL_SPI_GET_FLAG(hspi, Flag) != RESET)\r
1988     {\r
1989       if(Timeout != HAL_MAX_DELAY)\r
1990       {\r
1991         if(HAL_GetTick() >= timeout)\r
1992         {\r
1993           /* Disable the SPI and reset the CRC: the CRC value should be cleared\r
1994              on both master and slave sides in order to resynchronize the master\r
1995              and slave for their respective CRC calculation */\r
1996 \r
1997           /* Disable TXE, RXNE and ERR interrupts for the interrupt process */\r
1998           __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));\r
1999 \r
2000           /* Disable SPI peripheral */\r
2001           __HAL_SPI_DISABLE(hspi);\r
2002 \r
2003           /* Reset CRC Calculation */\r
2004           if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)\r
2005           {\r
2006             __HAL_SPI_RESET_CRC(hspi);\r
2007           }\r
2008 \r
2009           hspi->State= HAL_SPI_STATE_READY;\r
2010 \r
2011           /* Process Unlocked */\r
2012           __HAL_UNLOCK(hspi);\r
2013 \r
2014           return HAL_TIMEOUT;\r
2015         }\r
2016       }\r
2017     }\r
2018   }\r
2019   return HAL_OK;\r
2020 }\r
2021 \r
2022 \r
2023 /**\r
2024   * @}\r
2025   */\r
2026 \r
2027 #endif /* HAL_SPI_MODULE_ENABLED */\r
2028 /**\r
2029   * @}\r
2030   */\r
2031 \r
2032 /**\r
2033   * @}\r
2034   */\r
2035 \r
2036 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r