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