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