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