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