STM32F103xB HAL User Manual
stm32f1xx_hal_spi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f1xx_hal_spi.c
00004   * @author  MCD Application Team
00005   * @brief   SPI HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the Serial Peripheral Interface (SPI) peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + IO operation functions
00010   *           + Peripheral Control functions
00011   *           + Peripheral State functions
00012   *
00013   @verbatim
00014   ==============================================================================
00015                         ##### How to use this driver #####
00016   ==============================================================================
00017     [..]
00018       The SPI HAL driver can be used as follows:
00019 
00020       (#) Declare a SPI_HandleTypeDef handle structure, for example:
00021           SPI_HandleTypeDef  hspi;
00022 
00023       (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
00024           (##) Enable the SPIx interface clock
00025           (##) SPI pins configuration
00026               (+++) Enable the clock for the SPI GPIOs
00027               (+++) Configure these SPI pins as alternate function push-pull
00028           (##) NVIC configuration if you need to use interrupt process
00029               (+++) Configure the SPIx interrupt priority
00030               (+++) Enable the NVIC SPI IRQ handle
00031           (##) DMA Configuration if you need to use DMA process
00032               (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Stream/Channel
00033               (+++) Enable the DMAx clock
00034               (+++) Configure the DMA handle parameters
00035               (+++) Configure the DMA Tx or Rx Stream/Channel
00036               (+++) Associate the initialized hdma_tx(or _rx)  handle to the hspi DMA Tx or Rx handle
00037               (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Stream/Channel
00038 
00039       (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
00040           management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.
00041 
00042       (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:
00043           (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00044               by calling the customized HAL_SPI_MspInit() API.
00045      [..]
00046        Circular mode restriction:
00047       (#) The DMA circular mode cannot be used when the SPI is configured in these modes:
00048           (##) Master 2Lines RxOnly
00049           (##) Master 1Line Rx
00050       (#) The CRC feature is not managed when the DMA circular mode is enabled
00051       (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs
00052           the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks
00053      [..]
00054        Master Receive mode restriction:
00055       (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=1) or
00056           bidirectional receive mode (MSTR=1, BIDIMODE=1, BIDIOE=0), to ensure that the SPI
00057           does not initiate a new transfer the following procedure has to be respected:
00058           (##) HAL_SPI_DeInit()
00059           (##) HAL_SPI_Init()
00060      [..]
00061        Callback registration:
00062 
00063       (#) The compilation flag USE_HAL_SPI_REGISTER_CALLBACKS when set to 1U
00064           allows the user to configure dynamically the driver callbacks.
00065           Use Functions HAL_SPI_RegisterCallback() to register an interrupt callback.
00066 
00067           Function HAL_SPI_RegisterCallback() allows to register following callbacks:
00068             (++) TxCpltCallback        : SPI Tx Completed callback
00069             (++) RxCpltCallback        : SPI Rx Completed callback
00070             (++) TxRxCpltCallback      : SPI TxRx Completed callback
00071             (++) TxHalfCpltCallback    : SPI Tx Half Completed callback
00072             (++) RxHalfCpltCallback    : SPI Rx Half Completed callback
00073             (++) TxRxHalfCpltCallback  : SPI TxRx Half Completed callback
00074             (++) ErrorCallback         : SPI Error callback
00075             (++) AbortCpltCallback     : SPI Abort callback
00076             (++) MspInitCallback       : SPI Msp Init callback
00077             (++) MspDeInitCallback     : SPI Msp DeInit callback
00078           This function takes as parameters the HAL peripheral handle, the Callback ID
00079           and a pointer to the user callback function.
00080 
00081 
00082       (#) Use function HAL_SPI_UnRegisterCallback to reset a callback to the default
00083           weak function.
00084           HAL_SPI_UnRegisterCallback takes as parameters the HAL peripheral handle,
00085           and the Callback ID.
00086           This function allows to reset following callbacks:
00087             (++) TxCpltCallback        : SPI Tx Completed callback
00088             (++) RxCpltCallback        : SPI Rx Completed callback
00089             (++) TxRxCpltCallback      : SPI TxRx Completed callback
00090             (++) TxHalfCpltCallback    : SPI Tx Half Completed callback
00091             (++) RxHalfCpltCallback    : SPI Rx Half Completed callback
00092             (++) TxRxHalfCpltCallback  : SPI TxRx Half Completed callback
00093             (++) ErrorCallback         : SPI Error callback
00094             (++) AbortCpltCallback     : SPI Abort callback
00095             (++) MspInitCallback       : SPI Msp Init callback
00096             (++) MspDeInitCallback     : SPI Msp DeInit callback
00097 
00098        [..]
00099        By default, after the HAL_SPI_Init() and when the state is HAL_SPI_STATE_RESET
00100        all callbacks are set to the corresponding weak functions:
00101        examples HAL_SPI_MasterTxCpltCallback(), HAL_SPI_MasterRxCpltCallback().
00102        Exception done for MspInit and MspDeInit functions that are
00103        reset to the legacy weak functions in the HAL_SPI_Init()/ HAL_SPI_DeInit() only when
00104        these callbacks are null (not registered beforehand).
00105        If MspInit or MspDeInit are not null, the HAL_SPI_Init()/ HAL_SPI_DeInit()
00106        keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
00107 
00108        [..]
00109        Callbacks can be registered/unregistered in HAL_SPI_STATE_READY state only.
00110        Exception done MspInit/MspDeInit functions that can be registered/unregistered
00111        in HAL_SPI_STATE_READY or HAL_SPI_STATE_RESET state,
00112        thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
00113        Then, the user first registers the MspInit/MspDeInit user callbacks
00114        using HAL_SPI_RegisterCallback() before calling HAL_SPI_DeInit()
00115        or HAL_SPI_Init() function.
00116 
00117        [..]
00118        When the compilation define USE_HAL_PPP_REGISTER_CALLBACKS is set to 0 or
00119        not defined, the callback registering feature is not available
00120        and weak (surcharged) callbacks are used.
00121 
00122      [..]
00123        Using the HAL it is not possible to reach all supported SPI frequency with the different SPI Modes,
00124        the following table resume the max SPI frequency reached with data size 8bits/16bits,
00125          according to frequency of the APBx Peripheral Clock (fPCLK) used by the SPI instance.
00126 
00127   @endverbatim
00128 
00129   Additional table :
00130 
00131        DataSize = SPI_DATASIZE_8BIT:
00132        +----------------------------------------------------------------------------------------------+
00133        |         |                | 2Lines Fullduplex   |     2Lines RxOnly    |         1Line        |
00134        | Process | Transfer mode  |---------------------|----------------------|----------------------|
00135        |         |                |  Master  |  Slave   |  Master   |  Slave   |  Master   |  Slave   |
00136        |==============================================================================================|
00137        |    T    |     Polling    | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
00138        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00139        |    /    |     Interrupt  | Fpclk/4  | Fpclk/8  |    NA     |    NA    |    NA     |   NA     |
00140        |    R    |----------------|----------|----------|-----------|----------|-----------|----------|
00141        |    X    |       DMA      | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
00142        |=========|================|==========|==========|===========|==========|===========|==========|
00143        |         |     Polling    | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/64  | Fpclk/2  |
00144        |         |----------------|----------|----------|-----------|----------|-----------|----------|
00145        |    R    |     Interrupt  | Fpclk/8  | Fpclk/8  | Fpclk/64  | Fpclk/2  | Fpclk/64  | Fpclk/2  |
00146        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00147        |         |       DMA      | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/128 | Fpclk/2  |
00148        |=========|================|==========|==========|===========|==========|===========|==========|
00149        |         |     Polling    | Fpclk/2  | Fpclk/4  |     NA    |    NA    | Fpclk/2   | Fpclk/64 |
00150        |         |----------------|----------|----------|-----------|----------|-----------|----------|
00151        |    T    |     Interrupt  | Fpclk/2  | Fpclk/4  |     NA    |    NA    | Fpclk/2   | Fpclk/64 |
00152        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00153        |         |       DMA      | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/128|
00154        +----------------------------------------------------------------------------------------------+
00155 
00156        DataSize = SPI_DATASIZE_16BIT:
00157        +----------------------------------------------------------------------------------------------+
00158        |         |                | 2Lines Fullduplex   |     2Lines RxOnly    |         1Line        |
00159        | Process | Transfer mode  |---------------------|----------------------|----------------------|
00160        |         |                |  Master  |  Slave   |  Master   |  Slave   |  Master   |  Slave   |
00161        |==============================================================================================|
00162        |    T    |     Polling    | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
00163        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00164        |    /    |     Interrupt  | Fpclk/4  | Fpclk/4  |    NA     |    NA    |    NA     |   NA     |
00165        |    R    |----------------|----------|----------|-----------|----------|-----------|----------|
00166        |    X    |       DMA      | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
00167        |=========|================|==========|==========|===========|==========|===========|==========|
00168        |         |     Polling    | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/32  | Fpclk/2  |
00169        |         |----------------|----------|----------|-----------|----------|-----------|----------|
00170        |    R    |     Interrupt  | Fpclk/4  | Fpclk/4  | Fpclk/64  | Fpclk/2  | Fpclk/64  | Fpclk/2  |
00171        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00172        |         |       DMA      | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/128 | Fpclk/2  |
00173        |=========|================|==========|==========|===========|==========|===========|==========|
00174        |         |     Polling    | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/32 |
00175        |         |----------------|----------|----------|-----------|----------|-----------|----------|
00176        |    T    |     Interrupt  | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/64 |
00177        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00178        |         |       DMA      | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/128|
00179        +----------------------------------------------------------------------------------------------+
00180        @note The max SPI frequency depend on SPI data size (8bits, 16bits),
00181              SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA).
00182        @note
00183             (#) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA()
00184             (#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA()
00185             (#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA()
00186 
00187   ******************************************************************************
00188   * @attention
00189   *
00190   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
00191   * All rights reserved.</center></h2>
00192   *
00193   * This software component is licensed by ST under BSD 3-Clause license,
00194   * the "License"; You may not use this file except in compliance with the
00195   * License. You may obtain a copy of the License at:
00196   *                        opensource.org/licenses/BSD-3-Clause
00197   *
00198   ******************************************************************************
00199   */
00200 
00201 /* Includes ------------------------------------------------------------------*/
00202 #include "stm32f1xx_hal.h"
00203 
00204 /** @addtogroup STM32F1xx_HAL_Driver
00205   * @{
00206   */
00207 
00208 /** @defgroup SPI SPI
00209   * @brief SPI HAL module driver
00210   * @{
00211   */
00212 #ifdef HAL_SPI_MODULE_ENABLED
00213 
00214 /* Private typedef -----------------------------------------------------------*/
00215 /* Private defines -----------------------------------------------------------*/
00216 #if (USE_SPI_CRC != 0U) && defined(SPI_CRC_ERROR_WORKAROUND_FEATURE)
00217 /* CRC WORKAOUND FEATURE: Variable used to determine if device is impacted by implementation
00218  * of workaround related to wrong CRC errors detection on SPI2. Conditions in which this workaround
00219  * has to be applied, are:
00220  *  - STM32F101CDE/STM32F103CDE
00221  *  - Revision ID : Z
00222  *  - SPI2
00223  *  - In receive only mode, with CRC calculation enabled, at the end of the CRC reception,
00224  *     the software needs to check the CRCERR flag. If it is found set, read back the SPI_RXCRC:
00225  *       + If the value is 0, the complete data transfer is successful.
00226  *       + Otherwise, one or more errors have been detected during the data transfer by CPU or DMA.
00227  *    If CRCERR is found reset, the complete data transfer is considered successful.
00228  *
00229  * Check RevisionID value for identifying if Device is Rev Z (0x0001) in order to enable workaround for
00230  * CRC errors wrongly detected
00231  */
00232 /* Pb is that ES_STM32F10xxCDE also identify an issue in Debug registers access while not in Debug mode
00233  * Revision ID information is only available in Debug mode, so Workaround could not be implemented
00234  * to distinguish Rev Z devices (issue present) from more recent version (issue fixed).
00235  * So, in case of Revison Z F101 or F103 devices, below define should be assigned to 1.
00236  */
00237 #define  USE_SPI_CRC_ERROR_WORKAROUND   0U
00238 #endif
00239 /** @defgroup SPI_Private_Constants SPI Private Constants
00240   * @{
00241   */
00242 #define SPI_DEFAULT_TIMEOUT 100U
00243 /**
00244   * @}
00245   */
00246 
00247 /* Private macros ------------------------------------------------------------*/
00248 /* Private variables ---------------------------------------------------------*/
00249 /* Private function prototypes -----------------------------------------------*/
00250 /** @defgroup SPI_Private_Functions SPI Private Functions
00251   * @{
00252   */
00253 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00254 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00255 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
00256 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
00257 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
00258 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
00259 static void SPI_DMAError(DMA_HandleTypeDef *hdma);
00260 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
00261 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
00262 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
00263 static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus State,
00264                                                        uint32_t Timeout, uint32_t Tickstart);
00265 static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
00266 static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
00267 static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
00268 static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
00269 static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
00270 static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
00271 static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
00272 static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
00273 #if (USE_SPI_CRC != 0U)
00274 static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
00275 static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
00276 static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
00277 static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
00278 #endif /* USE_SPI_CRC */
00279 static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi);
00280 static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi);
00281 static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi);
00282 static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi);
00283 static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi);
00284 static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
00285 static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
00286 /**
00287   * @}
00288   */
00289 
00290 /* Exported functions --------------------------------------------------------*/
00291 /** @defgroup SPI_Exported_Functions SPI Exported Functions
00292   * @{
00293   */
00294 
00295 /** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
00296   *  @brief    Initialization and Configuration functions
00297   *
00298 @verbatim
00299  ===============================================================================
00300               ##### Initialization and de-initialization functions #####
00301  ===============================================================================
00302     [..]  This subsection provides a set of functions allowing to initialize and
00303           de-initialize the SPIx peripheral:
00304 
00305       (+) User must implement HAL_SPI_MspInit() function in which he configures
00306           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
00307 
00308       (+) Call the function HAL_SPI_Init() to configure the selected device with
00309           the selected configuration:
00310         (++) Mode
00311         (++) Direction
00312         (++) Data Size
00313         (++) Clock Polarity and Phase
00314         (++) NSS Management
00315         (++) BaudRate Prescaler
00316         (++) FirstBit
00317         (++) TIMode
00318         (++) CRC Calculation
00319         (++) CRC Polynomial if CRC enabled
00320 
00321       (+) Call the function HAL_SPI_DeInit() to restore the default configuration
00322           of the selected SPIx peripheral.
00323 
00324 @endverbatim
00325   * @{
00326   */
00327 
00328 /**
00329   * @brief  Initialize the SPI according to the specified parameters
00330   *         in the SPI_InitTypeDef and initialize the associated handle.
00331   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00332   *               the configuration information for SPI module.
00333   * @retval HAL status
00334   */
00335 HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
00336 {
00337   /* Check the SPI handle allocation */
00338   if (hspi == NULL)
00339   {
00340     return HAL_ERROR;
00341   }
00342 
00343   /* Check the parameters */
00344   assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
00345   assert_param(IS_SPI_MODE(hspi->Init.Mode));
00346   assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
00347   assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
00348   assert_param(IS_SPI_NSS(hspi->Init.NSS));
00349   assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
00350   assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
00351   /* TI mode is not supported on this device.
00352      TIMode parameter is mandatory equal to SPI_TIMODE_DISABLE */
00353   assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
00354   if (hspi->Init.TIMode == SPI_TIMODE_DISABLE)
00355   {
00356     assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
00357     assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
00358 
00359     if (hspi->Init.Mode == SPI_MODE_MASTER)
00360     {
00361       assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
00362     }
00363     else
00364     {
00365       /* Baudrate prescaler not use in Motoraola Slave mode. force to default value */
00366       hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
00367     }
00368   }
00369   else
00370   {
00371     assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
00372 
00373     /* Force polarity and phase to TI protocaol requirements */
00374     hspi->Init.CLKPolarity = SPI_POLARITY_LOW;
00375     hspi->Init.CLKPhase    = SPI_PHASE_1EDGE;
00376   }
00377 #if (USE_SPI_CRC != 0U)
00378   assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
00379   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00380   {
00381     assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
00382   }
00383 #else
00384   hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
00385 #endif /* USE_SPI_CRC */
00386 
00387   if (hspi->State == HAL_SPI_STATE_RESET)
00388   {
00389     /* Allocate lock resource and initialize it */
00390     hspi->Lock = HAL_UNLOCKED;
00391 
00392 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
00393     /* Init the SPI Callback settings */
00394     hspi->TxCpltCallback       = HAL_SPI_TxCpltCallback;       /* Legacy weak TxCpltCallback       */
00395     hspi->RxCpltCallback       = HAL_SPI_RxCpltCallback;       /* Legacy weak RxCpltCallback       */
00396     hspi->TxRxCpltCallback     = HAL_SPI_TxRxCpltCallback;     /* Legacy weak TxRxCpltCallback     */
00397     hspi->TxHalfCpltCallback   = HAL_SPI_TxHalfCpltCallback;   /* Legacy weak TxHalfCpltCallback   */
00398     hspi->RxHalfCpltCallback   = HAL_SPI_RxHalfCpltCallback;   /* Legacy weak RxHalfCpltCallback   */
00399     hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
00400     hspi->ErrorCallback        = HAL_SPI_ErrorCallback;        /* Legacy weak ErrorCallback        */
00401     hspi->AbortCpltCallback    = HAL_SPI_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
00402 
00403     if (hspi->MspInitCallback == NULL)
00404     {
00405       hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit  */
00406     }
00407 
00408     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
00409     hspi->MspInitCallback(hspi);
00410 #else
00411     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
00412     HAL_SPI_MspInit(hspi);
00413 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
00414   }
00415 
00416   hspi->State = HAL_SPI_STATE_BUSY;
00417 
00418   /* Disable the selected SPI peripheral */
00419   __HAL_SPI_DISABLE(hspi);
00420 
00421   /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
00422   /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
00423   Communication speed, First bit and CRC calculation state */
00424   WRITE_REG(hspi->Instance->CR1, ((hspi->Init.Mode & (SPI_CR1_MSTR | SPI_CR1_SSI)) |
00425                                   (hspi->Init.Direction & (SPI_CR1_RXONLY | SPI_CR1_BIDIMODE)) |
00426                                   (hspi->Init.DataSize & SPI_CR1_DFF) |
00427                                   (hspi->Init.CLKPolarity & SPI_CR1_CPOL) |
00428                                   (hspi->Init.CLKPhase & SPI_CR1_CPHA) |
00429                                   (hspi->Init.NSS & SPI_CR1_SSM) |
00430                                   (hspi->Init.BaudRatePrescaler & SPI_CR1_BR_Msk) |
00431                                   (hspi->Init.FirstBit  & SPI_CR1_LSBFIRST) |
00432                                   (hspi->Init.CRCCalculation & SPI_CR1_CRCEN)));
00433 
00434   /* Configure : NSS management */
00435   WRITE_REG(hspi->Instance->CR2, ((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE));
00436 
00437 #if (USE_SPI_CRC != 0U)
00438   /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
00439   /* Configure : CRC Polynomial */
00440   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00441   {
00442     WRITE_REG(hspi->Instance->CRCPR, (hspi->Init.CRCPolynomial & SPI_CRCPR_CRCPOLY_Msk));
00443   }
00444 #endif /* USE_SPI_CRC */
00445 
00446 #if defined(SPI_I2SCFGR_I2SMOD)
00447   /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
00448   CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
00449 #endif /* SPI_I2SCFGR_I2SMOD */
00450 
00451   hspi->ErrorCode = HAL_SPI_ERROR_NONE;
00452   hspi->State     = HAL_SPI_STATE_READY;
00453 
00454   return HAL_OK;
00455 }
00456 
00457 /**
00458   * @brief  De-Initialize the SPI peripheral.
00459   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00460   *               the configuration information for SPI module.
00461   * @retval HAL status
00462   */
00463 HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
00464 {
00465   /* Check the SPI handle allocation */
00466   if (hspi == NULL)
00467   {
00468     return HAL_ERROR;
00469   }
00470 
00471   /* Check SPI Instance parameter */
00472   assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
00473 
00474   hspi->State = HAL_SPI_STATE_BUSY;
00475 
00476   /* Disable the SPI Peripheral Clock */
00477   __HAL_SPI_DISABLE(hspi);
00478 
00479 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
00480   if (hspi->MspDeInitCallback == NULL)
00481   {
00482     hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit  */
00483   }
00484 
00485   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
00486   hspi->MspDeInitCallback(hspi);
00487 #else
00488   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
00489   HAL_SPI_MspDeInit(hspi);
00490 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
00491 
00492   hspi->ErrorCode = HAL_SPI_ERROR_NONE;
00493   hspi->State = HAL_SPI_STATE_RESET;
00494 
00495   /* Release Lock */
00496   __HAL_UNLOCK(hspi);
00497 
00498   return HAL_OK;
00499 }
00500 
00501 /**
00502   * @brief  Initialize the SPI MSP.
00503   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00504   *               the configuration information for SPI module.
00505   * @retval None
00506   */
00507 __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
00508 {
00509   /* Prevent unused argument(s) compilation warning */
00510   UNUSED(hspi);
00511 
00512   /* NOTE : This function should not be modified, when the callback is needed,
00513             the HAL_SPI_MspInit should be implemented in the user file
00514    */
00515 }
00516 
00517 /**
00518   * @brief  De-Initialize the SPI MSP.
00519   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00520   *               the configuration information for SPI module.
00521   * @retval None
00522   */
00523 __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
00524 {
00525   /* Prevent unused argument(s) compilation warning */
00526   UNUSED(hspi);
00527 
00528   /* NOTE : This function should not be modified, when the callback is needed,
00529             the HAL_SPI_MspDeInit should be implemented in the user file
00530    */
00531 }
00532 
00533 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
00534 /**
00535   * @brief  Register a User SPI Callback
00536   *         To be used instead of the weak predefined callback
00537   * @param  hspi Pointer to a SPI_HandleTypeDef structure that contains
00538   *                the configuration information for the specified SPI.
00539   * @param  CallbackID ID of the callback to be registered
00540   * @param  pCallback pointer to the Callback function
00541   * @retval HAL status
00542   */
00543 HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID,
00544                                            pSPI_CallbackTypeDef pCallback)
00545 {
00546   HAL_StatusTypeDef status = HAL_OK;
00547 
00548   if (pCallback == NULL)
00549   {
00550     /* Update the error code */
00551     hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK;
00552 
00553     return HAL_ERROR;
00554   }
00555   /* Process locked */
00556   __HAL_LOCK(hspi);
00557 
00558   if (HAL_SPI_STATE_READY == hspi->State)
00559   {
00560     switch (CallbackID)
00561     {
00562       case HAL_SPI_TX_COMPLETE_CB_ID :
00563         hspi->TxCpltCallback = pCallback;
00564         break;
00565 
00566       case HAL_SPI_RX_COMPLETE_CB_ID :
00567         hspi->RxCpltCallback = pCallback;
00568         break;
00569 
00570       case HAL_SPI_TX_RX_COMPLETE_CB_ID :
00571         hspi->TxRxCpltCallback = pCallback;
00572         break;
00573 
00574       case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
00575         hspi->TxHalfCpltCallback = pCallback;
00576         break;
00577 
00578       case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
00579         hspi->RxHalfCpltCallback = pCallback;
00580         break;
00581 
00582       case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
00583         hspi->TxRxHalfCpltCallback = pCallback;
00584         break;
00585 
00586       case HAL_SPI_ERROR_CB_ID :
00587         hspi->ErrorCallback = pCallback;
00588         break;
00589 
00590       case HAL_SPI_ABORT_CB_ID :
00591         hspi->AbortCpltCallback = pCallback;
00592         break;
00593 
00594       case HAL_SPI_MSPINIT_CB_ID :
00595         hspi->MspInitCallback = pCallback;
00596         break;
00597 
00598       case HAL_SPI_MSPDEINIT_CB_ID :
00599         hspi->MspDeInitCallback = pCallback;
00600         break;
00601 
00602       default :
00603         /* Update the error code */
00604         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
00605 
00606         /* Return error status */
00607         status =  HAL_ERROR;
00608         break;
00609     }
00610   }
00611   else if (HAL_SPI_STATE_RESET == hspi->State)
00612   {
00613     switch (CallbackID)
00614     {
00615       case HAL_SPI_MSPINIT_CB_ID :
00616         hspi->MspInitCallback = pCallback;
00617         break;
00618 
00619       case HAL_SPI_MSPDEINIT_CB_ID :
00620         hspi->MspDeInitCallback = pCallback;
00621         break;
00622 
00623       default :
00624         /* Update the error code */
00625         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
00626 
00627         /* Return error status */
00628         status =  HAL_ERROR;
00629         break;
00630     }
00631   }
00632   else
00633   {
00634     /* Update the error code */
00635     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
00636 
00637     /* Return error status */
00638     status =  HAL_ERROR;
00639   }
00640 
00641   /* Release Lock */
00642   __HAL_UNLOCK(hspi);
00643   return status;
00644 }
00645 
00646 /**
00647   * @brief  Unregister an SPI Callback
00648   *         SPI callback is redirected to the weak predefined callback
00649   * @param  hspi Pointer to a SPI_HandleTypeDef structure that contains
00650   *                the configuration information for the specified SPI.
00651   * @param  CallbackID ID of the callback to be unregistered
00652   * @retval HAL status
00653   */
00654 HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID)
00655 {
00656   HAL_StatusTypeDef status = HAL_OK;
00657 
00658   /* Process locked */
00659   __HAL_LOCK(hspi);
00660 
00661   if (HAL_SPI_STATE_READY == hspi->State)
00662   {
00663     switch (CallbackID)
00664     {
00665       case HAL_SPI_TX_COMPLETE_CB_ID :
00666         hspi->TxCpltCallback = HAL_SPI_TxCpltCallback;             /* Legacy weak TxCpltCallback       */
00667         break;
00668 
00669       case HAL_SPI_RX_COMPLETE_CB_ID :
00670         hspi->RxCpltCallback = HAL_SPI_RxCpltCallback;             /* Legacy weak RxCpltCallback       */
00671         break;
00672 
00673       case HAL_SPI_TX_RX_COMPLETE_CB_ID :
00674         hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback;         /* Legacy weak TxRxCpltCallback     */
00675         break;
00676 
00677       case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
00678         hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback;     /* Legacy weak TxHalfCpltCallback   */
00679         break;
00680 
00681       case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
00682         hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback;     /* Legacy weak RxHalfCpltCallback   */
00683         break;
00684 
00685       case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
00686         hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
00687         break;
00688 
00689       case HAL_SPI_ERROR_CB_ID :
00690         hspi->ErrorCallback = HAL_SPI_ErrorCallback;               /* Legacy weak ErrorCallback        */
00691         break;
00692 
00693       case HAL_SPI_ABORT_CB_ID :
00694         hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback;       /* Legacy weak AbortCpltCallback    */
00695         break;
00696 
00697       case HAL_SPI_MSPINIT_CB_ID :
00698         hspi->MspInitCallback = HAL_SPI_MspInit;                   /* Legacy weak MspInit              */
00699         break;
00700 
00701       case HAL_SPI_MSPDEINIT_CB_ID :
00702         hspi->MspDeInitCallback = HAL_SPI_MspDeInit;               /* Legacy weak MspDeInit            */
00703         break;
00704 
00705       default :
00706         /* Update the error code */
00707         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
00708 
00709         /* Return error status */
00710         status =  HAL_ERROR;
00711         break;
00712     }
00713   }
00714   else if (HAL_SPI_STATE_RESET == hspi->State)
00715   {
00716     switch (CallbackID)
00717     {
00718       case HAL_SPI_MSPINIT_CB_ID :
00719         hspi->MspInitCallback = HAL_SPI_MspInit;                   /* Legacy weak MspInit              */
00720         break;
00721 
00722       case HAL_SPI_MSPDEINIT_CB_ID :
00723         hspi->MspDeInitCallback = HAL_SPI_MspDeInit;               /* Legacy weak MspDeInit            */
00724         break;
00725 
00726       default :
00727         /* Update the error code */
00728         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
00729 
00730         /* Return error status */
00731         status =  HAL_ERROR;
00732         break;
00733     }
00734   }
00735   else
00736   {
00737     /* Update the error code */
00738     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
00739 
00740     /* Return error status */
00741     status =  HAL_ERROR;
00742   }
00743 
00744   /* Release Lock */
00745   __HAL_UNLOCK(hspi);
00746   return status;
00747 }
00748 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
00749 /**
00750   * @}
00751   */
00752 
00753 /** @defgroup SPI_Exported_Functions_Group2 IO operation functions
00754   *  @brief   Data transfers functions
00755   *
00756 @verbatim
00757   ==============================================================================
00758                       ##### IO operation functions #####
00759  ===============================================================================
00760  [..]
00761     This subsection provides a set of functions allowing to manage the SPI
00762     data transfers.
00763 
00764     [..] The SPI supports master and slave mode :
00765 
00766     (#) There are two modes of transfer:
00767        (++) Blocking mode: The communication is performed in polling mode.
00768             The HAL status of all data processing is returned by the same function
00769             after finishing transfer.
00770        (++) No-Blocking mode: The communication is performed using Interrupts
00771             or DMA, These APIs return the HAL status.
00772             The end of the data processing will be indicated through the
00773             dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
00774             using DMA mode.
00775             The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
00776             will be executed respectively at the end of the transmit or Receive process
00777             The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected
00778 
00779     (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
00780         exist for 1Line (simplex) and 2Lines (full duplex) modes.
00781 
00782 @endverbatim
00783   * @{
00784   */
00785 
00786 /**
00787   * @brief  Transmit an amount of data in blocking mode.
00788   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00789   *               the configuration information for SPI module.
00790   * @param  pData pointer to data buffer
00791   * @param  Size amount of data to be sent
00792   * @param  Timeout Timeout duration
00793   * @retval HAL status
00794   */
00795 HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00796 {
00797   uint32_t tickstart;
00798   HAL_StatusTypeDef errorcode = HAL_OK;
00799   uint16_t initial_TxXferCount;
00800 
00801   /* Check Direction parameter */
00802   assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
00803 
00804   /* Process Locked */
00805   __HAL_LOCK(hspi);
00806 
00807   /* Init tickstart for timeout management*/
00808   tickstart = HAL_GetTick();
00809   initial_TxXferCount = Size;
00810 
00811   if (hspi->State != HAL_SPI_STATE_READY)
00812   {
00813     errorcode = HAL_BUSY;
00814     goto error;
00815   }
00816 
00817   if ((pData == NULL) || (Size == 0U))
00818   {
00819     errorcode = HAL_ERROR;
00820     goto error;
00821   }
00822 
00823   /* Set the transaction information */
00824   hspi->State       = HAL_SPI_STATE_BUSY_TX;
00825   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
00826   hspi->pTxBuffPtr  = (uint8_t *)pData;
00827   hspi->TxXferSize  = Size;
00828   hspi->TxXferCount = Size;
00829 
00830   /*Init field not used in handle to zero */
00831   hspi->pRxBuffPtr  = (uint8_t *)NULL;
00832   hspi->RxXferSize  = 0U;
00833   hspi->RxXferCount = 0U;
00834   hspi->TxISR       = NULL;
00835   hspi->RxISR       = NULL;
00836 
00837   /* Configure communication direction : 1Line */
00838   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
00839   {
00840     /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
00841     __HAL_SPI_DISABLE(hspi);
00842     SPI_1LINE_TX(hspi);
00843   }
00844 
00845 #if (USE_SPI_CRC != 0U)
00846   /* Reset CRC Calculation */
00847   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00848   {
00849     SPI_RESET_CRC(hspi);
00850   }
00851 #endif /* USE_SPI_CRC */
00852 
00853   /* Check if the SPI is already enabled */
00854   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
00855   {
00856     /* Enable SPI peripheral */
00857     __HAL_SPI_ENABLE(hspi);
00858   }
00859 
00860   /* Transmit data in 16 Bit mode */
00861   if (hspi->Init.DataSize == SPI_DATASIZE_16BIT)
00862   {
00863     if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
00864     {
00865       hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
00866       hspi->pTxBuffPtr += sizeof(uint16_t);
00867       hspi->TxXferCount--;
00868     }
00869     /* Transmit data in 16 Bit mode */
00870     while (hspi->TxXferCount > 0U)
00871     {
00872       /* Wait until TXE flag is set to send data */
00873       if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
00874       {
00875         hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
00876         hspi->pTxBuffPtr += sizeof(uint16_t);
00877         hspi->TxXferCount--;
00878       }
00879       else
00880       {
00881         /* Timeout management */
00882         if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
00883         {
00884           errorcode = HAL_TIMEOUT;
00885           goto error;
00886         }
00887       }
00888     }
00889   }
00890   /* Transmit data in 8 Bit mode */
00891   else
00892   {
00893     if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
00894     {
00895       *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
00896       hspi->pTxBuffPtr += sizeof(uint8_t);
00897       hspi->TxXferCount--;
00898     }
00899     while (hspi->TxXferCount > 0U)
00900     {
00901       /* Wait until TXE flag is set to send data */
00902       if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
00903       {
00904         *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
00905         hspi->pTxBuffPtr += sizeof(uint8_t);
00906         hspi->TxXferCount--;
00907       }
00908       else
00909       {
00910         /* Timeout management */
00911         if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
00912         {
00913           errorcode = HAL_TIMEOUT;
00914           goto error;
00915         }
00916       }
00917     }
00918   }
00919 #if (USE_SPI_CRC != 0U)
00920   /* Enable CRC Transmission */
00921   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00922   {
00923     SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
00924   }
00925 #endif /* USE_SPI_CRC */
00926 
00927   /* Check the end of the transaction */
00928   if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK)
00929   {
00930     hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
00931   }
00932 
00933   /* Clear overrun flag in 2 Lines communication mode because received is not read */
00934   if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
00935   {
00936     __HAL_SPI_CLEAR_OVRFLAG(hspi);
00937   }
00938 
00939   if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
00940   {
00941     errorcode = HAL_ERROR;
00942   }
00943 
00944 error:
00945   hspi->State = HAL_SPI_STATE_READY;
00946   /* Process Unlocked */
00947   __HAL_UNLOCK(hspi);
00948   return errorcode;
00949 }
00950 
00951 /**
00952   * @brief  Receive an amount of data in blocking mode.
00953   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00954   *               the configuration information for SPI module.
00955   * @param  pData pointer to data buffer
00956   * @param  Size amount of data to be received
00957   * @param  Timeout Timeout duration
00958   * @retval HAL status
00959   */
00960 HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00961 {
00962 #if (USE_SPI_CRC != 0U)
00963   __IO uint32_t tmpreg = 0U;
00964 #endif /* USE_SPI_CRC */
00965   uint32_t tickstart;
00966   HAL_StatusTypeDef errorcode = HAL_OK;
00967 
00968   if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
00969   {
00970     hspi->State = HAL_SPI_STATE_BUSY_RX;
00971     /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
00972     return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout);
00973   }
00974 
00975   /* Process Locked */
00976   __HAL_LOCK(hspi);
00977 
00978   /* Init tickstart for timeout management*/
00979   tickstart = HAL_GetTick();
00980 
00981   if (hspi->State != HAL_SPI_STATE_READY)
00982   {
00983     errorcode = HAL_BUSY;
00984     goto error;
00985   }
00986 
00987   if ((pData == NULL) || (Size == 0U))
00988   {
00989     errorcode = HAL_ERROR;
00990     goto error;
00991   }
00992 
00993   /* Set the transaction information */
00994   hspi->State       = HAL_SPI_STATE_BUSY_RX;
00995   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
00996   hspi->pRxBuffPtr  = (uint8_t *)pData;
00997   hspi->RxXferSize  = Size;
00998   hspi->RxXferCount = Size;
00999 
01000   /*Init field not used in handle to zero */
01001   hspi->pTxBuffPtr  = (uint8_t *)NULL;
01002   hspi->TxXferSize  = 0U;
01003   hspi->TxXferCount = 0U;
01004   hspi->RxISR       = NULL;
01005   hspi->TxISR       = NULL;
01006 
01007 #if (USE_SPI_CRC != 0U)
01008   /* Reset CRC Calculation */
01009   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01010   {
01011     SPI_RESET_CRC(hspi);
01012     /* this is done to handle the CRCNEXT before the latest data */
01013     hspi->RxXferCount--;
01014   }
01015 #endif /* USE_SPI_CRC */
01016 
01017   /* Configure communication direction: 1Line */
01018   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
01019   {
01020     /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
01021     __HAL_SPI_DISABLE(hspi);
01022     SPI_1LINE_RX(hspi);
01023   }
01024 
01025   /* Check if the SPI is already enabled */
01026   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01027   {
01028     /* Enable SPI peripheral */
01029     __HAL_SPI_ENABLE(hspi);
01030   }
01031 
01032   /* Receive data in 8 Bit mode */
01033   if (hspi->Init.DataSize == SPI_DATASIZE_8BIT)
01034   {
01035     /* Transfer loop */
01036     while (hspi->RxXferCount > 0U)
01037     {
01038       /* Check the RXNE flag */
01039       if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
01040       {
01041         /* read the received data */
01042         (* (uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR;
01043         hspi->pRxBuffPtr += sizeof(uint8_t);
01044         hspi->RxXferCount--;
01045       }
01046       else
01047       {
01048         /* Timeout management */
01049         if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
01050         {
01051           errorcode = HAL_TIMEOUT;
01052           goto error;
01053         }
01054       }
01055     }
01056   }
01057   else
01058   {
01059     /* Transfer loop */
01060     while (hspi->RxXferCount > 0U)
01061     {
01062       /* Check the RXNE flag */
01063       if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
01064       {
01065         *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR;
01066         hspi->pRxBuffPtr += sizeof(uint16_t);
01067         hspi->RxXferCount--;
01068       }
01069       else
01070       {
01071         /* Timeout management */
01072         if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
01073         {
01074           errorcode = HAL_TIMEOUT;
01075           goto error;
01076         }
01077       }
01078     }
01079   }
01080 
01081 #if (USE_SPI_CRC != 0U)
01082   /* Handle the CRC Transmission */
01083   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01084   {
01085     /* freeze the CRC before the latest data */
01086     SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
01087 
01088     /* Check if CRCNEXT is well reseted by hardware */
01089     if (READ_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT))
01090     {
01091       /* Workaround to force CRCNEXT bit to zero in case of CRCNEXT is not reset automatically by hardware */
01092       CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
01093     }
01094     /* Read the latest data */
01095     if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
01096     {
01097       /* the latest data has not been received */
01098       errorcode = HAL_TIMEOUT;
01099       goto error;
01100     }
01101 
01102     /* Receive last data in 16 Bit mode */
01103     if (hspi->Init.DataSize == SPI_DATASIZE_16BIT)
01104     {
01105       *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR;
01106     }
01107     /* Receive last data in 8 Bit mode */
01108     else
01109     {
01110       (*(uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR;
01111     }
01112 
01113     /* Wait the CRC data */
01114     if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
01115     {
01116       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
01117       errorcode = HAL_TIMEOUT;
01118       goto error;
01119     }
01120 
01121     /* Read CRC to Flush DR and RXNE flag */
01122     tmpreg = READ_REG(hspi->Instance->DR);
01123     /* To avoid GCC warning */
01124     UNUSED(tmpreg);
01125   }
01126 #endif /* USE_SPI_CRC */
01127 
01128   /* Check the end of the transaction */
01129   if (SPI_EndRxTransaction(hspi, Timeout, tickstart) != HAL_OK)
01130   {
01131     hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
01132   }
01133 
01134 #if (USE_SPI_CRC != 0U)
01135   /* Check if CRC error occurred */
01136   if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
01137   {
01138     /* Check if CRC error is valid or not (workaround to be applied or not) */
01139     if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
01140     {
01141       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
01142 
01143       /* Reset CRC Calculation */
01144       SPI_RESET_CRC(hspi);
01145     }
01146     else
01147     {
01148       __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
01149     }
01150   }
01151 #endif /* USE_SPI_CRC */
01152 
01153   if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
01154   {
01155     errorcode = HAL_ERROR;
01156   }
01157 
01158 error :
01159   hspi->State = HAL_SPI_STATE_READY;
01160   __HAL_UNLOCK(hspi);
01161   return errorcode;
01162 }
01163 
01164 /**
01165   * @brief  Transmit and Receive an amount of data in blocking mode.
01166   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01167   *               the configuration information for SPI module.
01168   * @param  pTxData pointer to transmission data buffer
01169   * @param  pRxData pointer to reception data buffer
01170   * @param  Size amount of data to be sent and received
01171   * @param  Timeout Timeout duration
01172   * @retval HAL status
01173   */
01174 HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,
01175                                           uint32_t Timeout)
01176 {
01177   uint16_t             initial_TxXferCount;
01178   uint32_t             tmp_mode;
01179   HAL_SPI_StateTypeDef tmp_state;
01180   uint32_t             tickstart;
01181 #if (USE_SPI_CRC != 0U)
01182   __IO uint32_t tmpreg = 0U;
01183 #endif /* USE_SPI_CRC */
01184 
01185   /* Variable used to alternate Rx and Tx during transfer */
01186   uint32_t             txallowed = 1U;
01187   HAL_StatusTypeDef    errorcode = HAL_OK;
01188 
01189   /* Check Direction parameter */
01190   assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
01191 
01192   /* Process Locked */
01193   __HAL_LOCK(hspi);
01194 
01195   /* Init tickstart for timeout management*/
01196   tickstart = HAL_GetTick();
01197 
01198   /* Init temporary variables */
01199   tmp_state           = hspi->State;
01200   tmp_mode            = hspi->Init.Mode;
01201   initial_TxXferCount = Size;
01202 
01203   if (!((tmp_state == HAL_SPI_STATE_READY) || \
01204         ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
01205   {
01206     errorcode = HAL_BUSY;
01207     goto error;
01208   }
01209 
01210   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
01211   {
01212     errorcode = HAL_ERROR;
01213     goto error;
01214   }
01215 
01216   /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
01217   if (hspi->State != HAL_SPI_STATE_BUSY_RX)
01218   {
01219     hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
01220   }
01221 
01222   /* Set the transaction information */
01223   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01224   hspi->pRxBuffPtr  = (uint8_t *)pRxData;
01225   hspi->RxXferCount = Size;
01226   hspi->RxXferSize  = Size;
01227   hspi->pTxBuffPtr  = (uint8_t *)pTxData;
01228   hspi->TxXferCount = Size;
01229   hspi->TxXferSize  = Size;
01230 
01231   /*Init field not used in handle to zero */
01232   hspi->RxISR       = NULL;
01233   hspi->TxISR       = NULL;
01234 
01235 #if (USE_SPI_CRC != 0U)
01236   /* Reset CRC Calculation */
01237   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01238   {
01239     SPI_RESET_CRC(hspi);
01240   }
01241 #endif /* USE_SPI_CRC */
01242 
01243   /* Check if the SPI is already enabled */
01244   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01245   {
01246     /* Enable SPI peripheral */
01247     __HAL_SPI_ENABLE(hspi);
01248   }
01249 
01250   /* Transmit and Receive data in 16 Bit mode */
01251   if (hspi->Init.DataSize == SPI_DATASIZE_16BIT)
01252   {
01253     if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
01254     {
01255       hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
01256       hspi->pTxBuffPtr += sizeof(uint16_t);
01257       hspi->TxXferCount--;
01258     }
01259     while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
01260     {
01261       /* Check TXE flag */
01262       if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && (txallowed == 1U))
01263       {
01264         hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
01265         hspi->pTxBuffPtr += sizeof(uint16_t);
01266         hspi->TxXferCount--;
01267         /* Next Data is a reception (Rx). Tx not allowed */
01268         txallowed = 0U;
01269 
01270 #if (USE_SPI_CRC != 0U)
01271         /* Enable CRC Transmission */
01272         if ((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
01273         {
01274           SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
01275         }
01276 #endif /* USE_SPI_CRC */
01277       }
01278 
01279       /* Check RXNE flag */
01280       if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U))
01281       {
01282         *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR;
01283         hspi->pRxBuffPtr += sizeof(uint16_t);
01284         hspi->RxXferCount--;
01285         /* Next Data is a Transmission (Tx). Tx is allowed */
01286         txallowed = 1U;
01287       }
01288       if (((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY))
01289       {
01290         errorcode = HAL_TIMEOUT;
01291         goto error;
01292       }
01293     }
01294   }
01295   /* Transmit and Receive data in 8 Bit mode */
01296   else
01297   {
01298     if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
01299     {
01300       *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
01301       hspi->pTxBuffPtr += sizeof(uint8_t);
01302       hspi->TxXferCount--;
01303     }
01304     while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
01305     {
01306       /* Check TXE flag */
01307       if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && (txallowed == 1U))
01308       {
01309         *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);
01310         hspi->pTxBuffPtr++;
01311         hspi->TxXferCount--;
01312         /* Next Data is a reception (Rx). Tx not allowed */
01313         txallowed = 0U;
01314 
01315 #if (USE_SPI_CRC != 0U)
01316         /* Enable CRC Transmission */
01317         if ((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
01318         {
01319           SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
01320         }
01321 #endif /* USE_SPI_CRC */
01322       }
01323 
01324       /* Wait until RXNE flag is reset */
01325       if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U))
01326       {
01327         (*(uint8_t *)hspi->pRxBuffPtr) = hspi->Instance->DR;
01328         hspi->pRxBuffPtr++;
01329         hspi->RxXferCount--;
01330         /* Next Data is a Transmission (Tx). Tx is allowed */
01331         txallowed = 1U;
01332       }
01333       if ((((HAL_GetTick() - tickstart) >=  Timeout) && ((Timeout != HAL_MAX_DELAY))) || (Timeout == 0U))
01334       {
01335         errorcode = HAL_TIMEOUT;
01336         goto error;
01337       }
01338     }
01339   }
01340 
01341 #if (USE_SPI_CRC != 0U)
01342   /* Read CRC from DR to close CRC calculation process */
01343   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01344   {
01345     /* Wait until TXE flag */
01346     if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
01347     {
01348       /* Error on the CRC reception */
01349       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
01350       errorcode = HAL_TIMEOUT;
01351       goto error;
01352     }
01353     /* Read CRC */
01354     tmpreg = READ_REG(hspi->Instance->DR);
01355     /* To avoid GCC warning */
01356     UNUSED(tmpreg);
01357   }
01358 
01359   /* Check if CRC error occurred */
01360   if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
01361   {
01362     /* Check if CRC error is valid or not (workaround to be applied or not) */
01363     if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
01364     {
01365       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
01366 
01367       /* Reset CRC Calculation */
01368       SPI_RESET_CRC(hspi);
01369 
01370       errorcode = HAL_ERROR;
01371     }
01372     else
01373     {
01374       __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
01375     }
01376   }
01377 #endif /* USE_SPI_CRC */
01378 
01379   /* Check the end of the transaction */
01380   if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK)
01381   {
01382     errorcode = HAL_ERROR;
01383     hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
01384     goto error;
01385   }
01386 
01387   /* Clear overrun flag in 2 Lines communication mode because received is not read */
01388   if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
01389   {
01390     __HAL_SPI_CLEAR_OVRFLAG(hspi);
01391   }
01392 
01393 error :
01394   hspi->State = HAL_SPI_STATE_READY;
01395   __HAL_UNLOCK(hspi);
01396   return errorcode;
01397 }
01398 
01399 /**
01400   * @brief  Transmit an amount of data in non-blocking mode with Interrupt.
01401   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01402   *               the configuration information for SPI module.
01403   * @param  pData pointer to data buffer
01404   * @param  Size amount of data to be sent
01405   * @retval HAL status
01406   */
01407 HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
01408 {
01409   HAL_StatusTypeDef errorcode = HAL_OK;
01410 
01411   /* Check Direction parameter */
01412   assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
01413 
01414   /* Process Locked */
01415   __HAL_LOCK(hspi);
01416 
01417   if ((pData == NULL) || (Size == 0U))
01418   {
01419     errorcode = HAL_ERROR;
01420     goto error;
01421   }
01422 
01423   if (hspi->State != HAL_SPI_STATE_READY)
01424   {
01425     errorcode = HAL_BUSY;
01426     goto error;
01427   }
01428 
01429   /* Set the transaction information */
01430   hspi->State       = HAL_SPI_STATE_BUSY_TX;
01431   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01432   hspi->pTxBuffPtr  = (uint8_t *)pData;
01433   hspi->TxXferSize  = Size;
01434   hspi->TxXferCount = Size;
01435 
01436   /* Init field not used in handle to zero */
01437   hspi->pRxBuffPtr  = (uint8_t *)NULL;
01438   hspi->RxXferSize  = 0U;
01439   hspi->RxXferCount = 0U;
01440   hspi->RxISR       = NULL;
01441 
01442   /* Set the function for IT treatment */
01443   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
01444   {
01445     hspi->TxISR = SPI_TxISR_16BIT;
01446   }
01447   else
01448   {
01449     hspi->TxISR = SPI_TxISR_8BIT;
01450   }
01451 
01452   /* Configure communication direction : 1Line */
01453   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
01454   {
01455     /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
01456     __HAL_SPI_DISABLE(hspi);
01457     SPI_1LINE_TX(hspi);
01458   }
01459 
01460 #if (USE_SPI_CRC != 0U)
01461   /* Reset CRC Calculation */
01462   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01463   {
01464     SPI_RESET_CRC(hspi);
01465   }
01466 #endif /* USE_SPI_CRC */
01467 
01468   /* Enable TXE and ERR interrupt */
01469   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
01470 
01471 
01472   /* Check if the SPI is already enabled */
01473   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01474   {
01475     /* Enable SPI peripheral */
01476     __HAL_SPI_ENABLE(hspi);
01477   }
01478 
01479 error :
01480   __HAL_UNLOCK(hspi);
01481   return errorcode;
01482 }
01483 
01484 /**
01485   * @brief  Receive an amount of data in non-blocking mode with Interrupt.
01486   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01487   *               the configuration information for SPI module.
01488   * @param  pData pointer to data buffer
01489   * @param  Size amount of data to be sent
01490   * @retval HAL status
01491   */
01492 HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
01493 {
01494   HAL_StatusTypeDef errorcode = HAL_OK;
01495 
01496   if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
01497   {
01498     hspi->State = HAL_SPI_STATE_BUSY_RX;
01499     /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
01500     return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size);
01501   }
01502 
01503   /* Process Locked */
01504   __HAL_LOCK(hspi);
01505 
01506   if (hspi->State != HAL_SPI_STATE_READY)
01507   {
01508     errorcode = HAL_BUSY;
01509     goto error;
01510   }
01511 
01512   if ((pData == NULL) || (Size == 0U))
01513   {
01514     errorcode = HAL_ERROR;
01515     goto error;
01516   }
01517 
01518   /* Set the transaction information */
01519   hspi->State       = HAL_SPI_STATE_BUSY_RX;
01520   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01521   hspi->pRxBuffPtr  = (uint8_t *)pData;
01522   hspi->RxXferSize  = Size;
01523   hspi->RxXferCount = Size;
01524 
01525   /* Init field not used in handle to zero */
01526   hspi->pTxBuffPtr  = (uint8_t *)NULL;
01527   hspi->TxXferSize  = 0U;
01528   hspi->TxXferCount = 0U;
01529   hspi->TxISR       = NULL;
01530 
01531   /* Set the function for IT treatment */
01532   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
01533   {
01534     hspi->RxISR = SPI_RxISR_16BIT;
01535   }
01536   else
01537   {
01538     hspi->RxISR = SPI_RxISR_8BIT;
01539   }
01540 
01541   /* Configure communication direction : 1Line */
01542   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
01543   {
01544     /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
01545     __HAL_SPI_DISABLE(hspi);
01546     SPI_1LINE_RX(hspi);
01547   }
01548 
01549 #if (USE_SPI_CRC != 0U)
01550   /* Reset CRC Calculation */
01551   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01552   {
01553     SPI_RESET_CRC(hspi);
01554   }
01555 #endif /* USE_SPI_CRC */
01556 
01557   /* Enable TXE and ERR interrupt */
01558   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
01559 
01560   /* Note : The SPI must be enabled after unlocking current process
01561             to avoid the risk of SPI interrupt handle execution before current
01562             process unlock */
01563 
01564   /* Check if the SPI is already enabled */
01565   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01566   {
01567     /* Enable SPI peripheral */
01568     __HAL_SPI_ENABLE(hspi);
01569   }
01570 
01571 error :
01572   /* Process Unlocked */
01573   __HAL_UNLOCK(hspi);
01574   return errorcode;
01575 }
01576 
01577 /**
01578   * @brief  Transmit and Receive an amount of data in non-blocking mode with Interrupt.
01579   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01580   *               the configuration information for SPI module.
01581   * @param  pTxData pointer to transmission data buffer
01582   * @param  pRxData pointer to reception data buffer
01583   * @param  Size amount of data to be sent and received
01584   * @retval HAL status
01585   */
01586 HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
01587 {
01588   uint32_t             tmp_mode;
01589   HAL_SPI_StateTypeDef tmp_state;
01590   HAL_StatusTypeDef    errorcode = HAL_OK;
01591 
01592   /* Check Direction parameter */
01593   assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
01594 
01595   /* Process locked */
01596   __HAL_LOCK(hspi);
01597 
01598   /* Init temporary variables */
01599   tmp_state           = hspi->State;
01600   tmp_mode            = hspi->Init.Mode;
01601 
01602   if (!((tmp_state == HAL_SPI_STATE_READY) || \
01603         ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
01604   {
01605     errorcode = HAL_BUSY;
01606     goto error;
01607   }
01608 
01609   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
01610   {
01611     errorcode = HAL_ERROR;
01612     goto error;
01613   }
01614 
01615   /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
01616   if (hspi->State != HAL_SPI_STATE_BUSY_RX)
01617   {
01618     hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
01619   }
01620 
01621   /* Set the transaction information */
01622   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01623   hspi->pTxBuffPtr  = (uint8_t *)pTxData;
01624   hspi->TxXferSize  = Size;
01625   hspi->TxXferCount = Size;
01626   hspi->pRxBuffPtr  = (uint8_t *)pRxData;
01627   hspi->RxXferSize  = Size;
01628   hspi->RxXferCount = Size;
01629 
01630   /* Set the function for IT treatment */
01631   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
01632   {
01633     hspi->RxISR     = SPI_2linesRxISR_16BIT;
01634     hspi->TxISR     = SPI_2linesTxISR_16BIT;
01635   }
01636   else
01637   {
01638     hspi->RxISR     = SPI_2linesRxISR_8BIT;
01639     hspi->TxISR     = SPI_2linesTxISR_8BIT;
01640   }
01641 
01642 #if (USE_SPI_CRC != 0U)
01643   /* Reset CRC Calculation */
01644   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01645   {
01646     SPI_RESET_CRC(hspi);
01647   }
01648 #endif /* USE_SPI_CRC */
01649 
01650   /* Enable TXE, RXNE and ERR interrupt */
01651   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
01652 
01653   /* Check if the SPI is already enabled */
01654   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01655   {
01656     /* Enable SPI peripheral */
01657     __HAL_SPI_ENABLE(hspi);
01658   }
01659 
01660 error :
01661   /* Process Unlocked */
01662   __HAL_UNLOCK(hspi);
01663   return errorcode;
01664 }
01665 
01666 /**
01667   * @brief  Transmit an amount of data in non-blocking mode with DMA.
01668   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01669   *               the configuration information for SPI module.
01670   * @param  pData pointer to data buffer
01671   * @param  Size amount of data to be sent
01672   * @retval HAL status
01673   */
01674 HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
01675 {
01676   HAL_StatusTypeDef errorcode = HAL_OK;
01677 
01678   /* Check tx dma handle */
01679   assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
01680 
01681   /* Check Direction parameter */
01682   assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
01683 
01684   /* Process Locked */
01685   __HAL_LOCK(hspi);
01686 
01687   if (hspi->State != HAL_SPI_STATE_READY)
01688   {
01689     errorcode = HAL_BUSY;
01690     goto error;
01691   }
01692 
01693   if ((pData == NULL) || (Size == 0U))
01694   {
01695     errorcode = HAL_ERROR;
01696     goto error;
01697   }
01698 
01699   /* Set the transaction information */
01700   hspi->State       = HAL_SPI_STATE_BUSY_TX;
01701   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01702   hspi->pTxBuffPtr  = (uint8_t *)pData;
01703   hspi->TxXferSize  = Size;
01704   hspi->TxXferCount = Size;
01705 
01706   /* Init field not used in handle to zero */
01707   hspi->pRxBuffPtr  = (uint8_t *)NULL;
01708   hspi->TxISR       = NULL;
01709   hspi->RxISR       = NULL;
01710   hspi->RxXferSize  = 0U;
01711   hspi->RxXferCount = 0U;
01712 
01713   /* Configure communication direction : 1Line */
01714   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
01715   {
01716     /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
01717     __HAL_SPI_DISABLE(hspi);
01718     SPI_1LINE_TX(hspi);
01719   }
01720 
01721 #if (USE_SPI_CRC != 0U)
01722   /* Reset CRC Calculation */
01723   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01724   {
01725     SPI_RESET_CRC(hspi);
01726   }
01727 #endif /* USE_SPI_CRC */
01728 
01729   /* Set the SPI TxDMA Half transfer complete callback */
01730   hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
01731 
01732   /* Set the SPI TxDMA transfer complete callback */
01733   hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
01734 
01735   /* Set the DMA error callback */
01736   hspi->hdmatx->XferErrorCallback = SPI_DMAError;
01737 
01738   /* Set the DMA AbortCpltCallback */
01739   hspi->hdmatx->XferAbortCallback = NULL;
01740 
01741   /* Enable the Tx DMA Stream/Channel */
01742   if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR,
01743                                  hspi->TxXferCount))
01744   {
01745     /* Update SPI error code */
01746     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
01747     errorcode = HAL_ERROR;
01748 
01749     hspi->State = HAL_SPI_STATE_READY;
01750     goto error;
01751   }
01752 
01753   /* Check if the SPI is already enabled */
01754   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01755   {
01756     /* Enable SPI peripheral */
01757     __HAL_SPI_ENABLE(hspi);
01758   }
01759 
01760   /* Enable the SPI Error Interrupt Bit */
01761   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
01762 
01763   /* Enable Tx DMA Request */
01764   SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
01765 
01766 error :
01767   /* Process Unlocked */
01768   __HAL_UNLOCK(hspi);
01769   return errorcode;
01770 }
01771 
01772 /**
01773   * @brief  Receive an amount of data in non-blocking mode with DMA.
01774   * @note   In case of MASTER mode and SPI_DIRECTION_2LINES direction, hdmatx shall be defined.
01775   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01776   *               the configuration information for SPI module.
01777   * @param  pData pointer to data buffer
01778   * @note   When the CRC feature is enabled the pData Length must be Size + 1.
01779   * @param  Size amount of data to be sent
01780   * @retval HAL status
01781   */
01782 HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
01783 {
01784   HAL_StatusTypeDef errorcode = HAL_OK;
01785 
01786   /* Check rx dma handle */
01787   assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
01788 
01789   if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
01790   {
01791     hspi->State = HAL_SPI_STATE_BUSY_RX;
01792 
01793     /* Check tx dma handle */
01794     assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
01795 
01796     /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
01797     return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size);
01798   }
01799 
01800   /* Process Locked */
01801   __HAL_LOCK(hspi);
01802 
01803   if (hspi->State != HAL_SPI_STATE_READY)
01804   {
01805     errorcode = HAL_BUSY;
01806     goto error;
01807   }
01808 
01809   if ((pData == NULL) || (Size == 0U))
01810   {
01811     errorcode = HAL_ERROR;
01812     goto error;
01813   }
01814 
01815   /* Set the transaction information */
01816   hspi->State       = HAL_SPI_STATE_BUSY_RX;
01817   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01818   hspi->pRxBuffPtr  = (uint8_t *)pData;
01819   hspi->RxXferSize  = Size;
01820   hspi->RxXferCount = Size;
01821 
01822   /*Init field not used in handle to zero */
01823   hspi->RxISR       = NULL;
01824   hspi->TxISR       = NULL;
01825   hspi->TxXferSize  = 0U;
01826   hspi->TxXferCount = 0U;
01827 
01828   /* Configure communication direction : 1Line */
01829   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
01830   {
01831     /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
01832     __HAL_SPI_DISABLE(hspi);
01833     SPI_1LINE_RX(hspi);
01834   }
01835 
01836 #if (USE_SPI_CRC != 0U)
01837   /* Reset CRC Calculation */
01838   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01839   {
01840     SPI_RESET_CRC(hspi);
01841   }
01842 #endif /* USE_SPI_CRC */
01843 
01844   /* Set the SPI RxDMA Half transfer complete callback */
01845   hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
01846 
01847   /* Set the SPI Rx DMA transfer complete callback */
01848   hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
01849 
01850   /* Set the DMA error callback */
01851   hspi->hdmarx->XferErrorCallback = SPI_DMAError;
01852 
01853   /* Set the DMA AbortCpltCallback */
01854   hspi->hdmarx->XferAbortCallback = NULL;
01855 
01856   /* Enable the Rx DMA Stream/Channel  */
01857   if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr,
01858                                  hspi->RxXferCount))
01859   {
01860     /* Update SPI error code */
01861     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
01862     errorcode = HAL_ERROR;
01863 
01864     hspi->State = HAL_SPI_STATE_READY;
01865     goto error;
01866   }
01867 
01868   /* Check if the SPI is already enabled */
01869   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
01870   {
01871     /* Enable SPI peripheral */
01872     __HAL_SPI_ENABLE(hspi);
01873   }
01874 
01875   /* Enable the SPI Error Interrupt Bit */
01876   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
01877 
01878   /* Enable Rx DMA Request */
01879   SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
01880 
01881 error:
01882   /* Process Unlocked */
01883   __HAL_UNLOCK(hspi);
01884   return errorcode;
01885 }
01886 
01887 /**
01888   * @brief  Transmit and Receive an amount of data in non-blocking mode with DMA.
01889   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01890   *               the configuration information for SPI module.
01891   * @param  pTxData pointer to transmission data buffer
01892   * @param  pRxData pointer to reception data buffer
01893   * @note   When the CRC feature is enabled the pRxData Length must be Size + 1
01894   * @param  Size amount of data to be sent
01895   * @retval HAL status
01896   */
01897 HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData,
01898                                               uint16_t Size)
01899 {
01900   uint32_t             tmp_mode;
01901   HAL_SPI_StateTypeDef tmp_state;
01902   HAL_StatusTypeDef errorcode = HAL_OK;
01903 
01904   /* Check rx & tx dma handles */
01905   assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
01906   assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
01907 
01908   /* Check Direction parameter */
01909   assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
01910 
01911   /* Process locked */
01912   __HAL_LOCK(hspi);
01913 
01914   /* Init temporary variables */
01915   tmp_state           = hspi->State;
01916   tmp_mode            = hspi->Init.Mode;
01917 
01918   if (!((tmp_state == HAL_SPI_STATE_READY) ||
01919         ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
01920   {
01921     errorcode = HAL_BUSY;
01922     goto error;
01923   }
01924 
01925   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
01926   {
01927     errorcode = HAL_ERROR;
01928     goto error;
01929   }
01930 
01931   /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
01932   if (hspi->State != HAL_SPI_STATE_BUSY_RX)
01933   {
01934     hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
01935   }
01936 
01937   /* Set the transaction information */
01938   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01939   hspi->pTxBuffPtr  = (uint8_t *)pTxData;
01940   hspi->TxXferSize  = Size;
01941   hspi->TxXferCount = Size;
01942   hspi->pRxBuffPtr  = (uint8_t *)pRxData;
01943   hspi->RxXferSize  = Size;
01944   hspi->RxXferCount = Size;
01945 
01946   /* Init field not used in handle to zero */
01947   hspi->RxISR       = NULL;
01948   hspi->TxISR       = NULL;
01949 
01950 #if (USE_SPI_CRC != 0U)
01951   /* Reset CRC Calculation */
01952   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01953   {
01954     SPI_RESET_CRC(hspi);
01955   }
01956 #endif /* USE_SPI_CRC */
01957 
01958   /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
01959   if (hspi->State == HAL_SPI_STATE_BUSY_RX)
01960   {
01961     /* Set the SPI Rx DMA Half transfer complete callback */
01962     hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
01963     hspi->hdmarx->XferCpltCallback     = SPI_DMAReceiveCplt;
01964   }
01965   else
01966   {
01967     /* Set the SPI Tx/Rx DMA Half transfer complete callback */
01968     hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
01969     hspi->hdmarx->XferCpltCallback     = SPI_DMATransmitReceiveCplt;
01970   }
01971 
01972   /* Set the DMA error callback */
01973   hspi->hdmarx->XferErrorCallback = SPI_DMAError;
01974 
01975   /* Set the DMA AbortCpltCallback */
01976   hspi->hdmarx->XferAbortCallback = NULL;
01977 
01978   /* Enable the Rx DMA Stream/Channel  */
01979   if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr,
01980                                  hspi->RxXferCount))
01981   {
01982     /* Update SPI error code */
01983     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
01984     errorcode = HAL_ERROR;
01985 
01986     hspi->State = HAL_SPI_STATE_READY;
01987     goto error;
01988   }
01989 
01990   /* Enable Rx DMA Request */
01991   SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
01992 
01993   /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
01994   is performed in DMA reception complete callback  */
01995   hspi->hdmatx->XferHalfCpltCallback = NULL;
01996   hspi->hdmatx->XferCpltCallback     = NULL;
01997   hspi->hdmatx->XferErrorCallback    = NULL;
01998   hspi->hdmatx->XferAbortCallback    = NULL;
01999 
02000   /* Enable the Tx DMA Stream/Channel  */
02001   if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR,
02002                                  hspi->TxXferCount))
02003   {
02004     /* Update SPI error code */
02005     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
02006     errorcode = HAL_ERROR;
02007 
02008     hspi->State = HAL_SPI_STATE_READY;
02009     goto error;
02010   }
02011 
02012   /* Check if the SPI is already enabled */
02013   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
02014   {
02015     /* Enable SPI peripheral */
02016     __HAL_SPI_ENABLE(hspi);
02017   }
02018   /* Enable the SPI Error Interrupt Bit */
02019   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
02020 
02021   /* Enable Tx DMA Request */
02022   SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
02023 
02024 error :
02025   /* Process Unlocked */
02026   __HAL_UNLOCK(hspi);
02027   return errorcode;
02028 }
02029 
02030 /**
02031   * @brief  Abort ongoing transfer (blocking mode).
02032   * @param  hspi SPI handle.
02033   * @note   This procedure could be used for aborting any ongoing transfer (Tx and Rx),
02034   *         started in Interrupt or DMA mode.
02035   *         This procedure performs following operations :
02036   *           - Disable SPI Interrupts (depending of transfer direction)
02037   *           - Disable the DMA transfer in the peripheral register (if enabled)
02038   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
02039   *           - Set handle State to READY
02040   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
02041   * @retval HAL status
02042   */
02043 HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
02044 {
02045   HAL_StatusTypeDef errorcode;
02046   __IO uint32_t count;
02047   __IO uint32_t resetcount;
02048 
02049   /* Initialized local variable  */
02050   errorcode = HAL_OK;
02051   resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
02052   count = resetcount;
02053 
02054   /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure */
02055   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
02056 
02057   /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
02058   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
02059   {
02060     hspi->TxISR = SPI_AbortTx_ISR;
02061     /* Wait HAL_SPI_STATE_ABORT state */
02062     do
02063     {
02064       if (count == 0U)
02065       {
02066         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
02067         break;
02068       }
02069       count--;
02070     } while (hspi->State != HAL_SPI_STATE_ABORT);
02071     /* Reset Timeout Counter */
02072     count = resetcount;
02073   }
02074 
02075   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
02076   {
02077     hspi->RxISR = SPI_AbortRx_ISR;
02078     /* Wait HAL_SPI_STATE_ABORT state */
02079     do
02080     {
02081       if (count == 0U)
02082       {
02083         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
02084         break;
02085       }
02086       count--;
02087     } while (hspi->State != HAL_SPI_STATE_ABORT);
02088     /* Reset Timeout Counter */
02089     count = resetcount;
02090   }
02091 
02092   /* Disable the SPI DMA Tx request if enabled */
02093   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
02094   {
02095     /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) */
02096     if (hspi->hdmatx != NULL)
02097     {
02098       /* Set the SPI DMA Abort callback :
02099       will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
02100       hspi->hdmatx->XferAbortCallback = NULL;
02101 
02102       /* Abort DMA Tx Handle linked to SPI Peripheral */
02103       if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK)
02104       {
02105         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
02106       }
02107 
02108       /* Disable Tx DMA Request */
02109       CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN));
02110 
02111       /* Wait until TXE flag is set */
02112       do
02113       {
02114         if (count == 0U)
02115         {
02116           SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
02117           break;
02118         }
02119         count--;
02120       } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
02121     }
02122   }
02123 
02124   /* Disable the SPI DMA Rx request if enabled */
02125   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
02126   {
02127     /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) */
02128     if (hspi->hdmarx != NULL)
02129     {
02130       /* Set the SPI DMA Abort callback :
02131       will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
02132       hspi->hdmarx->XferAbortCallback = NULL;
02133 
02134       /* Abort DMA Rx Handle linked to SPI Peripheral */
02135       if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK)
02136       {
02137         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
02138       }
02139 
02140       /* Disable peripheral */
02141       __HAL_SPI_DISABLE(hspi);
02142 
02143       /* Disable Rx DMA Request */
02144       CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXDMAEN));
02145     }
02146   }
02147   /* Reset Tx and Rx transfer counters */
02148   hspi->RxXferCount = 0U;
02149   hspi->TxXferCount = 0U;
02150 
02151   /* Check error during Abort procedure */
02152   if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT)
02153   {
02154     /* return HAL_Error in case of error during Abort procedure */
02155     errorcode = HAL_ERROR;
02156   }
02157   else
02158   {
02159     /* Reset errorCode */
02160     hspi->ErrorCode = HAL_SPI_ERROR_NONE;
02161   }
02162 
02163   /* Clear the Error flags in the SR register */
02164   __HAL_SPI_CLEAR_OVRFLAG(hspi);
02165 
02166   /* Restore hspi->state to ready */
02167   hspi->State = HAL_SPI_STATE_READY;
02168 
02169   return errorcode;
02170 }
02171 
02172 /**
02173   * @brief  Abort ongoing transfer (Interrupt mode).
02174   * @param  hspi SPI handle.
02175   * @note   This procedure could be used for aborting any ongoing transfer (Tx and Rx),
02176   *         started in Interrupt or DMA mode.
02177   *         This procedure performs following operations :
02178   *           - Disable SPI Interrupts (depending of transfer direction)
02179   *           - Disable the DMA transfer in the peripheral register (if enabled)
02180   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
02181   *           - Set handle State to READY
02182   *           - At abort completion, call user abort complete callback
02183   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
02184   *         considered as completed only when user abort complete callback is executed (not when exiting function).
02185   * @retval HAL status
02186   */
02187 HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi)
02188 {
02189   HAL_StatusTypeDef errorcode;
02190   uint32_t abortcplt ;
02191   __IO uint32_t count;
02192   __IO uint32_t resetcount;
02193 
02194   /* Initialized local variable  */
02195   errorcode = HAL_OK;
02196   abortcplt = 1U;
02197   resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
02198   count = resetcount;
02199 
02200   /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure */
02201   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
02202 
02203   /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */
02204   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
02205   {
02206     hspi->TxISR = SPI_AbortTx_ISR;
02207     /* Wait HAL_SPI_STATE_ABORT state */
02208     do
02209     {
02210       if (count == 0U)
02211       {
02212         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
02213         break;
02214       }
02215       count--;
02216     } while (hspi->State != HAL_SPI_STATE_ABORT);
02217     /* Reset Timeout Counter */
02218     count = resetcount;
02219   }
02220 
02221   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
02222   {
02223     hspi->RxISR = SPI_AbortRx_ISR;
02224     /* Wait HAL_SPI_STATE_ABORT state */
02225     do
02226     {
02227       if (count == 0U)
02228       {
02229         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
02230         break;
02231       }
02232       count--;
02233     } while (hspi->State != HAL_SPI_STATE_ABORT);
02234     /* Reset Timeout Counter */
02235     count = resetcount;
02236   }
02237 
02238   /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialised
02239      before any call to DMA Abort functions */
02240   /* DMA Tx Handle is valid */
02241   if (hspi->hdmatx != NULL)
02242   {
02243     /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
02244        Otherwise, set it to NULL */
02245     if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
02246     {
02247       hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback;
02248     }
02249     else
02250     {
02251       hspi->hdmatx->XferAbortCallback = NULL;
02252     }
02253   }
02254   /* DMA Rx Handle is valid */
02255   if (hspi->hdmarx != NULL)
02256   {
02257     /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
02258        Otherwise, set it to NULL */
02259     if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
02260     {
02261       hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback;
02262     }
02263     else
02264     {
02265       hspi->hdmarx->XferAbortCallback = NULL;
02266     }
02267   }
02268 
02269   /* Disable the SPI DMA Tx request if enabled */
02270   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
02271   {
02272     /* Abort the SPI DMA Tx Stream/Channel */
02273     if (hspi->hdmatx != NULL)
02274     {
02275       /* Abort DMA Tx Handle linked to SPI Peripheral */
02276       if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
02277       {
02278         hspi->hdmatx->XferAbortCallback = NULL;
02279         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
02280       }
02281       else
02282       {
02283         abortcplt = 0U;
02284       }
02285     }
02286   }
02287   /* Disable the SPI DMA Rx request if enabled */
02288   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
02289   {
02290     /* Abort the SPI DMA Rx Stream/Channel */
02291     if (hspi->hdmarx != NULL)
02292     {
02293       /* Abort DMA Rx Handle linked to SPI Peripheral */
02294       if (HAL_DMA_Abort_IT(hspi->hdmarx) !=  HAL_OK)
02295       {
02296         hspi->hdmarx->XferAbortCallback = NULL;
02297         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
02298       }
02299       else
02300       {
02301         abortcplt = 0U;
02302       }
02303     }
02304   }
02305 
02306   if (abortcplt == 1U)
02307   {
02308     /* Reset Tx and Rx transfer counters */
02309     hspi->RxXferCount = 0U;
02310     hspi->TxXferCount = 0U;
02311 
02312     /* Check error during Abort procedure */
02313     if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT)
02314     {
02315       /* return HAL_Error in case of error during Abort procedure */
02316       errorcode = HAL_ERROR;
02317     }
02318     else
02319     {
02320       /* Reset errorCode */
02321       hspi->ErrorCode = HAL_SPI_ERROR_NONE;
02322     }
02323 
02324     /* Clear the Error flags in the SR register */
02325     __HAL_SPI_CLEAR_OVRFLAG(hspi);
02326 
02327     /* Restore hspi->State to Ready */
02328     hspi->State = HAL_SPI_STATE_READY;
02329 
02330     /* As no DMA to be aborted, call directly user Abort complete callback */
02331 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02332     hspi->AbortCpltCallback(hspi);
02333 #else
02334     HAL_SPI_AbortCpltCallback(hspi);
02335 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02336   }
02337 
02338   return errorcode;
02339 }
02340 
02341 /**
02342   * @brief  Pause the DMA Transfer.
02343   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02344   *               the configuration information for the specified SPI module.
02345   * @retval HAL status
02346   */
02347 HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
02348 {
02349   /* Process Locked */
02350   __HAL_LOCK(hspi);
02351 
02352   /* Disable the SPI DMA Tx & Rx requests */
02353   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
02354 
02355   /* Process Unlocked */
02356   __HAL_UNLOCK(hspi);
02357 
02358   return HAL_OK;
02359 }
02360 
02361 /**
02362   * @brief  Resume the DMA Transfer.
02363   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02364   *               the configuration information for the specified SPI module.
02365   * @retval HAL status
02366   */
02367 HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
02368 {
02369   /* Process Locked */
02370   __HAL_LOCK(hspi);
02371 
02372   /* Enable the SPI DMA Tx & Rx requests */
02373   SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
02374 
02375   /* Process Unlocked */
02376   __HAL_UNLOCK(hspi);
02377 
02378   return HAL_OK;
02379 }
02380 
02381 /**
02382   * @brief  Stop the DMA Transfer.
02383   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02384   *               the configuration information for the specified SPI module.
02385   * @retval HAL status
02386   */
02387 HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
02388 {
02389   HAL_StatusTypeDef errorcode = HAL_OK;
02390   /* The Lock is not implemented on this API to allow the user application
02391      to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback():
02392      when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
02393      and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback()
02394      */
02395 
02396   /* Abort the SPI DMA tx Stream/Channel  */
02397   if (hspi->hdmatx != NULL)
02398   {
02399     if (HAL_OK != HAL_DMA_Abort(hspi->hdmatx))
02400     {
02401       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
02402       errorcode = HAL_ERROR;
02403     }
02404   }
02405   /* Abort the SPI DMA rx Stream/Channel  */
02406   if (hspi->hdmarx != NULL)
02407   {
02408     if (HAL_OK != HAL_DMA_Abort(hspi->hdmarx))
02409     {
02410       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
02411       errorcode = HAL_ERROR;
02412     }
02413   }
02414 
02415   /* Disable the SPI DMA Tx & Rx requests */
02416   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
02417   hspi->State = HAL_SPI_STATE_READY;
02418   return errorcode;
02419 }
02420 
02421 /**
02422   * @brief  Handle SPI interrupt request.
02423   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02424   *               the configuration information for the specified SPI module.
02425   * @retval None
02426   */
02427 void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
02428 {
02429   uint32_t itsource = hspi->Instance->CR2;
02430   uint32_t itflag   = hspi->Instance->SR;
02431 
02432   /* SPI in mode Receiver ----------------------------------------------------*/
02433   if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) == RESET) &&
02434       (SPI_CHECK_FLAG(itflag, SPI_FLAG_RXNE) != RESET) && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_RXNE) != RESET))
02435   {
02436     hspi->RxISR(hspi);
02437     return;
02438   }
02439 
02440   /* SPI in mode Transmitter -------------------------------------------------*/
02441   if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_TXE) != RESET) && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_TXE) != RESET))
02442   {
02443     hspi->TxISR(hspi);
02444     return;
02445   }
02446 
02447   /* SPI in Error Treatment --------------------------------------------------*/
02448   if (((SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET) || (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET))
02449       && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_ERR) != RESET))
02450   {
02451     /* SPI Overrun error interrupt occurred ----------------------------------*/
02452     if (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET)
02453     {
02454       if (hspi->State != HAL_SPI_STATE_BUSY_TX)
02455       {
02456         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
02457         __HAL_SPI_CLEAR_OVRFLAG(hspi);
02458       }
02459       else
02460       {
02461         __HAL_SPI_CLEAR_OVRFLAG(hspi);
02462         return;
02463       }
02464     }
02465 
02466     /* SPI Mode Fault error interrupt occurred -------------------------------*/
02467     if (SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET)
02468     {
02469       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
02470       __HAL_SPI_CLEAR_MODFFLAG(hspi);
02471     }
02472 
02473     /* SPI Frame error interrupt occurred ------------------------------------*/
02474 
02475     if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
02476     {
02477       /* Disable all interrupts */
02478       __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
02479 
02480       hspi->State = HAL_SPI_STATE_READY;
02481       /* Disable the SPI DMA requests if enabled */
02482       if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN)) || (HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN)))
02483       {
02484         CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN));
02485 
02486         /* Abort the SPI DMA Rx channel */
02487         if (hspi->hdmarx != NULL)
02488         {
02489           /* Set the SPI DMA Abort callback :
02490           will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
02491           hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
02492           if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx))
02493           {
02494             SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
02495           }
02496         }
02497         /* Abort the SPI DMA Tx channel */
02498         if (hspi->hdmatx != NULL)
02499         {
02500           /* Set the SPI DMA Abort callback :
02501           will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
02502           hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
02503           if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx))
02504           {
02505             SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
02506           }
02507         }
02508       }
02509       else
02510       {
02511         /* Call user error callback */
02512 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02513         hspi->ErrorCallback(hspi);
02514 #else
02515         HAL_SPI_ErrorCallback(hspi);
02516 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02517       }
02518     }
02519     return;
02520   }
02521 }
02522 
02523 /**
02524   * @brief  Tx Transfer completed callback.
02525   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02526   *               the configuration information for SPI module.
02527   * @retval None
02528   */
02529 __weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
02530 {
02531   /* Prevent unused argument(s) compilation warning */
02532   UNUSED(hspi);
02533 
02534   /* NOTE : This function should not be modified, when the callback is needed,
02535             the HAL_SPI_TxCpltCallback should be implemented in the user file
02536    */
02537 }
02538 
02539 /**
02540   * @brief  Rx Transfer completed callback.
02541   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02542   *               the configuration information for SPI module.
02543   * @retval None
02544   */
02545 __weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
02546 {
02547   /* Prevent unused argument(s) compilation warning */
02548   UNUSED(hspi);
02549 
02550   /* NOTE : This function should not be modified, when the callback is needed,
02551             the HAL_SPI_RxCpltCallback should be implemented in the user file
02552    */
02553 }
02554 
02555 /**
02556   * @brief  Tx and Rx Transfer completed callback.
02557   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02558   *               the configuration information for SPI module.
02559   * @retval None
02560   */
02561 __weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
02562 {
02563   /* Prevent unused argument(s) compilation warning */
02564   UNUSED(hspi);
02565 
02566   /* NOTE : This function should not be modified, when the callback is needed,
02567             the HAL_SPI_TxRxCpltCallback should be implemented in the user file
02568    */
02569 }
02570 
02571 /**
02572   * @brief  Tx Half Transfer completed callback.
02573   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02574   *               the configuration information for SPI module.
02575   * @retval None
02576   */
02577 __weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi)
02578 {
02579   /* Prevent unused argument(s) compilation warning */
02580   UNUSED(hspi);
02581 
02582   /* NOTE : This function should not be modified, when the callback is needed,
02583             the HAL_SPI_TxHalfCpltCallback should be implemented in the user file
02584    */
02585 }
02586 
02587 /**
02588   * @brief  Rx Half Transfer completed callback.
02589   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02590   *               the configuration information for SPI module.
02591   * @retval None
02592   */
02593 __weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi)
02594 {
02595   /* Prevent unused argument(s) compilation warning */
02596   UNUSED(hspi);
02597 
02598   /* NOTE : This function should not be modified, when the callback is needed,
02599             the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file
02600    */
02601 }
02602 
02603 /**
02604   * @brief  Tx and Rx Half Transfer callback.
02605   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02606   *               the configuration information for SPI module.
02607   * @retval None
02608   */
02609 __weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi)
02610 {
02611   /* Prevent unused argument(s) compilation warning */
02612   UNUSED(hspi);
02613 
02614   /* NOTE : This function should not be modified, when the callback is needed,
02615             the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file
02616    */
02617 }
02618 
02619 /**
02620   * @brief  SPI error callback.
02621   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02622   *               the configuration information for SPI module.
02623   * @retval None
02624   */
02625 __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
02626 {
02627   /* Prevent unused argument(s) compilation warning */
02628   UNUSED(hspi);
02629 
02630   /* NOTE : This function should not be modified, when the callback is needed,
02631             the HAL_SPI_ErrorCallback should be implemented in the user file
02632    */
02633   /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes
02634             and user can use HAL_SPI_GetError() API to check the latest error occurred
02635    */
02636 }
02637 
02638 /**
02639   * @brief  SPI Abort Complete callback.
02640   * @param  hspi SPI handle.
02641   * @retval None
02642   */
02643 __weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi)
02644 {
02645   /* Prevent unused argument(s) compilation warning */
02646   UNUSED(hspi);
02647 
02648   /* NOTE : This function should not be modified, when the callback is needed,
02649             the HAL_SPI_AbortCpltCallback can be implemented in the user file.
02650    */
02651 }
02652 
02653 /**
02654   * @}
02655   */
02656 
02657 /** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
02658   * @brief   SPI control functions
02659   *
02660 @verbatim
02661  ===============================================================================
02662                       ##### Peripheral State and Errors functions #####
02663  ===============================================================================
02664     [..]
02665     This subsection provides a set of functions allowing to control the SPI.
02666      (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
02667      (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
02668 @endverbatim
02669   * @{
02670   */
02671 
02672 /**
02673   * @brief  Return the SPI handle state.
02674   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02675   *               the configuration information for SPI module.
02676   * @retval SPI state
02677   */
02678 HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi)
02679 {
02680   /* Return SPI handle state */
02681   return hspi->State;
02682 }
02683 
02684 /**
02685   * @brief  Return the SPI error code.
02686   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02687   *               the configuration information for SPI module.
02688   * @retval SPI error code in bitmap format
02689   */
02690 uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi)
02691 {
02692   /* Return SPI ErrorCode */
02693   return hspi->ErrorCode;
02694 }
02695 
02696 /**
02697   * @}
02698   */
02699 
02700 /**
02701   * @}
02702   */
02703 
02704 /** @addtogroup SPI_Private_Functions
02705   * @brief   Private functions
02706   * @{
02707   */
02708 
02709 /**
02710   * @brief  DMA SPI transmit process complete callback.
02711   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02712   *               the configuration information for the specified DMA module.
02713   * @retval None
02714   */
02715 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
02716 {
02717   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
02718   uint32_t tickstart;
02719 
02720   /* Init tickstart for timeout management*/
02721   tickstart = HAL_GetTick();
02722 
02723   /* DMA Normal Mode */
02724   if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
02725   {
02726     /* Disable ERR interrupt */
02727     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
02728 
02729     /* Disable Tx DMA Request */
02730     CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
02731 
02732     /* Check the end of the transaction */
02733     if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
02734     {
02735       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
02736     }
02737 
02738     /* Clear overrun flag in 2 Lines communication mode because received data is not read */
02739     if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
02740     {
02741       __HAL_SPI_CLEAR_OVRFLAG(hspi);
02742     }
02743 
02744     hspi->TxXferCount = 0U;
02745     hspi->State = HAL_SPI_STATE_READY;
02746 
02747     if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
02748     {
02749       /* Call user error callback */
02750 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02751       hspi->ErrorCallback(hspi);
02752 #else
02753       HAL_SPI_ErrorCallback(hspi);
02754 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02755       return;
02756     }
02757   }
02758   /* Call user Tx complete callback */
02759 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02760   hspi->TxCpltCallback(hspi);
02761 #else
02762   HAL_SPI_TxCpltCallback(hspi);
02763 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02764 }
02765 
02766 /**
02767   * @brief  DMA SPI receive process complete callback.
02768   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02769   *               the configuration information for the specified DMA module.
02770   * @retval None
02771   */
02772 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
02773 {
02774   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
02775   uint32_t tickstart;
02776 #if (USE_SPI_CRC != 0U)
02777   __IO uint32_t tmpreg = 0U;
02778 #endif /* USE_SPI_CRC */
02779 
02780   /* Init tickstart for timeout management*/
02781   tickstart = HAL_GetTick();
02782 
02783   /* DMA Normal Mode */
02784   if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
02785   {
02786     /* Disable ERR interrupt */
02787     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
02788 
02789 #if (USE_SPI_CRC != 0U)
02790     /* CRC handling */
02791     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02792     {
02793       /* Wait until RXNE flag */
02794       if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
02795       {
02796         /* Error on the CRC reception */
02797         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
02798       }
02799       /* Read CRC */
02800       tmpreg = READ_REG(hspi->Instance->DR);
02801       /* To avoid GCC warning */
02802       UNUSED(tmpreg);
02803     }
02804 #endif /* USE_SPI_CRC */
02805 
02806     /* Check if we are in Master RX 2 line mode */
02807     if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
02808     {
02809       /* Disable Rx/Tx DMA Request (done by default to handle the case master rx direction 2 lines) */
02810       CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
02811     }
02812     else
02813     {
02814       /* Normal case */
02815       CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
02816     }
02817 
02818     /* Check the end of the transaction */
02819     if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
02820     {
02821       hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
02822     }
02823 
02824     hspi->RxXferCount = 0U;
02825     hspi->State = HAL_SPI_STATE_READY;
02826 
02827 #if (USE_SPI_CRC != 0U)
02828     /* Check if CRC error occurred */
02829     if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
02830     {
02831       /* Check if CRC error is valid or not (workaround to be applied or not) */
02832       if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
02833       {
02834         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
02835 
02836         /* Reset CRC Calculation */
02837         SPI_RESET_CRC(hspi);
02838       }
02839       else
02840       {
02841         __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
02842       }
02843     }
02844 #endif /* USE_SPI_CRC */
02845 
02846     if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
02847     {
02848       /* Call user error callback */
02849 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02850       hspi->ErrorCallback(hspi);
02851 #else
02852       HAL_SPI_ErrorCallback(hspi);
02853 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02854       return;
02855     }
02856   }
02857   /* Call user Rx complete callback */
02858 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02859   hspi->RxCpltCallback(hspi);
02860 #else
02861   HAL_SPI_RxCpltCallback(hspi);
02862 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02863 }
02864 
02865 /**
02866   * @brief  DMA SPI transmit receive process complete callback.
02867   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02868   *               the configuration information for the specified DMA module.
02869   * @retval None
02870   */
02871 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
02872 {
02873   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
02874   uint32_t tickstart;
02875 #if (USE_SPI_CRC != 0U)
02876   __IO uint32_t tmpreg = 0U;
02877 #endif /* USE_SPI_CRC */
02878 
02879   /* Init tickstart for timeout management*/
02880   tickstart = HAL_GetTick();
02881 
02882   /* DMA Normal Mode */
02883   if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
02884   {
02885     /* Disable ERR interrupt */
02886     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
02887 
02888 #if (USE_SPI_CRC != 0U)
02889     /* CRC handling */
02890     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02891     {
02892       /* Wait the CRC data */
02893       if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
02894       {
02895         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
02896       }
02897       /* Read CRC to Flush DR and RXNE flag */
02898       tmpreg = READ_REG(hspi->Instance->DR);
02899       /* To avoid GCC warning */
02900       UNUSED(tmpreg);
02901     }
02902 #endif /* USE_SPI_CRC */
02903 
02904     /* Check the end of the transaction */
02905     if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
02906     {
02907       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
02908     }
02909 
02910     /* Disable Rx/Tx DMA Request */
02911     CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
02912 
02913     hspi->TxXferCount = 0U;
02914     hspi->RxXferCount = 0U;
02915     hspi->State = HAL_SPI_STATE_READY;
02916 
02917 #if (USE_SPI_CRC != 0U)
02918     /* Check if CRC error occurred */
02919     if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
02920     {
02921       /* Check if CRC error is valid or not (workaround to be applied or not) */
02922       if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
02923       {
02924         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
02925 
02926         /* Reset CRC Calculation */
02927         SPI_RESET_CRC(hspi);
02928       }
02929       else
02930       {
02931         __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
02932       }
02933     }
02934 #endif /* USE_SPI_CRC */
02935 
02936     if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
02937     {
02938       /* Call user error callback */
02939 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02940       hspi->ErrorCallback(hspi);
02941 #else
02942       HAL_SPI_ErrorCallback(hspi);
02943 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02944       return;
02945     }
02946   }
02947   /* Call user TxRx complete callback */
02948 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02949   hspi->TxRxCpltCallback(hspi);
02950 #else
02951   HAL_SPI_TxRxCpltCallback(hspi);
02952 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02953 }
02954 
02955 /**
02956   * @brief  DMA SPI half transmit process complete callback.
02957   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02958   *               the configuration information for the specified DMA module.
02959   * @retval None
02960   */
02961 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma)
02962 {
02963   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
02964 
02965   /* Call user Tx half complete callback */
02966 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02967   hspi->TxHalfCpltCallback(hspi);
02968 #else
02969   HAL_SPI_TxHalfCpltCallback(hspi);
02970 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02971 }
02972 
02973 /**
02974   * @brief  DMA SPI half receive process complete callback
02975   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02976   *               the configuration information for the specified DMA module.
02977   * @retval None
02978   */
02979 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma)
02980 {
02981   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
02982 
02983   /* Call user Rx half complete callback */
02984 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
02985   hspi->RxHalfCpltCallback(hspi);
02986 #else
02987   HAL_SPI_RxHalfCpltCallback(hspi);
02988 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
02989 }
02990 
02991 /**
02992   * @brief  DMA SPI half transmit receive process complete callback.
02993   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02994   *               the configuration information for the specified DMA module.
02995   * @retval None
02996   */
02997 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
02998 {
02999   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
03000 
03001   /* Call user TxRx half complete callback */
03002 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03003   hspi->TxRxHalfCpltCallback(hspi);
03004 #else
03005   HAL_SPI_TxRxHalfCpltCallback(hspi);
03006 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03007 }
03008 
03009 /**
03010   * @brief  DMA SPI communication error callback.
03011   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
03012   *               the configuration information for the specified DMA module.
03013   * @retval None
03014   */
03015 static void SPI_DMAError(DMA_HandleTypeDef *hdma)
03016 {
03017   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
03018 
03019   /* Stop the disable DMA transfer on SPI side */
03020   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
03021 
03022   SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
03023   hspi->State = HAL_SPI_STATE_READY;
03024   /* Call user error callback */
03025 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03026   hspi->ErrorCallback(hspi);
03027 #else
03028   HAL_SPI_ErrorCallback(hspi);
03029 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03030 }
03031 
03032 /**
03033   * @brief  DMA SPI communication abort callback, when initiated by HAL services on Error
03034   *         (To be called at end of DMA Abort procedure following error occurrence).
03035   * @param  hdma DMA handle.
03036   * @retval None
03037   */
03038 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
03039 {
03040   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
03041   hspi->RxXferCount = 0U;
03042   hspi->TxXferCount = 0U;
03043 
03044   /* Call user error callback */
03045 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03046   hspi->ErrorCallback(hspi);
03047 #else
03048   HAL_SPI_ErrorCallback(hspi);
03049 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03050 }
03051 
03052 /**
03053   * @brief  DMA SPI Tx communication abort callback, when initiated by user
03054   *         (To be called at end of DMA Tx Abort procedure following user abort request).
03055   * @note   When this callback is executed, User Abort complete call back is called only if no
03056   *         Abort still ongoing for Rx DMA Handle.
03057   * @param  hdma DMA handle.
03058   * @retval None
03059   */
03060 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
03061 {
03062   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
03063   __IO uint32_t count;
03064 
03065   hspi->hdmatx->XferAbortCallback = NULL;
03066   count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
03067 
03068   /* Disable Tx DMA Request */
03069   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
03070 
03071   /* Wait until TXE flag is set */
03072   do
03073   {
03074     if (count == 0U)
03075     {
03076       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
03077       break;
03078     }
03079     count--;
03080   } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
03081 
03082   /* Check if an Abort process is still ongoing */
03083   if (hspi->hdmarx != NULL)
03084   {
03085     if (hspi->hdmarx->XferAbortCallback != NULL)
03086     {
03087       return;
03088     }
03089   }
03090 
03091   /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user Abort Complete callback */
03092   hspi->RxXferCount = 0U;
03093   hspi->TxXferCount = 0U;
03094 
03095   /* Check no error during Abort procedure */
03096   if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT)
03097   {
03098     /* Reset errorCode */
03099     hspi->ErrorCode = HAL_SPI_ERROR_NONE;
03100   }
03101 
03102   /* Clear the Error flags in the SR register */
03103   __HAL_SPI_CLEAR_OVRFLAG(hspi);
03104 
03105   /* Restore hspi->State to Ready */
03106   hspi->State  = HAL_SPI_STATE_READY;
03107 
03108   /* Call user Abort complete callback */
03109 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03110   hspi->AbortCpltCallback(hspi);
03111 #else
03112   HAL_SPI_AbortCpltCallback(hspi);
03113 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03114 }
03115 
03116 /**
03117   * @brief  DMA SPI Rx communication abort callback, when initiated by user
03118   *         (To be called at end of DMA Rx Abort procedure following user abort request).
03119   * @note   When this callback is executed, User Abort complete call back is called only if no
03120   *         Abort still ongoing for Tx DMA Handle.
03121   * @param  hdma DMA handle.
03122   * @retval None
03123   */
03124 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
03125 {
03126   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
03127 
03128   /* Disable SPI Peripheral */
03129   __HAL_SPI_DISABLE(hspi);
03130 
03131   hspi->hdmarx->XferAbortCallback = NULL;
03132 
03133   /* Disable Rx DMA Request */
03134   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
03135 
03136   /* Check Busy flag */
03137   if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
03138   {
03139     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
03140   }
03141 
03142   /* Check if an Abort process is still ongoing */
03143   if (hspi->hdmatx != NULL)
03144   {
03145     if (hspi->hdmatx->XferAbortCallback != NULL)
03146     {
03147       return;
03148     }
03149   }
03150 
03151   /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user Abort Complete callback */
03152   hspi->RxXferCount = 0U;
03153   hspi->TxXferCount = 0U;
03154 
03155   /* Check no error during Abort procedure */
03156   if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT)
03157   {
03158     /* Reset errorCode */
03159     hspi->ErrorCode = HAL_SPI_ERROR_NONE;
03160   }
03161 
03162   /* Clear the Error flags in the SR register */
03163   __HAL_SPI_CLEAR_OVRFLAG(hspi);
03164 
03165   /* Restore hspi->State to Ready */
03166   hspi->State  = HAL_SPI_STATE_READY;
03167 
03168   /* Call user Abort complete callback */
03169 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03170   hspi->AbortCpltCallback(hspi);
03171 #else
03172   HAL_SPI_AbortCpltCallback(hspi);
03173 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03174 }
03175 
03176 /**
03177   * @brief  Rx 8-bit handler for Transmit and Receive in Interrupt mode.
03178   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03179   *               the configuration information for SPI module.
03180   * @retval None
03181   */
03182 static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
03183 {
03184   /* Receive data in 8bit mode */
03185   *hspi->pRxBuffPtr = *((__IO uint8_t *)&hspi->Instance->DR);
03186   hspi->pRxBuffPtr++;
03187   hspi->RxXferCount--;
03188 
03189   /* Check end of the reception */
03190   if (hspi->RxXferCount == 0U)
03191   {
03192 #if (USE_SPI_CRC != 0U)
03193     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
03194     {
03195       hspi->RxISR =  SPI_2linesRxISR_8BITCRC;
03196       return;
03197     }
03198 #endif /* USE_SPI_CRC */
03199 
03200     /* Disable RXNE  and ERR interrupt */
03201     __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
03202 
03203     if (hspi->TxXferCount == 0U)
03204     {
03205       SPI_CloseRxTx_ISR(hspi);
03206     }
03207   }
03208 }
03209 
03210 #if (USE_SPI_CRC != 0U)
03211 /**
03212   * @brief  Rx 8-bit handler for Transmit and Receive in Interrupt mode.
03213   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03214   *               the configuration information for SPI module.
03215   * @retval None
03216   */
03217 static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
03218 {
03219   __IO uint8_t  * ptmpreg8;
03220   __IO uint8_t  tmpreg8 = 0;
03221 
03222   /* Initialize the 8bit temporary pointer */
03223   ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR;
03224   /* Read 8bit CRC to flush Data Register */
03225   tmpreg8 = *ptmpreg8;
03226   /* To avoid GCC warning */
03227   UNUSED(tmpreg8);
03228 
03229   /* Disable RXNE and ERR interrupt */
03230   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
03231 
03232   if (hspi->TxXferCount == 0U)
03233   {
03234     SPI_CloseRxTx_ISR(hspi);
03235   }
03236 }
03237 #endif /* USE_SPI_CRC */
03238 
03239 /**
03240   * @brief  Tx 8-bit handler for Transmit and Receive in Interrupt mode.
03241   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03242   *               the configuration information for SPI module.
03243   * @retval None
03244   */
03245 static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
03246 {
03247   *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);
03248   hspi->pTxBuffPtr++;
03249   hspi->TxXferCount--;
03250 
03251   /* Check the end of the transmission */
03252   if (hspi->TxXferCount == 0U)
03253   {
03254 #if (USE_SPI_CRC != 0U)
03255     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
03256     {
03257       /* Set CRC Next Bit to send CRC */
03258       SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
03259       /* Disable TXE interrupt */
03260       __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
03261       return;
03262     }
03263 #endif /* USE_SPI_CRC */
03264 
03265     /* Disable TXE interrupt */
03266     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
03267 
03268     if (hspi->RxXferCount == 0U)
03269     {
03270       SPI_CloseRxTx_ISR(hspi);
03271     }
03272   }
03273 }
03274 
03275 /**
03276   * @brief  Rx 16-bit handler for Transmit and Receive in Interrupt mode.
03277   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03278   *               the configuration information for SPI module.
03279   * @retval None
03280   */
03281 static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
03282 {
03283   /* Receive data in 16 Bit mode */
03284   *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR);
03285   hspi->pRxBuffPtr += sizeof(uint16_t);
03286   hspi->RxXferCount--;
03287 
03288   if (hspi->RxXferCount == 0U)
03289   {
03290 #if (USE_SPI_CRC != 0U)
03291     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
03292     {
03293       hspi->RxISR =  SPI_2linesRxISR_16BITCRC;
03294       return;
03295     }
03296 #endif /* USE_SPI_CRC */
03297 
03298     /* Disable RXNE interrupt */
03299     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
03300 
03301     if (hspi->TxXferCount == 0U)
03302     {
03303       SPI_CloseRxTx_ISR(hspi);
03304     }
03305   }
03306 }
03307 
03308 #if (USE_SPI_CRC != 0U)
03309 /**
03310   * @brief  Manage the CRC 16-bit receive for Transmit and Receive in Interrupt mode.
03311   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03312   *               the configuration information for SPI module.
03313   * @retval None
03314   */
03315 static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
03316 {
03317   __IO uint32_t tmpreg = 0U;
03318 
03319   /* Read 16bit CRC to flush Data Register */
03320   tmpreg = READ_REG(hspi->Instance->DR);
03321   /* To avoid GCC warning */
03322   UNUSED(tmpreg);  
03323 
03324   /* Disable RXNE interrupt */
03325   __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
03326 
03327   SPI_CloseRxTx_ISR(hspi);
03328 }
03329 #endif /* USE_SPI_CRC */
03330 
03331 /**
03332   * @brief  Tx 16-bit handler for Transmit and Receive in Interrupt mode.
03333   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03334   *               the configuration information for SPI module.
03335   * @retval None
03336   */
03337 static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
03338 {
03339   /* Transmit data in 16 Bit mode */
03340   hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
03341   hspi->pTxBuffPtr += sizeof(uint16_t);
03342   hspi->TxXferCount--;
03343 
03344   /* Enable CRC Transmission */
03345   if (hspi->TxXferCount == 0U)
03346   {
03347 #if (USE_SPI_CRC != 0U)
03348     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
03349     {
03350       /* Set CRC Next Bit to send CRC */
03351       SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
03352       /* Disable TXE interrupt */
03353       __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
03354       return;
03355     }
03356 #endif /* USE_SPI_CRC */
03357 
03358     /* Disable TXE interrupt */
03359     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
03360 
03361     if (hspi->RxXferCount == 0U)
03362     {
03363       SPI_CloseRxTx_ISR(hspi);
03364     }
03365   }
03366 }
03367 
03368 #if (USE_SPI_CRC != 0U)
03369 /**
03370   * @brief  Manage the CRC 8-bit receive in Interrupt context.
03371   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03372   *               the configuration information for SPI module.
03373   * @retval None
03374   */
03375 static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
03376 {
03377   __IO uint8_t  * ptmpreg8;
03378   __IO uint8_t  tmpreg8 = 0;
03379 
03380   /* Initialize the 8bit temporary pointer */
03381   ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR;
03382   /* Read 8bit CRC to flush Data Register */
03383   tmpreg8 = *ptmpreg8;
03384   /* To avoid GCC warning */
03385   UNUSED(tmpreg8);
03386 
03387   SPI_CloseRx_ISR(hspi);
03388 }
03389 #endif /* USE_SPI_CRC */
03390 
03391 /**
03392   * @brief  Manage the receive 8-bit in Interrupt context.
03393   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03394   *               the configuration information for SPI module.
03395   * @retval None
03396   */
03397 static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
03398 {
03399   *hspi->pRxBuffPtr = (*(__IO uint8_t *)&hspi->Instance->DR);
03400   hspi->pRxBuffPtr++;
03401   hspi->RxXferCount--;
03402 
03403 #if (USE_SPI_CRC != 0U)
03404   /* Enable CRC Transmission */
03405   if ((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
03406   {
03407     SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
03408   }
03409   /* Check if CRCNEXT is well reseted by hardware */
03410   if (READ_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT))
03411   {
03412     /* Workaround to force CRCNEXT bit to zero in case of CRCNEXT is not reset automatically by hardware */
03413     CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
03414   }
03415 
03416 #endif /* USE_SPI_CRC */
03417 
03418   if (hspi->RxXferCount == 0U)
03419   {
03420 #if (USE_SPI_CRC != 0U)
03421     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
03422     {
03423       hspi->RxISR =  SPI_RxISR_8BITCRC;
03424       return;
03425     }
03426 #endif /* USE_SPI_CRC */
03427     SPI_CloseRx_ISR(hspi);
03428   }
03429 }
03430 
03431 #if (USE_SPI_CRC != 0U)
03432 /**
03433   * @brief  Manage the CRC 16-bit receive in Interrupt context.
03434   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03435   *               the configuration information for SPI module.
03436   * @retval None
03437   */
03438 static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
03439 {
03440   __IO uint32_t tmpreg = 0U;
03441 
03442   /* Read 16bit CRC to flush Data Register */
03443   tmpreg = READ_REG(hspi->Instance->DR);
03444   /* To avoid GCC warning */
03445   UNUSED(tmpreg);
03446 
03447   /* Disable RXNE and ERR interrupt */
03448   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
03449 
03450   SPI_CloseRx_ISR(hspi);
03451 }
03452 #endif /* USE_SPI_CRC */
03453 
03454 /**
03455   * @brief  Manage the 16-bit receive in Interrupt context.
03456   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03457   *               the configuration information for SPI module.
03458   * @retval None
03459   */
03460 static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
03461 {
03462   *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR);
03463   hspi->pRxBuffPtr += sizeof(uint16_t);
03464   hspi->RxXferCount--;
03465 
03466 #if (USE_SPI_CRC != 0U)
03467   /* Enable CRC Transmission */
03468   if ((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
03469   {
03470     SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
03471   }
03472   /* Check if CRCNEXT is well reseted by hardware */
03473   if (READ_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT))
03474   {
03475     /* Workaround to force CRCNEXT bit to zero in case of CRCNEXT is not reset automatically by hardware */
03476     CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
03477   }
03478 
03479 #endif /* USE_SPI_CRC */
03480 
03481   if (hspi->RxXferCount == 0U)
03482   {
03483 #if (USE_SPI_CRC != 0U)
03484     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
03485     {
03486       hspi->RxISR = SPI_RxISR_16BITCRC;
03487       return;
03488     }
03489 #endif /* USE_SPI_CRC */
03490     SPI_CloseRx_ISR(hspi);
03491   }
03492 }
03493 
03494 /**
03495   * @brief  Handle the data 8-bit transmit in Interrupt mode.
03496   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03497   *               the configuration information for SPI module.
03498   * @retval None
03499   */
03500 static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
03501 {
03502   *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);
03503   hspi->pTxBuffPtr++;
03504   hspi->TxXferCount--;
03505 
03506   if (hspi->TxXferCount == 0U)
03507   {
03508 #if (USE_SPI_CRC != 0U)
03509     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
03510     {
03511       /* Enable CRC Transmission */
03512       SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
03513     }
03514 #endif /* USE_SPI_CRC */
03515     SPI_CloseTx_ISR(hspi);
03516   }
03517 }
03518 
03519 /**
03520   * @brief  Handle the data 16-bit transmit in Interrupt mode.
03521   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03522   *               the configuration information for SPI module.
03523   * @retval None
03524   */
03525 static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
03526 {
03527   /* Transmit data in 16 Bit mode */
03528   hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
03529   hspi->pTxBuffPtr += sizeof(uint16_t);
03530   hspi->TxXferCount--;
03531 
03532   if (hspi->TxXferCount == 0U)
03533   {
03534 #if (USE_SPI_CRC != 0U)
03535     if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
03536     {
03537       /* Enable CRC Transmission */
03538       SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
03539     }
03540 #endif /* USE_SPI_CRC */
03541     SPI_CloseTx_ISR(hspi);
03542   }
03543 }
03544 
03545 /**
03546   * @brief  Handle SPI Communication Timeout.
03547   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03548   *              the configuration information for SPI module.
03549   * @param  Flag SPI flag to check
03550   * @param  State flag state to check
03551   * @param  Timeout Timeout duration
03552   * @param  Tickstart tick start value
03553   * @retval HAL status
03554   */
03555 static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus State,
03556                                                        uint32_t Timeout, uint32_t Tickstart)
03557 {
03558   __IO uint32_t count;
03559   uint32_t tmp_timeout;
03560   uint32_t tmp_tickstart;
03561 
03562   /* Adjust Timeout value  in case of end of transfer */
03563   tmp_timeout   = Timeout - (HAL_GetTick() - Tickstart);
03564   tmp_tickstart = HAL_GetTick();
03565 
03566   /* Calculate Timeout based on a software loop to avoid blocking issue if Systick is disabled */
03567   count = tmp_timeout * ((SystemCoreClock * 32U) >> 20U);
03568 
03569   while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State)
03570   {
03571     if (Timeout != HAL_MAX_DELAY)
03572     {
03573       if (((HAL_GetTick() - tmp_tickstart) >= tmp_timeout) || (tmp_timeout == 0U))
03574       {
03575         /* Disable the SPI and reset the CRC: the CRC value should be cleared
03576            on both master and slave sides in order to resynchronize the master
03577            and slave for their respective CRC calculation */
03578 
03579         /* Disable TXE, RXNE and ERR interrupts for the interrupt process */
03580         __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
03581 
03582         if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE)
03583                                                      || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
03584         {
03585           /* Disable SPI peripheral */
03586           __HAL_SPI_DISABLE(hspi);
03587         }
03588 
03589         /* Reset CRC Calculation */
03590         if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
03591         {
03592           SPI_RESET_CRC(hspi);
03593         }
03594 
03595         hspi->State = HAL_SPI_STATE_READY;
03596 
03597         /* Process Unlocked */
03598         __HAL_UNLOCK(hspi);
03599 
03600         return HAL_TIMEOUT;
03601       }
03602       /* If Systick is disabled or not incremented, deactivate timeout to go in disable loop procedure */
03603       if(count == 0U)
03604       {
03605         tmp_timeout = 0U;
03606       }
03607       count--;
03608     }
03609   }
03610 
03611   return HAL_OK;
03612 }
03613 
03614 /**
03615   * @brief  Handle the check of the RX transaction complete.
03616   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03617   *               the configuration information for SPI module.
03618   * @param  Timeout Timeout duration
03619   * @param  Tickstart tick start value
03620   * @retval HAL status
03621   */
03622 static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi,  uint32_t Timeout, uint32_t Tickstart)
03623 {
03624   if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE)
03625                                                || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
03626   {
03627     /* Disable SPI peripheral */
03628     __HAL_SPI_DISABLE(hspi);
03629   }
03630 
03631   if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))
03632   {
03633     /* Wait the RXNE reset */
03634     if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout, Tickstart) != HAL_OK)
03635     {
03636       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03637       return HAL_TIMEOUT;
03638     }
03639   }
03640   else
03641   {
03642     /* Control the BSY flag */
03643     if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK)
03644     {
03645       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03646       return HAL_TIMEOUT;
03647     }
03648   }
03649   return HAL_OK;
03650 }
03651 
03652 /**
03653   * @brief  Handle the check of the RXTX or TX transaction complete.
03654   * @param  hspi SPI handle
03655   * @param  Timeout Timeout duration
03656   * @param  Tickstart tick start value
03657   * @retval HAL status
03658   */
03659 static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart)
03660 {
03661   /* Control the BSY flag */
03662   if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK)
03663   {
03664     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03665     return HAL_TIMEOUT;
03666   }
03667   return HAL_OK;
03668 }
03669 
03670 /**
03671   * @brief  Handle the end of the RXTX transaction.
03672   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03673   *               the configuration information for SPI module.
03674   * @retval None
03675   */
03676 static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi)
03677 {
03678   uint32_t tickstart;
03679   __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
03680 
03681   /* Init tickstart for timeout management */
03682   tickstart = HAL_GetTick();
03683 
03684   /* Disable ERR interrupt */
03685   __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
03686 
03687   /* Wait until TXE flag is set */
03688   do
03689   {
03690     if (count == 0U)
03691     {
03692       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03693       break;
03694     }
03695     count--;
03696   } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
03697 
03698   /* Check the end of the transaction */
03699   if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
03700   {
03701     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03702   }
03703 
03704   /* Clear overrun flag in 2 Lines communication mode because received is not read */
03705   if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
03706   {
03707     __HAL_SPI_CLEAR_OVRFLAG(hspi);
03708   }
03709 
03710 #if (USE_SPI_CRC != 0U)
03711   /* Check if CRC error occurred */
03712   if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
03713   {
03714     /* Check if CRC error is valid or not (workaround to be applied or not) */
03715     if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
03716     {
03717       hspi->State = HAL_SPI_STATE_READY;
03718       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
03719 
03720       /* Reset CRC Calculation */
03721       SPI_RESET_CRC(hspi);
03722 
03723       /* Call user error callback */
03724 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03725       hspi->ErrorCallback(hspi);
03726 #else
03727       HAL_SPI_ErrorCallback(hspi);
03728 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03729     }
03730     else
03731     {
03732       __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
03733     }
03734   }
03735   else
03736   {
03737 #endif /* USE_SPI_CRC */
03738     if (hspi->ErrorCode == HAL_SPI_ERROR_NONE)
03739     {
03740       if (hspi->State == HAL_SPI_STATE_BUSY_RX)
03741       {
03742         hspi->State = HAL_SPI_STATE_READY;
03743         /* Call user Rx complete callback */
03744 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03745         hspi->RxCpltCallback(hspi);
03746 #else
03747         HAL_SPI_RxCpltCallback(hspi);
03748 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03749       }
03750       else
03751       {
03752         hspi->State = HAL_SPI_STATE_READY;
03753         /* Call user TxRx complete callback */
03754 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03755         hspi->TxRxCpltCallback(hspi);
03756 #else
03757         HAL_SPI_TxRxCpltCallback(hspi);
03758 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03759       }
03760     }
03761     else
03762     {
03763       hspi->State = HAL_SPI_STATE_READY;
03764       /* Call user error callback */
03765 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03766       hspi->ErrorCallback(hspi);
03767 #else
03768       HAL_SPI_ErrorCallback(hspi);
03769 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03770     }
03771 #if (USE_SPI_CRC != 0U)
03772   }
03773 #endif /* USE_SPI_CRC */
03774 }
03775 
03776 /**
03777   * @brief  Handle the end of the RX transaction.
03778   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03779   *               the configuration information for SPI module.
03780   * @retval None
03781   */
03782 static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi)
03783 {
03784   /* Disable RXNE and ERR interrupt */
03785   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
03786 
03787   /* Check the end of the transaction */
03788   if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
03789   {
03790     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03791   }
03792 
03793   /* Clear overrun flag in 2 Lines communication mode because received is not read */
03794   if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
03795   {
03796     __HAL_SPI_CLEAR_OVRFLAG(hspi);
03797   }
03798   hspi->State = HAL_SPI_STATE_READY;
03799 
03800 #if (USE_SPI_CRC != 0U)
03801   /* Check if CRC error occurred */
03802   if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
03803   {
03804     /* Check if CRC error is valid or not (workaround to be applied or not) */
03805     if (SPI_ISCRCErrorValid(hspi) == SPI_VALID_CRC_ERROR)
03806     {
03807       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
03808 
03809       /* Reset CRC Calculation */
03810       SPI_RESET_CRC(hspi);
03811 
03812       /* Call user error callback */
03813 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03814       hspi->ErrorCallback(hspi);
03815 #else
03816       HAL_SPI_ErrorCallback(hspi);
03817 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03818     }
03819     else
03820     {
03821       __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
03822     }
03823   }
03824   else
03825   {
03826 #endif /* USE_SPI_CRC */
03827     if (hspi->ErrorCode == HAL_SPI_ERROR_NONE)
03828     {
03829       /* Call user Rx complete callback */
03830 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03831       hspi->RxCpltCallback(hspi);
03832 #else
03833       HAL_SPI_RxCpltCallback(hspi);
03834 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03835     }
03836     else
03837     {
03838       /* Call user error callback */
03839 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03840       hspi->ErrorCallback(hspi);
03841 #else
03842       HAL_SPI_ErrorCallback(hspi);
03843 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03844     }
03845 #if (USE_SPI_CRC != 0U)
03846   }
03847 #endif /* USE_SPI_CRC */
03848 }
03849 
03850 /**
03851   * @brief  Handle the end of the TX transaction.
03852   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03853   *               the configuration information for SPI module.
03854   * @retval None
03855   */
03856 static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi)
03857 {
03858   uint32_t tickstart;
03859   __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
03860 
03861   /* Init tickstart for timeout management*/
03862   tickstart = HAL_GetTick();
03863 
03864   /* Wait until TXE flag is set */
03865   do
03866   {
03867     if (count == 0U)
03868     {
03869       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03870       break;
03871     }
03872     count--;
03873   } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
03874 
03875   /* Disable TXE and ERR interrupt */
03876   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
03877 
03878   /* Check the end of the transaction */
03879   if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
03880   {
03881     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03882   }
03883 
03884   /* Clear overrun flag in 2 Lines communication mode because received is not read */
03885   if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
03886   {
03887     __HAL_SPI_CLEAR_OVRFLAG(hspi);
03888   }
03889 
03890   hspi->State = HAL_SPI_STATE_READY;
03891   if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
03892   {
03893     /* Call user error callback */
03894 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03895     hspi->ErrorCallback(hspi);
03896 #else
03897     HAL_SPI_ErrorCallback(hspi);
03898 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03899   }
03900   else
03901   {
03902     /* Call user Rx complete callback */
03903 #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
03904     hspi->TxCpltCallback(hspi);
03905 #else
03906     HAL_SPI_TxCpltCallback(hspi);
03907 #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
03908   }
03909 }
03910 
03911 /**
03912   * @brief  Handle abort a Rx transaction.
03913   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03914   *               the configuration information for SPI module.
03915   * @retval None
03916   */
03917 static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi)
03918 {
03919   __IO uint32_t tmpreg = 0U;
03920   __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
03921 
03922   /* Wait until TXE flag is set */
03923   do
03924   {
03925     if (count == 0U)
03926     {
03927       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
03928       break;
03929     }
03930     count--;
03931   } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
03932 
03933   /* Disable SPI Peripheral */
03934   __HAL_SPI_DISABLE(hspi);
03935 
03936   /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
03937   CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE));
03938 
03939   /* Flush Data Register by a blank read */
03940   tmpreg = READ_REG(hspi->Instance->DR);
03941   /* To avoid GCC warning */
03942   UNUSED(tmpreg);
03943 
03944   hspi->State = HAL_SPI_STATE_ABORT;
03945 }
03946 
03947 /**
03948   * @brief  Handle abort a Tx or Rx/Tx transaction.
03949   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03950   *               the configuration information for SPI module.
03951   * @retval None
03952   */
03953 static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi)
03954 {
03955   /* Disable TXEIE interrupt */
03956   CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE));
03957 
03958   /* Disable SPI Peripheral */
03959   __HAL_SPI_DISABLE(hspi);
03960 
03961   hspi->State = HAL_SPI_STATE_ABORT;
03962 }
03963 
03964 #if (USE_SPI_CRC != 0U)
03965 /**
03966   * @brief  Checks if encountered CRC error could be corresponding to wrongly detected errors
03967   *         according to SPI instance, Device type, and revision ID.
03968   * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
03969   *               the configuration information for SPI module.
03970   * @retval CRC error validity (SPI_INVALID_CRC_ERROR or SPI_VALID_CRC_ERROR).
03971   */
03972 uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi)
03973 {
03974 #if defined(SPI_CRC_ERROR_WORKAROUND_FEATURE) && (USE_SPI_CRC_ERROR_WORKAROUND != 0U)
03975   /* Check how to handle this CRC error (workaround to be applied or not) */
03976   /* If CRC errors could be wrongly detected (issue 2.15.2 in STM32F10xxC/D/E silicon limitations ES (DocID14732 Rev 13) */
03977   if (hspi->Instance == SPI2)
03978   {
03979     if (hspi->Instance->RXCRCR == 0U)
03980     {
03981       return (SPI_INVALID_CRC_ERROR);
03982     }
03983   }
03984 #endif
03985   /* Prevent unused argument(s) compilation warning */
03986   UNUSED(hspi);
03987 
03988   return (SPI_VALID_CRC_ERROR);
03989 }
03990 #endif /* USE_SPI_CRC */
03991 /**
03992   * @}
03993   */
03994 
03995 #endif /* HAL_SPI_MODULE_ENABLED */
03996 
03997 /**
03998   * @}
03999   */
04000 
04001 /**
04002   * @}
04003   */
04004 
04005 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/