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