STM32F439xx HAL User Manual
stm32f4xx_hal_spi.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_hal_spi.c
00004   * @author  MCD Application Team
00005   * @brief   SPI HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the Serial Peripheral Interface (SPI) peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + IO operation functions
00010   *           + Peripheral Control functions
00011   *           + Peripheral State functions
00012   *
00013   @verbatim
00014   ==============================================================================
00015                         ##### How to use this driver #####
00016   ==============================================================================
00017     [..]
00018       The SPI HAL driver can be used as follows:
00019 
00020       (#) Declare a SPI_HandleTypeDef handle structure, for example:
00021           SPI_HandleTypeDef  hspi;
00022 
00023       (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
00024           (##) Enable the SPIx interface clock
00025           (##) SPI pins configuration
00026               (+++) Enable the clock for the SPI GPIOs
00027               (+++) Configure these SPI pins as alternate function push-pull
00028           (##) NVIC configuration if you need to use interrupt process
00029               (+++) Configure the SPIx interrupt priority
00030               (+++) Enable the NVIC SPI IRQ handle
00031           (##) DMA Configuration if you need to use DMA process
00032               (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream
00033               (+++) Enable the DMAx clock
00034               (+++) Configure the DMA handle parameters
00035               (+++) Configure the DMA Tx or Rx stream
00036               (+++) Associate the initialized hdma_tx handle to the hspi DMA Tx or Rx handle
00037               (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx stream
00038 
00039       (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
00040           management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.
00041 
00042       (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:
00043           (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
00044               by calling the customized HAL_SPI_MspInit() API.
00045      [..]
00046        Circular mode restriction:
00047       (#) The DMA circular mode cannot be used when the SPI is configured in these modes:
00048           (##) Master 2Lines RxOnly
00049           (##) Master 1Line Rx
00050       (#) The CRC feature is not managed when the DMA circular mode is enabled
00051       (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs
00052           the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks
00053      [..]
00054        Master Receive mode restriction:
00055       (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=0) or
00056           bidirectional receive mode (MSTR=1, BIDIMODE=1, BIDIOE=0), to ensure that the SPI
00057           does not initiate a new transfer the following procedure has to be respected:
00058           (##) HAL_SPI_DeInit()
00059           (##) HAL_SPI_Init()
00060 
00061   @endverbatim
00062 
00063     Using the HAL it is not possible to reach all supported SPI frequency with the differents SPI Modes,
00064     the following tables resume the max SPI frequency reached with data size 8bits/16bits,
00065     according to frequency used on APBx Peripheral Clock (fPCLK) used by the SPI instance :
00066     
00067     DataSize = SPI_DATASIZE_8BIT:
00068     +----------------------------------------------------------------------------------------------+
00069     |         |                | 2Lines Fullduplex   |     2Lines RxOnly    |         1Line        |
00070     | Process | Tranfert mode  |---------------------|----------------------|----------------------|
00071     |         |                |  Master  |  Slave   |  Master   |  Slave   |  Master   |  Slave   |
00072     |==============================================================================================|
00073     |    T    |     Polling    | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
00074     |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00075     |    /    |     Interrupt  | Fpclk/4  | Fpclk/8  |    NA     |    NA    |    NA     |   NA     |
00076     |    R    |----------------|----------|----------|-----------|----------|-----------|----------|
00077     |    X    |       DMA      | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
00078     |=========|================|==========|==========|===========|==========|===========|==========|
00079     |         |     Polling    | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/64  | Fpclk/2  |
00080     |         |----------------|----------|----------|-----------|----------|-----------|----------|
00081     |    R    |     Interrupt  | Fpclk/8  | Fpclk/8  | Fpclk/64  | Fpclk/2  | Fpclk/64  | Fpclk/2  |
00082     |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00083     |         |       DMA      | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/128 | Fpclk/2  |
00084     |=========|================|==========|==========|===========|==========|===========|==========|
00085     |         |     Polling    | Fpclk/2  | Fpclk/4  |     NA    |    NA    | Fpclk/2   | Fpclk/64 |
00086     |         |----------------|----------|----------|-----------|----------|-----------|----------|
00087     |    T    |     Interrupt  | Fpclk/2  | Fpclk/4  |     NA    |    NA    | Fpclk/2   | Fpclk/64 |
00088     |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00089     |         |       DMA      | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/128|
00090     +----------------------------------------------------------------------------------------------+
00091     
00092     DataSize = SPI_DATASIZE_16BIT:
00093     +----------------------------------------------------------------------------------------------+
00094     |         |                | 2Lines Fullduplex   |     2Lines RxOnly    |         1Line        |
00095     | Process | Tranfert mode  |---------------------|----------------------|----------------------|
00096     |         |                |  Master  |  Slave   |  Master   |  Slave   |  Master   |  Slave   |
00097     |==============================================================================================|
00098     |    T    |     Polling    | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
00099     |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00100     |    /    |     Interrupt  | Fpclk/4  | Fpclk/4  |    NA     |    NA    |    NA     |   NA     |
00101     |    R    |----------------|----------|----------|-----------|----------|-----------|----------|
00102     |    X    |       DMA      | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
00103     |=========|================|==========|==========|===========|==========|===========|==========|
00104     |         |     Polling    | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/32  | Fpclk/2  |
00105     |         |----------------|----------|----------|-----------|----------|-----------|----------|
00106     |    R    |     Interrupt  | Fpclk/4  | Fpclk/4  | Fpclk/64  | Fpclk/2  | Fpclk/64  | Fpclk/2  |
00107     |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00108     |         |       DMA      | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/128 | Fpclk/2  |
00109     |=========|================|==========|==========|===========|==========|===========|==========|
00110     |         |     Polling    | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/32 |
00111     |         |----------------|----------|----------|-----------|----------|-----------|----------|
00112     |    T    |     Interrupt  | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/64 |
00113     |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
00114     |         |       DMA      | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/128|
00115     +----------------------------------------------------------------------------------------------+
00116      [..]
00117        (@) The max SPI frequency depend on SPI data size (8bits, 16bits),
00118            SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA).
00119        (@)
00120             (+@) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA()
00121             (+@) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA()
00122             (+@) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA()
00123   ******************************************************************************
00124   * @attention
00125   *
00126   * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
00127   *
00128   * Redistribution and use in source and binary forms, with or without modification,
00129   * are permitted provided that the following conditions are met:
00130   *   1. Redistributions of source code must retain the above copyright notice,
00131   *      this list of conditions and the following disclaimer.
00132   *   2. Redistributions in binary form must reproduce the above copyright notice,
00133   *      this list of conditions and the following disclaimer in the documentation
00134   *      and/or other materials provided with the distribution.
00135   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00136   *      may be used to endorse or promote products derived from this software
00137   *      without specific prior written permission.
00138   *
00139   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00140   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00141   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00142   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00143   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00144   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00145   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00146   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00147   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00148   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00149   *
00150   ******************************************************************************
00151   */
00152 
00153 /* Includes ------------------------------------------------------------------*/
00154 #include "stm32f4xx_hal.h"
00155 
00156 /** @addtogroup STM32F4xx_HAL_Driver
00157   * @{
00158   */
00159 /** @defgroup SPI SPI
00160   * @brief SPI HAL module driver
00161   * @{
00162   */
00163 #ifdef HAL_SPI_MODULE_ENABLED
00164 
00165 /* Private typedef -----------------------------------------------------------*/
00166 /* Private defines -----------------------------------------------------------*/
00167 /** @defgroup SPI_Private_Constants SPI Private Constants
00168   * @{
00169   */
00170 #define SPI_DEFAULT_TIMEOUT 100U
00171 /**
00172   * @}
00173   */
00174 
00175 /* Private macros ------------------------------------------------------------*/
00176 /* Private variables ---------------------------------------------------------*/
00177 /* Private function prototypes -----------------------------------------------*/
00178 /** @addtogroup SPI_Private_Functions
00179   * @{
00180   */
00181 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00182 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00183 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
00184 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
00185 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
00186 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
00187 static void SPI_DMAError(DMA_HandleTypeDef *hdma);
00188 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
00189 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
00190 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
00191 static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart);
00192 static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
00193 static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
00194 static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
00195 static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
00196 static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
00197 static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
00198 static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
00199 static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
00200 #if (USE_SPI_CRC != 0U)
00201 static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
00202 static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
00203 static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
00204 static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
00205 #endif /* USE_SPI_CRC */
00206 static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi);
00207 static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi);
00208 static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi);
00209 static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi);
00210 static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi);
00211 static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
00212 /**
00213   * @}
00214   */
00215 
00216 /* Exported functions --------------------------------------------------------*/
00217 /** @defgroup SPI_Exported_Functions SPI Exported Functions
00218   * @{
00219   */
00220 
00221 /** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
00222  *  @brief    Initialization and Configuration functions
00223  *
00224 @verbatim
00225  ===============================================================================
00226               ##### Initialization and de-initialization functions #####
00227  ===============================================================================
00228     [..]  This subsection provides a set of functions allowing to initialize and
00229           de-initialize the SPIx peripheral:
00230 
00231       (+) User must implement HAL_SPI_MspInit() function in which he configures
00232           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
00233 
00234       (+) Call the function HAL_SPI_Init() to configure the selected device with
00235           the selected configuration:
00236         (++) Mode
00237         (++) Direction
00238         (++) Data Size
00239         (++) Clock Polarity and Phase
00240         (++) NSS Management
00241         (++) BaudRate Prescaler
00242         (++) FirstBit
00243         (++) TIMode
00244         (++) CRC Calculation
00245         (++) CRC Polynomial if CRC enabled
00246 
00247       (+) Call the function HAL_SPI_DeInit() to restore the default configuration
00248           of the selected SPIx peripheral.
00249 
00250 @endverbatim
00251   * @{
00252   */
00253 
00254 /**
00255   * @brief  Initialize the SPI according to the specified parameters
00256   *         in the SPI_InitTypeDef and initialize the associated handle.
00257   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00258   *               the configuration information for SPI module.
00259   * @retval HAL status
00260   */
00261 HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
00262 {
00263   /* Check the SPI handle allocation */
00264   if(hspi == NULL)
00265   {
00266     return HAL_ERROR;
00267   }
00268 
00269   /* Check the parameters */
00270   assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
00271   assert_param(IS_SPI_MODE(hspi->Init.Mode));
00272   assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
00273   assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
00274   assert_param(IS_SPI_NSS(hspi->Init.NSS));
00275   assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
00276   assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
00277   assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
00278   if(hspi->Init.TIMode == SPI_TIMODE_DISABLE)
00279   {
00280     assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
00281     assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
00282   }
00283 #if (USE_SPI_CRC != 0U)
00284   assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
00285   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00286   {
00287     assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
00288   }
00289 #else
00290   hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
00291 #endif /* USE_SPI_CRC */
00292 
00293   if(hspi->State == HAL_SPI_STATE_RESET)
00294   {
00295     /* Allocate lock resource and initialize it */
00296     hspi->Lock = HAL_UNLOCKED;
00297 
00298     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
00299     HAL_SPI_MspInit(hspi);
00300   }
00301 
00302   hspi->State = HAL_SPI_STATE_BUSY;
00303 
00304   /* Disable the selected SPI peripheral */
00305   __HAL_SPI_DISABLE(hspi);
00306 
00307   /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
00308   /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
00309   Communication speed, First bit and CRC calculation state */
00310   WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
00311                                   hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
00312                                   hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit  | hspi->Init.CRCCalculation) );
00313 
00314   /* Configure : NSS management */
00315   WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode));
00316 
00317 #if (USE_SPI_CRC != 0U)
00318   /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
00319   /* Configure : CRC Polynomial */
00320   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00321   {
00322     WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);
00323   }
00324 #endif /* USE_SPI_CRC */
00325 
00326 #if defined(SPI_I2SCFGR_I2SMOD)
00327   /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
00328   CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
00329 #endif /* USE_SPI_CRC */
00330 
00331   hspi->ErrorCode = HAL_SPI_ERROR_NONE;
00332   hspi->State     = HAL_SPI_STATE_READY;
00333 
00334   return HAL_OK;
00335 }
00336 
00337 /**
00338   * @brief  De Initialize the SPI peripheral.
00339   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00340   *               the configuration information for SPI module.
00341   * @retval HAL status
00342   */
00343 HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
00344 {
00345   /* Check the SPI handle allocation */
00346   if(hspi == NULL)
00347   {
00348     return HAL_ERROR;
00349   }
00350 
00351   /* Check SPI Instance parameter */
00352   assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
00353 
00354   hspi->State = HAL_SPI_STATE_BUSY;
00355 
00356   /* Disable the SPI Peripheral Clock */
00357   __HAL_SPI_DISABLE(hspi);
00358 
00359   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
00360   HAL_SPI_MspDeInit(hspi);
00361 
00362   hspi->ErrorCode = HAL_SPI_ERROR_NONE;
00363   hspi->State = HAL_SPI_STATE_RESET;
00364 
00365   /* Release Lock */
00366   __HAL_UNLOCK(hspi);
00367 
00368   return HAL_OK;
00369 }
00370 
00371 /**
00372   * @brief  Initialize the SPI MSP.
00373   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00374   *               the configuration information for SPI module.
00375   * @retval None
00376   */
00377 __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
00378 {
00379   /* Prevent unused argument(s) compilation warning */
00380   UNUSED(hspi);
00381   /* NOTE : This function should not be modified, when the callback is needed,
00382             the HAL_SPI_MspInit should be implemented in the user file
00383   */
00384 }
00385 
00386 /**
00387   * @brief  De-Initialize the SPI MSP.
00388   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00389   *               the configuration information for SPI module.
00390   * @retval None
00391   */
00392 __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
00393 {
00394   /* Prevent unused argument(s) compilation warning */
00395   UNUSED(hspi);
00396   /* NOTE : This function should not be modified, when the callback is needed,
00397             the HAL_SPI_MspDeInit should be implemented in the user file
00398   */
00399 }
00400 
00401 /**
00402   * @}
00403   */
00404 
00405 /** @defgroup SPI_Exported_Functions_Group2 IO operation functions
00406  *  @brief   Data transfers functions
00407  *
00408 @verbatim
00409   ==============================================================================
00410                       ##### IO operation functions #####
00411  ===============================================================================
00412  [..]
00413     This subsection provides a set of functions allowing to manage the SPI
00414     data transfers.
00415 
00416     [..] The SPI supports master and slave mode :
00417 
00418     (#) There are two modes of transfer:
00419        (++) Blocking mode: The communication is performed in polling mode.
00420             The HAL status of all data processing is returned by the same function
00421             after finishing transfer.
00422        (++) No-Blocking mode: The communication is performed using Interrupts
00423             or DMA, These APIs return the HAL status.
00424             The end of the data processing will be indicated through the
00425             dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
00426             using DMA mode.
00427             The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
00428             will be executed respectively at the end of the transmit or Receive process
00429             The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected
00430 
00431     (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
00432         exist for 1Line (simplex) and 2Lines (full duplex) modes.
00433 
00434 @endverbatim
00435   * @{
00436   */
00437 
00438 /**
00439   * @brief  Transmit an amount of data in blocking mode.
00440   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00441   *               the configuration information for SPI module.
00442   * @param  pData pointer to data buffer
00443   * @param  Size amount of data to be sent
00444   * @param  Timeout Timeout duration
00445   * @retval HAL status
00446   */
00447 HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00448 {
00449   uint32_t tickstart = 0U;
00450   HAL_StatusTypeDef errorcode = HAL_OK;
00451 
00452   /* Check Direction parameter */
00453   assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
00454 
00455   /* Process Locked */
00456   __HAL_LOCK(hspi);
00457 
00458   /* Init tickstart for timeout management*/
00459   tickstart = HAL_GetTick();
00460 
00461   if(hspi->State != HAL_SPI_STATE_READY)
00462   {
00463     errorcode = HAL_BUSY;
00464     goto error;
00465   }
00466 
00467   if((pData == NULL ) || (Size == 0))
00468   {
00469     errorcode = HAL_ERROR;
00470     goto error;
00471   }
00472 
00473   /* Set the transaction information */
00474   hspi->State       = HAL_SPI_STATE_BUSY_TX;
00475   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
00476   hspi->pTxBuffPtr  = (uint8_t *)pData;
00477   hspi->TxXferSize  = Size;
00478   hspi->TxXferCount = Size;
00479 
00480   /*Init field not used in handle to zero */
00481   hspi->pRxBuffPtr  = (uint8_t *)NULL;
00482   hspi->RxXferSize  = 0U;
00483   hspi->RxXferCount = 0U;
00484   hspi->TxISR       = NULL;
00485   hspi->RxISR       = NULL;
00486 
00487   /* Configure communication direction : 1Line */
00488   if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
00489   {
00490     SPI_1LINE_TX(hspi);
00491   }
00492 
00493 #if (USE_SPI_CRC != 0U)
00494   /* Reset CRC Calculation */
00495   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00496   {
00497     SPI_RESET_CRC(hspi);
00498   }
00499 #endif /* USE_SPI_CRC */
00500 
00501   /* Check if the SPI is already enabled */
00502   if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
00503   {
00504     /* Enable SPI peripheral */
00505     __HAL_SPI_ENABLE(hspi);
00506   }
00507 
00508   /* Transmit data in 16 Bit mode */
00509   if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
00510   {
00511     if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01))
00512     {
00513       hspi->Instance->DR = *((uint16_t *)pData);
00514       pData += sizeof(uint16_t);
00515       hspi->TxXferCount--;
00516     }
00517     /* Transmit data in 16 Bit mode */
00518     while (hspi->TxXferCount > 0U)
00519     {
00520       /* Wait until TXE flag is set to send data */
00521       if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
00522       {
00523           hspi->Instance->DR = *((uint16_t *)pData);
00524           pData += sizeof(uint16_t);
00525           hspi->TxXferCount--;
00526       }
00527       else
00528       {
00529         /* Timeout management */
00530         if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
00531         {
00532           errorcode = HAL_TIMEOUT;
00533           goto error;
00534         }
00535       }
00536     }
00537   }
00538   /* Transmit data in 8 Bit mode */
00539   else
00540   {
00541     if((hspi->Init.Mode == SPI_MODE_SLAVE)|| (hspi->TxXferCount == 0x01))
00542     {
00543       *((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
00544       pData += sizeof(uint8_t);
00545       hspi->TxXferCount--;
00546     }
00547     while (hspi->TxXferCount > 0U)
00548     {
00549       /* Wait until TXE flag is set to send data */
00550       if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
00551       {
00552         *((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
00553         pData += sizeof(uint8_t);
00554         hspi->TxXferCount--;
00555       }
00556       else
00557       {
00558         /* Timeout management */
00559         if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
00560         {
00561           errorcode = HAL_TIMEOUT;
00562           goto error;
00563         }
00564       }
00565     }
00566   }
00567 
00568   /* Wait until TXE flag */
00569   if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
00570   {
00571     errorcode = HAL_TIMEOUT;
00572     goto error;
00573   }
00574   
00575   /* Check Busy flag */
00576   if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
00577   {
00578     errorcode = HAL_ERROR;
00579     hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
00580     goto error;
00581   }
00582 
00583   /* Clear overrun flag in 2 Lines communication mode because received is not read */
00584   if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
00585   {
00586     __HAL_SPI_CLEAR_OVRFLAG(hspi);
00587   }
00588 #if (USE_SPI_CRC != 0U)
00589   /* Enable CRC Transmission */
00590   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00591   {
00592      SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
00593   }
00594 #endif /* USE_SPI_CRC */
00595 
00596   if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
00597   {
00598     errorcode = HAL_ERROR;
00599   }
00600 
00601 error:
00602   hspi->State = HAL_SPI_STATE_READY;
00603   /* Process Unlocked */
00604   __HAL_UNLOCK(hspi);
00605   return errorcode;
00606 }
00607 
00608 /**
00609   * @brief  Receive an amount of data in blocking mode.
00610   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00611   *               the configuration information for SPI module.
00612   * @param  pData pointer to data buffer
00613   * @param  Size amount of data to be received
00614   * @param  Timeout Timeout duration
00615   * @retval HAL status
00616   */
00617 HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
00618 {
00619 #if (USE_SPI_CRC != 0U)
00620   __IO uint16_t tmpreg = 0U;
00621 #endif /* USE_SPI_CRC */
00622   uint32_t tickstart = 0U;
00623   HAL_StatusTypeDef errorcode = HAL_OK;
00624 
00625   if((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
00626   {
00627      hspi->State = HAL_SPI_STATE_BUSY_RX;
00628      /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
00629     return HAL_SPI_TransmitReceive(hspi,pData,pData,Size,Timeout);
00630   }
00631 
00632   /* Process Locked */
00633   __HAL_LOCK(hspi);
00634 
00635   /* Init tickstart for timeout management*/
00636   tickstart = HAL_GetTick();
00637 
00638   if(hspi->State != HAL_SPI_STATE_READY)
00639   {
00640     errorcode = HAL_BUSY;
00641     goto error;
00642   }
00643 
00644   if((pData == NULL ) || (Size == 0))
00645   {
00646     errorcode = HAL_ERROR;
00647     goto error;
00648   }
00649 
00650   /* Set the transaction information */
00651   hspi->State       = HAL_SPI_STATE_BUSY_RX;
00652   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
00653   hspi->pRxBuffPtr  = (uint8_t *)pData;
00654   hspi->RxXferSize  = Size;
00655   hspi->RxXferCount = Size;
00656 
00657   /*Init field not used in handle to zero */
00658   hspi->pTxBuffPtr  = (uint8_t *)NULL;
00659   hspi->TxXferSize  = 0U;
00660   hspi->TxXferCount = 0U;
00661   hspi->RxISR       = NULL;
00662   hspi->TxISR       = NULL;
00663 
00664 #if (USE_SPI_CRC != 0U)
00665   /* Reset CRC Calculation */
00666   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00667   {
00668     SPI_RESET_CRC(hspi);
00669     /* this is done to handle the CRCNEXT before the latest data */
00670     hspi->RxXferCount--;
00671   }
00672 #endif /* USE_SPI_CRC */
00673 
00674   /* Configure communication direction: 1Line */
00675   if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
00676   {
00677     SPI_1LINE_RX(hspi);
00678   }
00679 
00680   /* Check if the SPI is already enabled */
00681   if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
00682   {
00683     /* Enable SPI peripheral */
00684     __HAL_SPI_ENABLE(hspi);
00685   }
00686 
00687     /* Receive data in 8 Bit mode */
00688   if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
00689   {
00690     /* Transfer loop */
00691     while(hspi->RxXferCount > 0U)
00692     {
00693       /* Check the RXNE flag */
00694       if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
00695       {
00696         /* read the received data */
00697         (* (uint8_t *)pData)= *(__IO uint8_t *)&hspi->Instance->DR;
00698         pData += sizeof(uint8_t);
00699         hspi->RxXferCount--;
00700       }
00701       else
00702       {
00703         /* Timeout management */
00704         if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
00705         {
00706           errorcode = HAL_TIMEOUT;
00707           goto error;
00708         }
00709       }
00710     }
00711   }
00712   else
00713   {
00714     /* Transfer loop */
00715     while(hspi->RxXferCount > 0U)
00716     {
00717       /* Check the RXNE flag */
00718       if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
00719       {
00720         *((uint16_t*)pData) = hspi->Instance->DR;
00721         pData += sizeof(uint16_t);
00722         hspi->RxXferCount--;
00723       }
00724       else
00725       {
00726         /* Timeout management */
00727         if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
00728         {
00729           errorcode = HAL_TIMEOUT;
00730           goto error;
00731         }
00732       }
00733     }
00734   }
00735 
00736 #if (USE_SPI_CRC != 0U)
00737   /* Handle the CRC Transmission */
00738   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00739   {
00740     /* freeze the CRC before the latest data */
00741     SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
00742 
00743     /* Read the latest data */
00744     if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
00745     {
00746       /* the latest data has not been received */
00747       errorcode = HAL_TIMEOUT;
00748       goto error;
00749     }
00750 
00751     /* Receive last data in 16 Bit mode */
00752     if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
00753     {
00754       *((uint16_t*)pData) = hspi->Instance->DR;
00755     }
00756     /* Receive last data in 8 Bit mode */
00757     else
00758     {
00759       (*(uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR;
00760     }
00761 
00762     /* Wait the CRC data */
00763     if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
00764     {
00765       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
00766       errorcode = HAL_TIMEOUT;
00767       goto error;
00768     }
00769 
00770     /* Read CRC to Flush DR and RXNE flag */
00771     tmpreg = hspi->Instance->DR;
00772     /* To avoid GCC warning */
00773     UNUSED(tmpreg);
00774   }
00775 #endif /* USE_SPI_CRC */
00776 
00777   /* Check the end of the transaction */
00778   if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
00779   {
00780     /* Disable SPI peripheral */
00781     __HAL_SPI_DISABLE(hspi);
00782   }
00783 
00784 #if (USE_SPI_CRC != 0U)
00785   /* Check if CRC error occurred */
00786   if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR))
00787   {
00788     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
00789     __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
00790   }
00791 #endif /* USE_SPI_CRC */
00792 
00793   if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
00794   {
00795     errorcode = HAL_ERROR;
00796   }
00797 
00798 error :
00799   hspi->State = HAL_SPI_STATE_READY;
00800   __HAL_UNLOCK(hspi);
00801   return errorcode;
00802 }
00803 
00804 /**
00805   * @brief  Transmit and Receive an amount of data in blocking mode.
00806   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
00807   *               the configuration information for SPI module.
00808   * @param  pTxData pointer to transmission data buffer
00809   * @param  pRxData pointer to reception data buffer
00810   * @param  Size amount of data to be sent and received
00811   * @param  Timeout Timeout duration
00812   * @retval HAL status
00813   */
00814 HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
00815 {
00816   uint32_t tmp = 0U, tmp1 = 0U;
00817 #if (USE_SPI_CRC != 0U)
00818   __IO uint16_t tmpreg1 = 0U;
00819 #endif /* USE_SPI_CRC */
00820   uint32_t tickstart = 0U;
00821   /* Variable used to alternate Rx and Tx during transfer */
00822   uint32_t txallowed = 1U;
00823   HAL_StatusTypeDef errorcode = HAL_OK;
00824 
00825   /* Check Direction parameter */
00826   assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
00827 
00828   /* Process Locked */
00829   __HAL_LOCK(hspi);
00830 
00831   /* Init tickstart for timeout management*/
00832   tickstart = HAL_GetTick();
00833   
00834   tmp  = hspi->State;
00835   tmp1 = hspi->Init.Mode;
00836   
00837   if(!((tmp == HAL_SPI_STATE_READY) || \
00838     ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
00839   {
00840     errorcode = HAL_BUSY;
00841     goto error;
00842   }
00843 
00844   if((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
00845   {
00846     errorcode = HAL_ERROR;
00847     goto error;
00848   }
00849 
00850   /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
00851   if(hspi->State == HAL_SPI_STATE_READY)
00852   {
00853     hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
00854   }
00855 
00856   /* Set the transaction information */
00857   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
00858   hspi->pRxBuffPtr  = (uint8_t *)pRxData;
00859   hspi->RxXferCount = Size;
00860   hspi->RxXferSize  = Size;
00861   hspi->pTxBuffPtr  = (uint8_t *)pTxData;
00862   hspi->TxXferCount = Size;
00863   hspi->TxXferSize  = Size;
00864 
00865   /*Init field not used in handle to zero */
00866   hspi->RxISR       = NULL;
00867   hspi->TxISR       = NULL;
00868 
00869 #if (USE_SPI_CRC != 0U)
00870   /* Reset CRC Calculation */
00871   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00872   {
00873     SPI_RESET_CRC(hspi);
00874   }
00875 #endif /* USE_SPI_CRC */
00876 
00877   /* Check if the SPI is already enabled */
00878   if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
00879   {
00880     /* Enable SPI peripheral */
00881     __HAL_SPI_ENABLE(hspi);
00882   }
00883 
00884   /* Transmit and Receive data in 16 Bit mode */
00885   if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
00886   {
00887     if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U))
00888     {
00889       hspi->Instance->DR = *((uint16_t *)pTxData);
00890       pTxData += sizeof(uint16_t);
00891       hspi->TxXferCount--;
00892     }
00893     while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
00894     {
00895       /* Check TXE flag */
00896       if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
00897       {
00898         hspi->Instance->DR = *((uint16_t *)pTxData);
00899         pTxData += sizeof(uint16_t);
00900         hspi->TxXferCount--;
00901         /* Next Data is a reception (Rx). Tx not allowed */ 
00902         txallowed = 0U;
00903 
00904 #if (USE_SPI_CRC != 0U)
00905         /* Enable CRC Transmission */
00906         if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
00907         {
00908           SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
00909         }
00910 #endif /* USE_SPI_CRC */
00911       }
00912 
00913       /* Check RXNE flag */
00914       if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
00915       {
00916         *((uint16_t *)pRxData) = hspi->Instance->DR;
00917         pRxData += sizeof(uint16_t);
00918         hspi->RxXferCount--;
00919         /* Next Data is a Transmission (Tx). Tx is allowed */ 
00920         txallowed = 1U;
00921       }
00922       if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout))
00923       {
00924         errorcode = HAL_TIMEOUT;
00925         goto error;
00926       }
00927     }
00928   }
00929   /* Transmit and Receive data in 8 Bit mode */
00930   else
00931   {
00932     if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U))
00933     {
00934       *((__IO uint8_t*)&hspi->Instance->DR) = (*pTxData);
00935       pTxData += sizeof(uint8_t);
00936       hspi->TxXferCount--;
00937     }
00938     while((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
00939     {
00940       /* check TXE flag */
00941       if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
00942       {
00943         *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++);
00944         hspi->TxXferCount--;
00945         /* Next Data is a reception (Rx). Tx not allowed */ 
00946         txallowed = 0U;
00947 
00948 #if (USE_SPI_CRC != 0U)
00949         /* Enable CRC Transmission */
00950         if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
00951         {
00952           SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
00953         }
00954 #endif /* USE_SPI_CRC */
00955       }
00956 
00957       /* Wait until RXNE flag is reset */
00958       if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
00959       {
00960         (*(uint8_t *)pRxData++) = hspi->Instance->DR;
00961         hspi->RxXferCount--;
00962         /* Next Data is a Transmission (Tx). Tx is allowed */ 
00963         txallowed = 1U;
00964       }
00965       if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout))
00966       {
00967         errorcode = HAL_TIMEOUT;
00968         goto error;
00969       }
00970     }
00971   }
00972 
00973 #if (USE_SPI_CRC != 0U)
00974   /* Read CRC from DR to close CRC calculation process */
00975   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
00976   {
00977     /* Wait until TXE flag */
00978     if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
00979     {
00980       /* Error on the CRC reception */
00981       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
00982       errorcode = HAL_TIMEOUT;
00983       goto error;
00984     }
00985     /* Read CRC */
00986     tmpreg1 = hspi->Instance->DR;
00987     /* To avoid GCC warning */
00988     UNUSED(tmpreg1);
00989   }
00990 
00991   /* Check if CRC error occurred */
00992   if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR))
00993   {
00994     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
00995     /* Clear CRC Flag */
00996     __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
00997 
00998     errorcode = HAL_ERROR;
00999   }
01000 #endif /* USE_SPI_CRC */
01001 
01002   /* Wait until TXE flag */
01003   if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
01004   {
01005     errorcode = HAL_TIMEOUT;
01006     goto error;
01007   }
01008   
01009   /* Check Busy flag */
01010   if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
01011   {
01012     errorcode = HAL_ERROR;
01013     hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
01014     goto error;
01015   }
01016 
01017   /* Clear overrun flag in 2 Lines communication mode because received is not read */
01018   if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
01019   {
01020     __HAL_SPI_CLEAR_OVRFLAG(hspi);
01021   }
01022   
01023 error :
01024   hspi->State = HAL_SPI_STATE_READY;
01025   __HAL_UNLOCK(hspi);
01026   return errorcode;
01027 }
01028 
01029 /**
01030   * @brief  Transmit an amount of data in non-blocking mode with Interrupt.
01031   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01032   *               the configuration information for SPI module.
01033   * @param  pData pointer to data buffer
01034   * @param  Size amount of data to be sent
01035   * @retval HAL status
01036   */
01037 HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
01038 {
01039   HAL_StatusTypeDef errorcode = HAL_OK;
01040 
01041   /* Check Direction parameter */
01042   assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
01043 
01044   /* Process Locked */
01045   __HAL_LOCK(hspi);
01046 
01047   if((pData == NULL) || (Size == 0))
01048   {
01049     errorcode = HAL_ERROR;
01050     goto error;
01051   }
01052 
01053   if(hspi->State != HAL_SPI_STATE_READY)
01054   {
01055     errorcode = HAL_BUSY;
01056     goto error;
01057   }
01058 
01059   /* Set the transaction information */
01060   hspi->State       = HAL_SPI_STATE_BUSY_TX;
01061   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01062   hspi->pTxBuffPtr  = (uint8_t *)pData;
01063   hspi->TxXferSize  = Size;
01064   hspi->TxXferCount = Size;
01065 
01066   /* Init field not used in handle to zero */
01067   hspi->pRxBuffPtr  = (uint8_t *)NULL;
01068   hspi->RxXferSize  = 0U;
01069   hspi->RxXferCount = 0U;
01070   hspi->RxISR       = NULL;
01071 
01072   /* Set the function for IT treatment */
01073   if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
01074   {
01075     hspi->TxISR = SPI_TxISR_16BIT;
01076   }
01077   else
01078   {
01079     hspi->TxISR = SPI_TxISR_8BIT;
01080   }
01081 
01082   /* Configure communication direction : 1Line */
01083   if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
01084   {
01085     SPI_1LINE_TX(hspi);
01086   }
01087 
01088 #if (USE_SPI_CRC != 0U)
01089   /* Reset CRC Calculation */
01090   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01091   {
01092     SPI_RESET_CRC(hspi);
01093   }
01094 #endif /* USE_SPI_CRC */
01095 
01096   if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
01097   {
01098     /* Enable TXE interrupt */
01099     __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE));
01100   }
01101   else
01102   {
01103     /* Enable TXE and ERR interrupt */
01104     __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
01105   }
01106 
01107   /* Check if the SPI is already enabled */
01108   if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
01109   {
01110     /* Enable SPI peripheral */
01111     __HAL_SPI_ENABLE(hspi);
01112   }
01113 
01114 error :
01115   __HAL_UNLOCK(hspi);
01116   return errorcode;
01117 }
01118 
01119 /**
01120   * @brief  Receive an amount of data in non-blocking mode with Interrupt.
01121   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01122   *               the configuration information for SPI module.
01123   * @param  pData pointer to data buffer
01124   * @param  Size amount of data to be sent
01125   * @retval HAL status
01126   */
01127 HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
01128 {
01129   HAL_StatusTypeDef errorcode = HAL_OK;
01130 
01131   if((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
01132   {
01133      hspi->State = HAL_SPI_STATE_BUSY_RX;
01134      /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
01135      return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size);
01136   }
01137 
01138   /* Process Locked */
01139   __HAL_LOCK(hspi);
01140 
01141   if(hspi->State != HAL_SPI_STATE_READY)
01142   {
01143     errorcode = HAL_BUSY;
01144     goto error;
01145   }
01146 
01147   if((pData == NULL) || (Size == 0))
01148   {
01149     errorcode = HAL_ERROR;
01150     goto error;
01151   }
01152 
01153   /* Set the transaction information */
01154   hspi->State       = HAL_SPI_STATE_BUSY_RX;
01155   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01156   hspi->pRxBuffPtr  = (uint8_t *)pData;
01157   hspi->RxXferSize  = Size;
01158   hspi->RxXferCount = Size;
01159 
01160   /* Init field not used in handle to zero */
01161   hspi->pTxBuffPtr  = (uint8_t *)NULL;
01162   hspi->TxXferSize  = 0U;
01163   hspi->TxXferCount = 0U;
01164   hspi->TxISR       = NULL;
01165 
01166   /* Set the function for IT treatment */
01167   if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
01168   {
01169     hspi->RxISR = SPI_RxISR_16BIT;
01170   }
01171   else
01172   {
01173     hspi->RxISR = SPI_RxISR_8BIT;
01174   }
01175 
01176   /* Configure communication direction : 1Line */
01177   if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
01178   {
01179     SPI_1LINE_RX(hspi);
01180   }
01181 
01182 #if (USE_SPI_CRC != 0U)
01183   /* Reset CRC Calculation */
01184   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01185   {
01186     SPI_RESET_CRC(hspi);
01187   }
01188 #endif /* USE_SPI_CRC */
01189 
01190   /* Enable TXE and ERR interrupt */
01191   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
01192 
01193   /* Note : The SPI must be enabled after unlocking current process
01194             to avoid the risk of SPI interrupt handle execution before current
01195             process unlock */
01196 
01197   /* Check if the SPI is already enabled */
01198   if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
01199   {
01200     /* Enable SPI peripheral */
01201     __HAL_SPI_ENABLE(hspi);
01202   }
01203 
01204 error :
01205   /* Process Unlocked */
01206   __HAL_UNLOCK(hspi);
01207   return errorcode;
01208 }
01209 
01210 /**
01211   * @brief  Transmit and Receive an amount of data in non-blocking mode with Interrupt.
01212   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01213   *               the configuration information for SPI module.
01214   * @param  pTxData pointer to transmission data buffer
01215   * @param  pRxData pointer to reception data buffer
01216   * @param  Size amount of data to be sent and received
01217   * @retval HAL status
01218   */
01219 HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
01220 {
01221   uint32_t tmp = 0U, tmp1 = 0U;
01222   HAL_StatusTypeDef errorcode = HAL_OK;
01223 
01224   /* Check Direction parameter */
01225   assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
01226 
01227   /* Process locked */
01228   __HAL_LOCK(hspi);
01229 
01230   tmp  = hspi->State;
01231   tmp1 = hspi->Init.Mode;
01232   
01233   if(!((tmp == HAL_SPI_STATE_READY) || \
01234     ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
01235   {
01236     errorcode = HAL_BUSY;
01237     goto error;
01238   }
01239 
01240   if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
01241   {
01242     errorcode = HAL_ERROR;
01243     goto error;
01244   }
01245 
01246   /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
01247   if(hspi->State == HAL_SPI_STATE_READY)
01248   {
01249     hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
01250   }
01251 
01252   /* Set the transaction information */
01253   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01254   hspi->pTxBuffPtr  = (uint8_t *)pTxData;
01255   hspi->TxXferSize  = Size;
01256   hspi->TxXferCount = Size;
01257   hspi->pRxBuffPtr  = (uint8_t *)pRxData;
01258   hspi->RxXferSize  = Size;
01259   hspi->RxXferCount = Size;
01260 
01261   /* Set the function for IT treatment */
01262   if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
01263   {
01264     hspi->RxISR     = SPI_2linesRxISR_16BIT;
01265     hspi->TxISR     = SPI_2linesTxISR_16BIT;
01266   }
01267   else
01268   {
01269     hspi->RxISR     = SPI_2linesRxISR_8BIT;
01270     hspi->TxISR     = SPI_2linesTxISR_8BIT;
01271   }
01272 
01273 #if (USE_SPI_CRC != 0U)
01274   /* Reset CRC Calculation */
01275   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01276   {
01277     SPI_RESET_CRC(hspi);
01278   }
01279 #endif /* USE_SPI_CRC */
01280 
01281   /* Enable TXE, RXNE and ERR interrupt */
01282   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
01283 
01284   /* Check if the SPI is already enabled */
01285   if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
01286   {
01287     /* Enable SPI peripheral */
01288     __HAL_SPI_ENABLE(hspi);
01289   }
01290 
01291 error :
01292   /* Process Unlocked */
01293   __HAL_UNLOCK(hspi);
01294   return errorcode;
01295 }
01296 
01297 /**
01298   * @brief  Transmit an amount of data in non-blocking mode with DMA.
01299   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01300   *               the configuration information for SPI module.
01301   * @param  pData pointer to data buffer
01302   * @param  Size amount of data to be sent
01303   * @retval HAL status
01304   */
01305 HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
01306 {
01307   HAL_StatusTypeDef errorcode = HAL_OK;
01308 
01309   /* Check Direction parameter */
01310   assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
01311 
01312   /* Process Locked */
01313   __HAL_LOCK(hspi);
01314 
01315   if(hspi->State != HAL_SPI_STATE_READY)
01316   {
01317     errorcode = HAL_BUSY;
01318     goto error;
01319   }
01320 
01321   if((pData == NULL) || (Size == 0))
01322   {
01323     errorcode = HAL_ERROR;
01324     goto error;
01325   }
01326 
01327   /* Set the transaction information */
01328   hspi->State       = HAL_SPI_STATE_BUSY_TX;
01329   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01330   hspi->pTxBuffPtr  = (uint8_t *)pData;
01331   hspi->TxXferSize  = Size;
01332   hspi->TxXferCount = Size;
01333 
01334   /* Init field not used in handle to zero */
01335   hspi->pRxBuffPtr  = (uint8_t *)NULL;
01336   hspi->TxISR       = NULL;
01337   hspi->RxISR       = NULL;
01338   hspi->RxXferSize  = 0U;
01339   hspi->RxXferCount = 0U;
01340 
01341   /* Configure communication direction : 1Line */
01342   if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
01343   {
01344     SPI_1LINE_TX(hspi);
01345   }
01346 
01347 #if (USE_SPI_CRC != 0U)
01348   /* Reset CRC Calculation */
01349   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01350   {
01351     SPI_RESET_CRC(hspi);
01352   }
01353 #endif /* USE_SPI_CRC */
01354 
01355   /* Set the SPI TxDMA Half transfer complete callback */
01356   hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
01357 
01358   /* Set the SPI TxDMA transfer complete callback */
01359   hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
01360 
01361   /* Set the DMA error callback */
01362   hspi->hdmatx->XferErrorCallback = SPI_DMAError;
01363 
01364   /* Set the DMA AbortCpltCallback */
01365   hspi->hdmatx->XferAbortCallback = NULL;
01366 
01367   /* Enable the Tx DMA Stream */
01368   HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);
01369 
01370   /* Check if the SPI is already enabled */
01371   if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
01372   {
01373     /* Enable SPI peripheral */
01374     __HAL_SPI_ENABLE(hspi);
01375   }
01376 
01377   /* Enable the SPI Error Interrupt Bit */
01378   SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
01379 
01380   /* Enable Tx DMA Request */
01381   SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
01382 
01383 error :
01384   /* Process Unlocked */
01385   __HAL_UNLOCK(hspi);
01386   return errorcode;
01387 }
01388 
01389 /**
01390   * @brief  Receive an amount of data in non-blocking mode with DMA.
01391   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01392   *               the configuration information for SPI module.
01393   * @param  pData pointer to data buffer
01394   * @note   When the CRC feature is enabled the pData Length must be Size + 1.
01395   * @param  Size amount of data to be sent
01396   * @retval HAL status
01397   */
01398 HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
01399 {
01400   HAL_StatusTypeDef errorcode = HAL_OK;
01401 
01402   if((hspi->Init.Direction == SPI_DIRECTION_2LINES)&&(hspi->Init.Mode == SPI_MODE_MASTER))
01403   {
01404      hspi->State = HAL_SPI_STATE_BUSY_RX;
01405      /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
01406      return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size);
01407   }
01408 
01409   /* Process Locked */
01410   __HAL_LOCK(hspi);
01411 
01412   if(hspi->State != HAL_SPI_STATE_READY)
01413   {
01414     errorcode = HAL_BUSY;
01415     goto error;
01416   }
01417 
01418   if((pData == NULL) || (Size == 0))
01419   {
01420     errorcode = HAL_ERROR;
01421     goto error;
01422   }
01423 
01424   /* Set the transaction information */
01425   hspi->State       = HAL_SPI_STATE_BUSY_RX;
01426   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01427   hspi->pRxBuffPtr  = (uint8_t *)pData;
01428   hspi->RxXferSize  = Size;
01429   hspi->RxXferCount = Size;
01430 
01431   /*Init field not used in handle to zero */
01432   hspi->RxISR       = NULL;
01433   hspi->TxISR       = NULL;
01434   hspi->TxXferSize  = 0U;
01435   hspi->TxXferCount = 0U;
01436 
01437   /* Configure communication direction : 1Line */
01438   if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
01439   {
01440     SPI_1LINE_RX(hspi);
01441   }
01442 
01443 #if (USE_SPI_CRC != 0U)
01444   /* Reset CRC Calculation */
01445   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01446   {
01447     SPI_RESET_CRC(hspi);
01448   }
01449 #endif /* USE_SPI_CRC */
01450 
01451   /* Set the SPI RxDMA Half transfer complete callback */
01452   hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
01453 
01454   /* Set the SPI Rx DMA transfer complete callback */
01455   hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
01456 
01457   /* Set the DMA error callback */
01458   hspi->hdmarx->XferErrorCallback = SPI_DMAError;
01459 
01460  /* Set the DMA AbortCpltCallback */
01461   hspi->hdmarx->XferAbortCallback = NULL;
01462 
01463   /* Enable the Rx DMA Stream */
01464   HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
01465 
01466   /* Check if the SPI is already enabled */
01467   if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
01468   {
01469     /* Enable SPI peripheral */
01470     __HAL_SPI_ENABLE(hspi);
01471   }
01472 
01473   /* Enable the SPI Error Interrupt Bit */
01474   SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
01475 
01476   /* Enable Rx DMA Request */
01477   SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
01478 
01479 error:
01480   /* Process Unlocked */
01481   __HAL_UNLOCK(hspi);
01482   return errorcode;
01483 }
01484 
01485 /**
01486   * @brief  Transmit and Receive an amount of data in non-blocking mode with DMA.
01487   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01488   *               the configuration information for SPI module.
01489   * @param  pTxData pointer to transmission data buffer
01490   * @param  pRxData pointer to reception data buffer
01491   * @note   When the CRC feature is enabled the pRxData Length must be Size + 1
01492   * @param  Size amount of data to be sent
01493   * @retval HAL status
01494   */
01495 HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
01496 {
01497   uint32_t tmp = 0U, tmp1 = 0U;
01498   HAL_StatusTypeDef errorcode = HAL_OK;
01499 
01500   /* Check Direction parameter */
01501   assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
01502 
01503   /* Process locked */
01504   __HAL_LOCK(hspi);
01505 
01506   tmp  = hspi->State;
01507   tmp1 = hspi->Init.Mode;
01508   if(!((tmp == HAL_SPI_STATE_READY) ||
01509       ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
01510   {
01511     errorcode = HAL_BUSY;
01512     goto error;
01513   }
01514 
01515   if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
01516   {
01517     errorcode = HAL_ERROR;
01518     goto error;
01519   }
01520 
01521   /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
01522   if(hspi->State == HAL_SPI_STATE_READY)
01523   {
01524     hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
01525   }
01526 
01527   /* Set the transaction information */
01528   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
01529   hspi->pTxBuffPtr  = (uint8_t*)pTxData;
01530   hspi->TxXferSize  = Size;
01531   hspi->TxXferCount = Size;
01532   hspi->pRxBuffPtr  = (uint8_t*)pRxData;
01533   hspi->RxXferSize  = Size;
01534   hspi->RxXferCount = Size;
01535 
01536   /* Init field not used in handle to zero */
01537   hspi->RxISR       = NULL;
01538   hspi->TxISR       = NULL;
01539 
01540 #if (USE_SPI_CRC != 0U)
01541   /* Reset CRC Calculation */
01542   if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
01543   {
01544     SPI_RESET_CRC(hspi);
01545   }
01546 #endif /* USE_SPI_CRC */
01547 
01548   /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
01549   if(hspi->State == HAL_SPI_STATE_BUSY_RX)
01550   {
01551     /* Set the SPI Rx DMA Half transfer complete callback */
01552     hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
01553     hspi->hdmarx->XferCpltCallback     = SPI_DMAReceiveCplt;
01554   }
01555   else
01556   {
01557     /* Set the SPI Tx/Rx DMA Half transfer complete callback */
01558     hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
01559     hspi->hdmarx->XferCpltCallback     = SPI_DMATransmitReceiveCplt;
01560   }
01561 
01562   /* Set the DMA error callback */
01563   hspi->hdmarx->XferErrorCallback = SPI_DMAError;
01564 
01565   /* Set the DMA AbortCpltCallback */
01566   hspi->hdmarx->XferAbortCallback = NULL;
01567 
01568   /* Enable the Rx DMA Stream */
01569   HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);
01570 
01571   /* Enable Rx DMA Request */
01572   SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
01573 
01574   /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
01575   is performed in DMA reception complete callback  */
01576   hspi->hdmatx->XferHalfCpltCallback = NULL;
01577   hspi->hdmatx->XferCpltCallback     = NULL;
01578   hspi->hdmatx->XferErrorCallback    = NULL;
01579   hspi->hdmatx->XferAbortCallback    = NULL;
01580 
01581   /* Enable the Tx DMA Stream */
01582   HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, hspi->TxXferCount);
01583 
01584   /* Check if the SPI is already enabled */
01585   if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
01586   {
01587     /* Enable SPI peripheral */
01588     __HAL_SPI_ENABLE(hspi);
01589   }
01590   /* Enable the SPI Error Interrupt Bit */
01591   SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
01592 
01593   /* Enable Tx DMA Request */
01594   SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
01595 
01596 error :
01597   /* Process Unlocked */
01598   __HAL_UNLOCK(hspi);
01599   return errorcode;
01600 }
01601 
01602 /**
01603   * @brief  Abort ongoing transfer (blocking mode).
01604   * @param  hspi SPI handle.
01605   * @note   This procedure could be used for aborting any ongoing transfer (Tx and Rx),
01606   *         started in Interrupt or DMA mode.
01607   *         This procedure performs following operations :
01608   *           - Disable SPI Interrupts (depending of transfer direction)
01609   *           - Disable the DMA transfer in the peripheral register (if enabled)
01610   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
01611   *           - Set handle State to READY
01612   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
01613   * @note   Once transfer is aborted, the __HAL_SPI_CLEAR_OVRFLAG() macro must be called in user application 
01614   *         before starting new SPI receive process.
01615   * @retval HAL status
01616 */
01617 HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
01618 {
01619   __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
01620 
01621   /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
01622   if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
01623   {
01624     hspi->TxISR = SPI_AbortTx_ISR;
01625   }
01626 
01627   if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
01628   {
01629     hspi->RxISR = SPI_AbortRx_ISR;
01630   }
01631 
01632   /* Clear ERRIE interrupts in case of DMA Mode */
01633   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
01634 
01635   /* Disable the SPI DMA Tx or SPI DMA Rx request if enabled */
01636   if ((HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) || (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)))
01637   {
01638     /* Abort the SPI DMA Tx channel : use blocking DMA Abort API (no callback) */  
01639     if(hspi->hdmatx != NULL)
01640     {
01641       /* Set the SPI DMA Abort callback :
01642       will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
01643       hspi->hdmatx->XferAbortCallback = NULL;
01644       
01645       /* Abort DMA Tx Handle linked to SPI Peripheral */
01646       HAL_DMA_Abort(hspi->hdmatx);
01647 
01648       /* Disable Tx DMA Request */
01649       CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN));
01650 
01651       /* Wait until TXE flag is set */
01652       do
01653       {
01654         if(count-- == 0U)
01655         {
01656           SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
01657           break;
01658         }
01659       }
01660       while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);       
01661     }
01662     /* Abort the SPI DMA Rx channel : use blocking DMA Abort API (no callback) */
01663     if(hspi->hdmarx != NULL)
01664     {
01665       /* Set the SPI DMA Abort callback :
01666       will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
01667       hspi->hdmarx->XferAbortCallback = NULL;
01668       
01669       /* Abort DMA Rx Handle linked to SPI Peripheral */
01670       HAL_DMA_Abort(hspi->hdmarx);
01671 
01672       /* Disable peripheral */
01673       __HAL_SPI_DISABLE(hspi); 
01674 
01675       /* Disable Rx DMA Request */
01676       CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXDMAEN));
01677       
01678     }
01679   }
01680   /* Reset Tx and Rx transfer counters */
01681   hspi->RxXferCount = 0U;
01682   hspi->TxXferCount = 0U;
01683 
01684   /* Reset errorCode */
01685   hspi->ErrorCode = HAL_SPI_ERROR_NONE;
01686 
01687   /* Clear the Error flags in the SR register */
01688   __HAL_SPI_CLEAR_OVRFLAG(hspi);
01689   __HAL_SPI_CLEAR_FREFLAG(hspi);
01690 
01691   /* Restore hspi->state to ready */
01692   hspi->State = HAL_SPI_STATE_READY;
01693 
01694   return HAL_OK;
01695 }
01696 
01697 /**
01698   * @brief  Abort ongoing transfer (Interrupt mode).
01699   * @param  hspi SPI handle.
01700   * @note   This procedure could be used for aborting any ongoing transfer (Tx and Rx),
01701   *         started in Interrupt or DMA mode.
01702   *         This procedure performs following operations :
01703   *           - Disable SPI Interrupts (depending of transfer direction)
01704   *           - Disable the DMA transfer in the peripheral register (if enabled)
01705   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
01706   *           - Set handle State to READY
01707   *           - At abort completion, call user abort complete callback
01708   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
01709   *         considered as completed only when user abort complete callback is executed (not when exiting function).
01710   * @note   Once transfer is aborted, the __HAL_SPI_CLEAR_OVRFLAG() macro must be called in user application 
01711   *         before starting new SPI receive process.
01712   * @retval HAL status
01713 */
01714 HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi)
01715 {
01716   uint32_t abortcplt;
01717 
01718   /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */
01719   if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
01720   {
01721     hspi->TxISR = SPI_AbortTx_ISR;
01722   }
01723 
01724   if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
01725   {
01726     hspi->RxISR = SPI_AbortRx_ISR;
01727   }
01728 
01729   /* Clear ERRIE interrupts in case of DMA Mode */
01730   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
01731 
01732   abortcplt = 1U;
01733   
01734   /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialised
01735      before any call to DMA Abort functions */  
01736   /* DMA Tx Handle is valid */
01737   if(hspi->hdmatx != NULL)
01738   {
01739     /* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
01740        Otherwise, set it to NULL */
01741     if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
01742     {
01743       hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback;
01744     }
01745     else
01746     {
01747       hspi->hdmatx->XferAbortCallback = NULL;
01748     }
01749   }  
01750   /* DMA Rx Handle is valid */
01751   if(hspi->hdmarx != NULL)
01752   {
01753     /* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
01754        Otherwise, set it to NULL */
01755     if(HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
01756     {
01757       hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback;
01758     }
01759     else
01760     {
01761       hspi->hdmarx->XferAbortCallback = NULL;
01762     }
01763   }
01764 
01765   /* Disable the SPI DMA Tx or the SPI Rx request if enabled */
01766   if((HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) && (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)))
01767   {
01768     /* Abort the SPI DMA Tx channel */
01769     if(hspi->hdmatx != NULL)
01770     {
01771       /* Abort DMA Tx Handle linked to SPI Peripheral */
01772       if(HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
01773       {
01774         hspi->hdmatx->XferAbortCallback = NULL;
01775       }
01776       else
01777       {
01778         abortcplt = 0U;
01779       }
01780     }
01781     /* Abort the SPI DMA Rx channel */
01782     if(hspi->hdmarx != NULL)
01783     {
01784       /* Abort DMA Rx Handle linked to SPI Peripheral */
01785       if(HAL_DMA_Abort_IT(hspi->hdmarx)!=  HAL_OK)
01786       {
01787         hspi->hdmarx->XferAbortCallback = NULL;
01788         abortcplt = 1U;
01789       }
01790       else
01791       {
01792         abortcplt = 0U;
01793       }
01794     }
01795   }
01796 
01797   /* Disable the SPI DMA Tx or the SPI Rx request if enabled */
01798   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
01799   {
01800     /* Abort the SPI DMA Tx channel */
01801     if(hspi->hdmatx != NULL)
01802     {
01803       /* Abort DMA Tx Handle linked to SPI Peripheral */
01804       if(HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
01805       {
01806         hspi->hdmatx->XferAbortCallback = NULL;
01807       }
01808       else
01809       {
01810         abortcplt = 0U;
01811       }
01812     }
01813   }
01814   /* Disable the SPI DMA Tx or the SPI Rx request if enabled */
01815   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
01816   {
01817     /* Abort the SPI DMA Rx channel */
01818     if(hspi->hdmarx != NULL)
01819     {
01820       /* Abort DMA Rx Handle linked to SPI Peripheral */
01821       if(HAL_DMA_Abort_IT(hspi->hdmarx)!=  HAL_OK)
01822       {
01823         hspi->hdmarx->XferAbortCallback = NULL;
01824       }
01825       else
01826       {
01827         abortcplt = 0U;
01828       }
01829     }
01830   }
01831 
01832   if(abortcplt == 1U)
01833   {
01834     /* Reset Tx and Rx transfer counters */
01835     hspi->RxXferCount = 0U;
01836     hspi->TxXferCount = 0U;
01837 
01838     /* Reset errorCode */
01839     hspi->ErrorCode = HAL_SPI_ERROR_NONE;
01840 
01841     /* Clear the Error flags in the SR register */
01842     __HAL_SPI_CLEAR_OVRFLAG(hspi);
01843     __HAL_SPI_CLEAR_FREFLAG(hspi);
01844 
01845     /* Restore hspi->State to Ready */
01846     hspi->State = HAL_SPI_STATE_READY;
01847 
01848     /* As no DMA to be aborted, call directly user Abort complete callback */
01849     HAL_SPI_AbortCpltCallback(hspi);
01850   }
01851   return HAL_OK;
01852 }
01853 
01854 /**
01855   * @brief  Pause the DMA Transfer.
01856   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01857   *               the configuration information for the specified SPI module.
01858   * @retval HAL status
01859   */
01860 HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
01861 {
01862   /* Process Locked */
01863   __HAL_LOCK(hspi);
01864 
01865   /* Disable the SPI DMA Tx & Rx requests */
01866   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
01867 
01868   /* Process Unlocked */
01869   __HAL_UNLOCK(hspi);
01870 
01871   return HAL_OK;
01872 }
01873 
01874 /**
01875   * @brief  Resume the DMA Transfer.
01876   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01877   *               the configuration information for the specified SPI module.
01878   * @retval HAL status
01879   */
01880 HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
01881 {
01882   /* Process Locked */
01883   __HAL_LOCK(hspi);
01884 
01885   /* Enable the SPI DMA Tx & Rx requests */
01886   SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
01887 
01888   /* Process Unlocked */
01889   __HAL_UNLOCK(hspi);
01890 
01891   return HAL_OK;
01892 }
01893 
01894 /**
01895   * @brief Stop the DMA Transfer.
01896   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01897   *               the configuration information for the specified SPI module.
01898   * @retval HAL status
01899   */
01900 HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
01901 {
01902   /* The Lock is not implemented on this API to allow the user application
01903      to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback():
01904      when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
01905      and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback()
01906      */
01907 
01908   /* Abort the SPI DMA tx Stream */
01909   if(hspi->hdmatx != NULL)
01910   {
01911     HAL_DMA_Abort(hspi->hdmatx);
01912   }
01913   /* Abort the SPI DMA rx Stream */
01914   if(hspi->hdmarx != NULL)
01915   {
01916     HAL_DMA_Abort(hspi->hdmarx);
01917   }
01918 
01919   /* Disable the SPI DMA Tx & Rx requests */
01920   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
01921   hspi->State = HAL_SPI_STATE_READY;
01922   return HAL_OK;
01923 }
01924 
01925 /**
01926   * @brief  Handle SPI interrupt request.
01927   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
01928   *               the configuration information for the specified SPI module.
01929   * @retval None
01930   */
01931 void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
01932 {
01933   uint32_t itsource = hspi->Instance->CR2;
01934   uint32_t itflag   = hspi->Instance->SR;
01935 
01936   /* SPI in mode Receiver ----------------------------------------------------*/
01937   if(((itflag & SPI_FLAG_OVR) == RESET) &&
01938      ((itflag & SPI_FLAG_RXNE) != RESET) && ((itsource & SPI_IT_RXNE) != RESET))
01939   {
01940     hspi->RxISR(hspi);
01941     return;
01942   }
01943 
01944   /* SPI in mode Transmitter -------------------------------------------------*/
01945   if(((itflag & SPI_FLAG_TXE) != RESET) && ((itsource & SPI_IT_TXE) != RESET))
01946   {
01947     hspi->TxISR(hspi);
01948     return;
01949   }
01950 
01951   /* SPI in Error Treatment --------------------------------------------------*/
01952   if(((itflag & (SPI_FLAG_MODF | SPI_FLAG_OVR | SPI_FLAG_FRE)) != RESET) && ((itsource & SPI_IT_ERR) != RESET))
01953   {
01954     /* SPI Overrun error interrupt occurred ----------------------------------*/
01955     if((itflag & SPI_FLAG_OVR) != RESET)
01956     {
01957       if(hspi->State != HAL_SPI_STATE_BUSY_TX)
01958       {
01959         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
01960         __HAL_SPI_CLEAR_OVRFLAG(hspi);
01961       }
01962       else
01963       {
01964         __HAL_SPI_CLEAR_OVRFLAG(hspi);
01965         return;
01966       }
01967     }
01968 
01969     /* SPI Mode Fault error interrupt occurred -------------------------------*/
01970     if((itflag & SPI_FLAG_MODF) != RESET)
01971     {
01972       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
01973       __HAL_SPI_CLEAR_MODFFLAG(hspi);
01974     }
01975 
01976     /* SPI Frame error interrupt occurred ------------------------------------*/
01977     if((itflag & SPI_FLAG_FRE) != RESET)
01978     {
01979       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE);
01980       __HAL_SPI_CLEAR_FREFLAG(hspi);
01981     }
01982 
01983     if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
01984     {
01985       /* Disable all interrupts */
01986       __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
01987 
01988       hspi->State = HAL_SPI_STATE_READY;
01989       /* Disable the SPI DMA requests if enabled */
01990       if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN))||(HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN)))
01991       {
01992         CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN));
01993 
01994         /* Abort the SPI DMA Rx channel */
01995         if(hspi->hdmarx != NULL)
01996         {
01997           /* Set the SPI DMA Abort callback :
01998           will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
01999           hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
02000           HAL_DMA_Abort_IT(hspi->hdmarx);
02001         }
02002         /* Abort the SPI DMA Tx channel */
02003         if(hspi->hdmatx != NULL)
02004         {
02005           /* Set the SPI DMA Abort callback :
02006           will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
02007           hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
02008           HAL_DMA_Abort_IT(hspi->hdmatx);
02009         }
02010       }
02011       else
02012       {
02013         /* Call user error callback */
02014         HAL_SPI_ErrorCallback(hspi);
02015       }
02016     }
02017     return;
02018   }
02019 }
02020 
02021 /**
02022   * @brief Tx Transfer completed callback.
02023   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02024   *               the configuration information for SPI module.
02025   * @retval None
02026   */
02027 __weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
02028 {
02029   /* Prevent unused argument(s) compilation warning */
02030   UNUSED(hspi);
02031   /* NOTE : This function should not be modified, when the callback is needed,
02032             the HAL_SPI_TxCpltCallback should be implemented in the user file
02033   */
02034 }
02035 
02036 /**
02037   * @brief Rx Transfer completed callback.
02038   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02039   *               the configuration information for SPI module.
02040   * @retval None
02041   */
02042 __weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
02043 {
02044   /* Prevent unused argument(s) compilation warning */
02045   UNUSED(hspi);
02046   /* NOTE : This function should not be modified, when the callback is needed,
02047             the HAL_SPI_RxCpltCallback should be implemented in the user file
02048   */
02049 }
02050 
02051 /**
02052   * @brief Tx and Rx Transfer completed callback.
02053   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02054   *               the configuration information for SPI module.
02055   * @retval None
02056   */
02057 __weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
02058 {
02059   /* Prevent unused argument(s) compilation warning */
02060   UNUSED(hspi);
02061   /* NOTE : This function should not be modified, when the callback is needed,
02062             the HAL_SPI_TxRxCpltCallback should be implemented in the user file
02063   */
02064 }
02065 
02066 /**
02067   * @brief Tx Half Transfer completed callback.
02068   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02069   *               the configuration information for SPI module.
02070   * @retval None
02071   */
02072 __weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi)
02073 {
02074   /* Prevent unused argument(s) compilation warning */
02075   UNUSED(hspi);
02076   /* NOTE : This function should not be modified, when the callback is needed,
02077             the HAL_SPI_TxHalfCpltCallback should be implemented in the user file
02078   */
02079 }
02080 
02081 /**
02082   * @brief Rx Half Transfer completed callback.
02083   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02084   *               the configuration information for SPI module.
02085   * @retval None
02086   */
02087 __weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi)
02088 {
02089   /* Prevent unused argument(s) compilation warning */
02090   UNUSED(hspi);
02091   /* NOTE : This function should not be modified, when the callback is needed,
02092             the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file
02093   */
02094 }
02095 
02096 /**
02097   * @brief Tx and Rx Half Transfer callback.
02098   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02099   *               the configuration information for SPI module.
02100   * @retval None
02101   */
02102 __weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi)
02103 {
02104   /* Prevent unused argument(s) compilation warning */
02105   UNUSED(hspi);
02106   /* NOTE : This function should not be modified, when the callback is needed,
02107             the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file
02108   */
02109 }
02110 
02111 /**
02112   * @brief SPI error callback.
02113   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02114   *               the configuration information for SPI module.
02115   * @retval None
02116   */
02117  __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
02118 {
02119   /* Prevent unused argument(s) compilation warning */
02120   UNUSED(hspi);
02121   /* NOTE : This function should not be modified, when the callback is needed,
02122             the HAL_SPI_ErrorCallback should be implemented in the user file
02123    */
02124   /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes
02125             and user can use HAL_SPI_GetError() API to check the latest error occurred
02126   */
02127 }
02128 
02129 /**
02130   * @brief  SPI Abort Complete callback.
02131   * @param  hspi SPI handle.
02132   * @retval None
02133   */
02134 __weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi)
02135 {
02136   /* Prevent unused argument(s) compilation warning */
02137   UNUSED(hspi);
02138 
02139   /* NOTE : This function should not be modified, when the callback is needed,
02140             the HAL_SPI_AbortCpltCallback can be implemented in the user file.
02141    */
02142 }
02143 
02144 /**
02145   * @}
02146   */
02147 
02148 /** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
02149   * @brief   SPI control functions
02150   *
02151 @verbatim
02152  ===============================================================================
02153                       ##### Peripheral State and Errors functions #####
02154  ===============================================================================
02155     [..]
02156     This subsection provides a set of functions allowing to control the SPI.
02157      (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
02158      (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
02159 @endverbatim
02160   * @{
02161   */
02162 
02163 /**
02164   * @brief  Return the SPI handle state.
02165   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02166   *               the configuration information for SPI module.
02167   * @retval SPI state
02168   */
02169 HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi)
02170 {
02171   /* Return SPI handle state */
02172   return hspi->State;
02173 }
02174 
02175 /**
02176   * @brief  Return the SPI error code.
02177   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02178   *               the configuration information for SPI module.
02179   * @retval SPI error code in bitmap format
02180   */
02181 uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi)
02182 {
02183   /* Return SPI ErrorCode */
02184   return hspi->ErrorCode;
02185 }
02186 
02187 /**
02188   * @}
02189   */
02190 
02191 /**
02192   * @}
02193   */
02194 
02195 /** @addtogroup SPI_Private_Functions
02196   * @brief   Private functions
02197   * @{
02198   */
02199 
02200 /**
02201   * @brief DMA SPI transmit process complete callback.
02202   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02203   *               the configuration information for the specified DMA module.
02204   * @retval None
02205   */
02206 static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
02207 {
02208   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02209   uint32_t tickstart = 0U;
02210 
02211   /* Init tickstart for timeout managment*/
02212   tickstart = HAL_GetTick();
02213 
02214   /* DMA Normal Mode */
02215   if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
02216   {
02217     /* Disable Tx DMA Request */
02218     CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
02219 
02220     /* Check the end of the transaction */
02221     if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
02222     {
02223       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
02224     }
02225 
02226     /* Clear overrun flag in 2 Lines communication mode because received data is not read */
02227     if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
02228     {
02229       __HAL_SPI_CLEAR_OVRFLAG(hspi);
02230     }
02231 
02232     hspi->TxXferCount = 0U;
02233     hspi->State = HAL_SPI_STATE_READY;
02234 
02235     if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
02236     {
02237       HAL_SPI_ErrorCallback(hspi);
02238       return;
02239     }
02240   }
02241   HAL_SPI_TxCpltCallback(hspi);
02242 }
02243 
02244 /**
02245   * @brief DMA SPI receive process complete callback.
02246   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02247   *               the configuration information for the specified DMA module.
02248   * @retval None
02249   */
02250 static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
02251 {
02252   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02253 #if (USE_SPI_CRC != 0U)
02254   uint32_t tickstart = 0U;
02255   __IO uint16_t tmpreg = 0U;
02256 
02257   /* Init tickstart for timeout management*/
02258   tickstart = HAL_GetTick();
02259 #endif /* USE_SPI_CRC */
02260  
02261   if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
02262   {
02263 #if (USE_SPI_CRC != 0U)
02264     /* CRC handling */
02265     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02266     {
02267       /* Wait until RXNE flag */
02268       if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SPI_FLAG_RXNE, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
02269       {
02270         /* Error on the CRC reception */
02271         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
02272       }
02273       /* Read CRC */
02274       tmpreg = hspi->Instance->DR;
02275       /* To avoid GCC warning */
02276       UNUSED(tmpreg);
02277     }
02278 #endif /* USE_SPI_CRC */
02279 
02280     /* Disable Rx/Tx DMA Request (done by default to handle the case master rx direction 2 lines) */
02281     CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
02282 
02283     /* Check the end of the transaction */
02284     if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
02285     {
02286       /* Disable SPI peripheral */
02287       __HAL_SPI_DISABLE(hspi);
02288     }
02289 
02290     hspi->RxXferCount = 0U;
02291     hspi->State = HAL_SPI_STATE_READY;
02292 
02293 #if (USE_SPI_CRC != 0U)
02294     /* Check if CRC error occurred */
02295     if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR))
02296     {
02297       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
02298       __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
02299     }
02300 #endif /* USE_SPI_CRC */
02301 
02302     if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
02303     {
02304       HAL_SPI_ErrorCallback(hspi);
02305       return;
02306     }
02307   }
02308   HAL_SPI_RxCpltCallback(hspi);
02309 }
02310 
02311 /**
02312   * @brief  DMA SPI transmit receive process complete callback.
02313   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02314   *               the configuration information for the specified DMA module.
02315   * @retval None
02316   */
02317 static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
02318 {
02319   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02320   uint32_t tickstart = 0U;
02321 #if (USE_SPI_CRC != 0U)
02322   __IO int16_t tmpreg = 0U;
02323 #endif /* USE_SPI_CRC */
02324   /* Init tickstart for timeout management*/
02325   tickstart = HAL_GetTick();
02326 
02327   if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U)
02328   {
02329 #if (USE_SPI_CRC != 0U)
02330     /* CRC handling */
02331     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02332     {
02333       /* Wait the CRC data */
02334       if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
02335       {
02336         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
02337       }
02338       /* Read CRC to Flush DR and RXNE flag */
02339       tmpreg = hspi->Instance->DR;
02340       /* To avoid GCC warning */
02341       UNUSED(tmpreg);
02342     }
02343 #endif /* USE_SPI_CRC */
02344     /* Check the end of the transaction */
02345     if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
02346     {
02347       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
02348     }
02349 
02350     /* Disable Rx/Tx DMA Request */
02351     CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
02352 
02353     hspi->TxXferCount = 0U;
02354     hspi->RxXferCount = 0U;
02355     hspi->State = HAL_SPI_STATE_READY;
02356 
02357 #if (USE_SPI_CRC != 0U)
02358     /* Check if CRC error occurred */
02359     if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR))
02360     {
02361       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
02362       __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
02363     }
02364 #endif /* USE_SPI_CRC */
02365 
02366     if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
02367     {
02368       HAL_SPI_ErrorCallback(hspi);
02369       return;
02370     }
02371   }
02372   HAL_SPI_TxRxCpltCallback(hspi);
02373 }
02374 
02375 /**
02376   * @brief  DMA SPI half transmit process complete callback.
02377   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02378   *               the configuration information for the specified DMA module.
02379   * @retval None
02380   */
02381 static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma)
02382 {
02383   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02384 
02385   HAL_SPI_TxHalfCpltCallback(hspi);
02386 }
02387 
02388 /**
02389   * @brief  DMA SPI half receive process complete callback
02390   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02391   *               the configuration information for the specified DMA module.
02392   * @retval None
02393   */
02394 static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma)
02395 {
02396   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02397 
02398   HAL_SPI_RxHalfCpltCallback(hspi);
02399 }
02400 
02401 /**
02402   * @brief  DMA SPI half transmit receive process complete callback.
02403   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02404   *               the configuration information for the specified DMA module.
02405   * @retval None
02406   */
02407 static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
02408 {
02409   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02410 
02411   HAL_SPI_TxRxHalfCpltCallback(hspi);
02412 }
02413 
02414 /**
02415   * @brief  DMA SPI communication error callback.
02416   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
02417   *               the configuration information for the specified DMA module.
02418   * @retval None
02419   */
02420 static void SPI_DMAError(DMA_HandleTypeDef *hdma)
02421 {
02422   SPI_HandleTypeDef* hspi = (SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02423 
02424 /* Stop the disable DMA transfer on SPI side */
02425   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
02426 
02427   SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
02428   hspi->State = HAL_SPI_STATE_READY;
02429   HAL_SPI_ErrorCallback(hspi);
02430 }
02431 
02432 /**
02433   * @brief  DMA SPI communication abort callback, when initiated by HAL services on Error
02434   *         (To be called at end of DMA Abort procedure following error occurrence).
02435   * @param  hdma DMA handle.
02436   * @retval None
02437   */
02438 static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
02439 {
02440   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02441   hspi->RxXferCount = 0U;
02442   hspi->TxXferCount = 0U;
02443 
02444   HAL_SPI_ErrorCallback(hspi);
02445 }
02446 
02447 /**
02448   * @brief  DMA SPI Tx communication abort callback, when initiated by user
02449   *         (To be called at end of DMA Tx Abort procedure following user abort request).
02450   * @note   When this callback is executed, User Abort complete call back is called only if no
02451   *         Abort still ongoing for Rx DMA Handle.
02452   * @param  hdma DMA handle.
02453   * @retval None
02454   */
02455 static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
02456 {
02457   __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
02458   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02459 
02460   hspi->hdmatx->XferAbortCallback = NULL;
02461 
02462   /* Disable Tx DMA Request */
02463   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN );
02464 
02465   /* Wait until TXE flag is set */
02466   do
02467   {
02468     if(count-- == 0U)
02469     {
02470       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
02471       break;
02472     }
02473   }
02474   while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
02475 
02476   /* Check if an Abort process is still ongoing */
02477   if(hspi->hdmarx != NULL)
02478   {
02479     if(hspi->hdmarx->XferAbortCallback != NULL)
02480     {
02481       return;
02482     }
02483   }
02484   
02485   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
02486   hspi->RxXferCount = 0U;
02487   hspi->TxXferCount = 0U;
02488 
02489   /* Reset errorCode */
02490   hspi->ErrorCode = HAL_SPI_ERROR_NONE;
02491 
02492   /* Clear the Error flags in the SR register */
02493   __HAL_SPI_CLEAR_FREFLAG(hspi);
02494 
02495   /* Restore hspi->State to Ready */
02496   hspi->State  = HAL_SPI_STATE_READY;
02497 
02498   /* Call user Abort complete callback */
02499   HAL_SPI_AbortCpltCallback(hspi);
02500 }
02501 
02502 /**
02503   * @brief  DMA SPI Rx communication abort callback, when initiated by user
02504   *         (To be called at end of DMA Rx Abort procedure following user abort request).
02505   * @note   When this callback is executed, User Abort complete call back is called only if no
02506   *         Abort still ongoing for Tx DMA Handle.
02507   * @param  hdma DMA handle.
02508   * @retval None
02509   */
02510 static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
02511 {
02512   SPI_HandleTypeDef* hspi = ( SPI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
02513 
02514   /* Disable SPI Peripheral */
02515   __HAL_SPI_DISABLE(hspi);
02516 
02517   hspi->hdmarx->XferAbortCallback = NULL;
02518 
02519   /* Disable Rx DMA Request */
02520   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
02521 
02522   /* Check if an Abort process is still ongoing */
02523   if(hspi->hdmatx != NULL)
02524   {
02525     if(hspi->hdmatx->XferAbortCallback != NULL)
02526     {
02527       return;
02528     }
02529   }
02530 
02531   /* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
02532   hspi->RxXferCount = 0U;
02533   hspi->TxXferCount = 0U;
02534 
02535   /* Reset errorCode */
02536   hspi->ErrorCode = HAL_SPI_ERROR_NONE;
02537 
02538   /* Clear the Error flags in the SR register */
02539   __HAL_SPI_CLEAR_OVRFLAG(hspi);
02540   __HAL_SPI_CLEAR_FREFLAG(hspi);  
02541 
02542   /* Restore hspi->State to Ready */
02543   hspi->State  = HAL_SPI_STATE_READY;
02544 
02545   /* Call user Abort complete callback */
02546   HAL_SPI_AbortCpltCallback(hspi);
02547 }
02548 
02549 /**
02550   * @brief  Rx 8-bit handler for Transmit and Receive in Interrupt mode.
02551   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02552   *               the configuration information for SPI module.
02553   * @retval None
02554   */
02555 static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
02556 {
02557   /* Receive data in 8bit mode */
02558   *hspi->pRxBuffPtr++ = *((__IO uint8_t *)&hspi->Instance->DR);
02559   hspi->RxXferCount--;
02560 
02561   /* check end of the reception */
02562   if(hspi->RxXferCount == 0U)
02563   {
02564 #if (USE_SPI_CRC != 0U)
02565     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02566     {
02567       hspi->RxISR =  SPI_2linesRxISR_8BITCRC;
02568       return;
02569     }
02570 #endif /* USE_SPI_CRC */
02571 
02572     /* Disable RXNE interrupt */
02573     __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
02574 
02575     if(hspi->TxXferCount == 0U)
02576     {
02577       SPI_CloseRxTx_ISR(hspi);
02578     }
02579   }
02580 }
02581 
02582 #if (USE_SPI_CRC != 0U)
02583 /**
02584   * @brief  Rx 8-bit handler for Transmit and Receive in Interrupt mode.
02585   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02586   *               the configuration information for SPI module.
02587   * @retval None
02588   */
02589 static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
02590 {
02591   __IO uint8_t tmpreg = 0U;
02592 
02593   /* Read data register to flush CRC */
02594   tmpreg = *((__IO uint8_t *)&hspi->Instance->DR);
02595 
02596   /* To avoid GCC warning */
02597 
02598   UNUSED(tmpreg);
02599 
02600    /* Disable RXNE interrupt */
02601   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
02602 
02603   if(hspi->TxXferCount == 0U)
02604   {
02605     SPI_CloseRxTx_ISR(hspi);
02606   }
02607 }
02608 #endif /* USE_SPI_CRC */
02609 
02610 /**
02611   * @brief  Tx 8-bit handler for Transmit and Receive in Interrupt mode.
02612   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02613   *               the configuration information for SPI module.
02614   * @retval None
02615   */
02616 static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
02617 {
02618   *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++);
02619   hspi->TxXferCount--;
02620 
02621   /* check the end of the transmission */
02622   if(hspi->TxXferCount == 0U)
02623   {
02624 #if (USE_SPI_CRC != 0U)
02625     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02626     {
02627       SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
02628       __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
02629       return;
02630     }
02631 #endif /* USE_SPI_CRC */
02632 
02633     /* Disable TXE interrupt */
02634     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
02635 
02636     if(hspi->RxXferCount == 0U)
02637     {
02638       SPI_CloseRxTx_ISR(hspi);
02639     }
02640   }
02641 }
02642 
02643 /**
02644   * @brief  Rx 16-bit handler for Transmit and Receive in Interrupt mode.
02645   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02646   *               the configuration information for SPI module.
02647   * @retval None
02648   */
02649 static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
02650 {
02651   /* Receive data in 16 Bit mode */
02652   *((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
02653   hspi->pRxBuffPtr += sizeof(uint16_t);
02654   hspi->RxXferCount--;
02655 
02656   if(hspi->RxXferCount == 0U)
02657   {
02658 #if (USE_SPI_CRC != 0U)
02659     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02660     {
02661       hspi->RxISR =  SPI_2linesRxISR_16BITCRC;
02662       return;
02663     }
02664 #endif /* USE_SPI_CRC */
02665 
02666     /* Disable RXNE interrupt */
02667     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
02668 
02669     if(hspi->TxXferCount == 0U)
02670     {
02671       SPI_CloseRxTx_ISR(hspi);
02672     }
02673   }
02674 }
02675 
02676 #if (USE_SPI_CRC != 0U)
02677 /**
02678   * @brief  Manage the CRC 16-bit receive for Transmit and Receive in Interrupt mode.
02679   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02680   *               the configuration information for SPI module.
02681   * @retval None
02682   */
02683 static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
02684 {
02685   /* Receive data in 16 Bit mode */
02686   __IO uint16_t tmpreg = 0U;
02687 
02688   /* Read data register to flush CRC */
02689   tmpreg = hspi->Instance->DR;
02690 
02691   /* To avoid GCC warning */
02692   UNUSED(tmpreg);
02693 
02694   /* Disable RXNE interrupt */
02695   __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
02696 
02697   SPI_CloseRxTx_ISR(hspi);
02698 }
02699 #endif /* USE_SPI_CRC */
02700 
02701 /**
02702   * @brief  Tx 16-bit handler for Transmit and Receive in Interrupt mode.
02703   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02704   *               the configuration information for SPI module.
02705   * @retval None
02706   */
02707 static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
02708 {
02709   /* Transmit data in 16 Bit mode */
02710   hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
02711   hspi->pTxBuffPtr += sizeof(uint16_t);
02712   hspi->TxXferCount--;
02713 
02714   /* Enable CRC Transmission */
02715   if(hspi->TxXferCount == 0U)
02716   {
02717 #if (USE_SPI_CRC != 0U)
02718     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02719     {
02720       SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
02721       __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
02722       return;
02723     }
02724 #endif /* USE_SPI_CRC */
02725 
02726     /* Disable TXE interrupt */
02727     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
02728 
02729     if(hspi->RxXferCount == 0U)
02730     {
02731       SPI_CloseRxTx_ISR(hspi);
02732     }
02733   }
02734 }
02735 
02736 #if (USE_SPI_CRC != 0U)
02737 /**
02738   * @brief  Manage the CRC 8-bit receive in Interrupt context.
02739   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02740   *               the configuration information for SPI module.
02741   * @retval None
02742   */
02743 static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
02744 {
02745   __IO uint8_t tmpreg = 0U;
02746 
02747   /* Read data register to flush CRC */
02748   tmpreg = *((__IO uint8_t*)&hspi->Instance->DR);
02749 
02750   /* To avoid GCC warning */
02751   UNUSED(tmpreg);
02752 
02753   SPI_CloseRx_ISR(hspi);
02754 }
02755 #endif /* USE_SPI_CRC */
02756 
02757 /**
02758   * @brief  Manage the receive 8-bit in Interrupt context.
02759   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02760   *               the configuration information for SPI module.
02761   * @retval None
02762   */
02763 static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
02764 {
02765   *hspi->pRxBuffPtr++ = (*(__IO uint8_t *)&hspi->Instance->DR);
02766   hspi->RxXferCount--;
02767 
02768 #if (USE_SPI_CRC != 0U)
02769   /* Enable CRC Transmission */
02770   if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
02771   {
02772     SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
02773   }
02774 #endif /* USE_SPI_CRC */
02775 
02776   if(hspi->RxXferCount == 0U)
02777   {
02778 #if (USE_SPI_CRC != 0U)
02779     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02780     {
02781       hspi->RxISR =  SPI_RxISR_8BITCRC;
02782       return;
02783     }
02784 #endif /* USE_SPI_CRC */
02785     SPI_CloseRx_ISR(hspi);
02786   }
02787 }
02788 
02789 #if (USE_SPI_CRC != 0U)
02790 /**
02791   * @brief  Manage the CRC 16-bit receive in Interrupt context.
02792   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02793   *               the configuration information for SPI module.
02794   * @retval None
02795   */
02796 static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
02797 {
02798   __IO uint16_t tmpreg = 0U;
02799 
02800   /* Read data register to flush CRC */
02801   tmpreg = hspi->Instance->DR;
02802 
02803   /* To avoid GCC warning */
02804   UNUSED(tmpreg);
02805 
02806   /* Disable RXNE and ERR interrupt */
02807   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
02808 
02809   SPI_CloseRx_ISR(hspi);
02810 }
02811 #endif /* USE_SPI_CRC */
02812 
02813 /**
02814   * @brief  Manage the 16-bit receive in Interrupt context.
02815   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02816   *               the configuration information for SPI module.
02817   * @retval None
02818   */
02819 static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
02820 {
02821   *((uint16_t *)hspi->pRxBuffPtr) = hspi->Instance->DR;
02822   hspi->pRxBuffPtr += sizeof(uint16_t);
02823   hspi->RxXferCount--;
02824 
02825 #if (USE_SPI_CRC != 0U)
02826   /* Enable CRC Transmission */
02827   if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
02828   {
02829     SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
02830   }
02831 #endif /* USE_SPI_CRC */
02832 
02833   if(hspi->RxXferCount == 0U)
02834   {
02835 #if (USE_SPI_CRC != 0U)
02836     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02837     {
02838       hspi->RxISR = SPI_RxISR_16BITCRC;
02839       return;
02840     }
02841 #endif /* USE_SPI_CRC */
02842     SPI_CloseRx_ISR(hspi);
02843   }
02844 }
02845 
02846 /**
02847   * @brief  Handle the data 8-bit transmit in Interrupt mode.
02848   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02849   *               the configuration information for SPI module.
02850   * @retval None
02851   */
02852 static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
02853 {
02854   *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++);
02855   hspi->TxXferCount--;
02856 
02857   if(hspi->TxXferCount == 0U)
02858   {
02859 #if (USE_SPI_CRC != 0U)
02860     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02861     {
02862       /* Enable CRC Transmission */
02863       SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
02864     }
02865 #endif /* USE_SPI_CRC */
02866     SPI_CloseTx_ISR(hspi);
02867   }
02868 }
02869 
02870 /**
02871   * @brief  Handle the data 16-bit transmit in Interrupt mode.
02872   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02873   *               the configuration information for SPI module.
02874   * @retval None
02875   */
02876 static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
02877 {
02878   /* Transmit data in 16 Bit mode */
02879   hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
02880   hspi->pTxBuffPtr += sizeof(uint16_t);
02881   hspi->TxXferCount--;
02882 
02883   if(hspi->TxXferCount == 0U)
02884   {
02885 #if (USE_SPI_CRC != 0U)
02886     if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02887     {
02888       /* Enable CRC Transmission */
02889       SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
02890     }
02891 #endif /* USE_SPI_CRC */
02892     SPI_CloseTx_ISR(hspi);
02893   }
02894 }
02895 
02896 /**
02897   * @brief Handle SPI Communication Timeout.
02898   * @param hspi pointer to a SPI_HandleTypeDef structure that contains
02899   *              the configuration information for SPI module.
02900   * @param Flag SPI flag to check
02901   * @param State flag state to check
02902   * @param Timeout Timeout duration
02903   * @param Tickstart tick start value
02904   * @retval HAL status
02905   */
02906 static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart)
02907 {
02908   while((((hspi->Instance->SR & Flag) == (Flag)) ? SET : RESET) != State)
02909   {
02910     if(Timeout != HAL_MAX_DELAY)
02911     {
02912       if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) >= Timeout))
02913       {
02914         /* Disable the SPI and reset the CRC: the CRC value should be cleared
02915         on both master and slave sides in order to resynchronize the master
02916         and slave for their respective CRC calculation */
02917 
02918         /* Disable TXE, RXNE and ERR interrupts for the interrupt process */
02919         __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
02920 
02921         if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
02922         {
02923           /* Disable SPI peripheral */
02924           __HAL_SPI_DISABLE(hspi);
02925         }
02926 
02927         /* Reset CRC Calculation */
02928         if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
02929         {
02930           SPI_RESET_CRC(hspi);
02931         }
02932 
02933         hspi->State= HAL_SPI_STATE_READY;
02934 
02935         /* Process Unlocked */
02936         __HAL_UNLOCK(hspi);
02937 
02938         return HAL_TIMEOUT;
02939       }
02940     }
02941   }
02942 
02943   return HAL_OK;
02944 }
02945 /**
02946   * @brief Handle to check BSY flag before start a new transaction.
02947   * @param hspi pointer to a SPI_HandleTypeDef structure that contains
02948   *              the configuration information for SPI module.
02949   * @param Timeout Timeout duration
02950   * @param Tickstart tick start value
02951   * @retval HAL status
02952   */
02953 static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart)
02954 {
02955   /* Control the BSY flag */
02956   if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK)
02957   {
02958     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
02959     return HAL_TIMEOUT;
02960   }
02961   return HAL_OK;
02962 }
02963 
02964 /**
02965   * @brief  Handle the end of the RXTX transaction.
02966   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
02967   *               the configuration information for SPI module.
02968   * @retval None
02969   */
02970 static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi)
02971 {
02972   uint32_t tickstart = 0U;
02973   __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
02974   /* Init tickstart for timeout managment*/
02975   tickstart = HAL_GetTick();
02976 
02977   /* Disable ERR interrupt */
02978   __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
02979 
02980   /* Wait until TXE flag is set */
02981   do
02982   {
02983     if(count-- == 0U)
02984     {
02985       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
02986       break;
02987     }
02988   }
02989   while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
02990   
02991   /* Check the end of the transaction */
02992   if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart)!=HAL_OK)
02993   {
02994     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
02995   }
02996 
02997   /* Clear overrun flag in 2 Lines communication mode because received is not read */
02998   if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
02999   {
03000     __HAL_SPI_CLEAR_OVRFLAG(hspi);
03001   }
03002 
03003 #if (USE_SPI_CRC != 0U)
03004   /* Check if CRC error occurred */
03005   if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
03006   {
03007     hspi->State = HAL_SPI_STATE_READY;
03008     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
03009     __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
03010     HAL_SPI_ErrorCallback(hspi);
03011   }
03012   else
03013   {
03014 #endif /* USE_SPI_CRC */
03015     if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
03016     {
03017       if(hspi->State == HAL_SPI_STATE_BUSY_RX)
03018       {
03019         hspi->State = HAL_SPI_STATE_READY;
03020         HAL_SPI_RxCpltCallback(hspi);
03021       }
03022       else
03023       {
03024         hspi->State = HAL_SPI_STATE_READY;
03025         HAL_SPI_TxRxCpltCallback(hspi);
03026       }
03027     }
03028     else
03029     {
03030       hspi->State = HAL_SPI_STATE_READY;
03031       HAL_SPI_ErrorCallback(hspi);
03032     }
03033 #if (USE_SPI_CRC != 0U)
03034   }
03035 #endif /* USE_SPI_CRC */
03036 }
03037 
03038 /**
03039   * @brief  Handle the end of the RX transaction.
03040   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03041   *               the configuration information for SPI module.
03042   * @retval None
03043   */
03044 static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi)
03045 {
03046     /* Disable RXNE and ERR interrupt */
03047     __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
03048 
03049     /* Check the end of the transaction */
03050     if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
03051     {
03052       /* Disable SPI peripheral */
03053       __HAL_SPI_DISABLE(hspi);
03054     }
03055 
03056     /* Clear overrun flag in 2 Lines communication mode because received is not read */
03057     if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
03058     {
03059       __HAL_SPI_CLEAR_OVRFLAG(hspi);
03060     }
03061     hspi->State = HAL_SPI_STATE_READY;
03062 
03063 #if (USE_SPI_CRC != 0U)
03064     /* Check if CRC error occurred */
03065     if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
03066     {
03067       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
03068       __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
03069       HAL_SPI_ErrorCallback(hspi);
03070     }
03071     else
03072     {
03073 #endif /* USE_SPI_CRC */
03074       if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
03075       {
03076         HAL_SPI_RxCpltCallback(hspi);
03077       }
03078       else
03079       {
03080         HAL_SPI_ErrorCallback(hspi);
03081       }
03082 #if (USE_SPI_CRC != 0U)
03083     }
03084 #endif /* USE_SPI_CRC */
03085 }
03086 
03087 /**
03088   * @brief  Handle the end of the TX transaction.
03089   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03090   *               the configuration information for SPI module.
03091   * @retval None
03092   */
03093 static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi)
03094 {
03095   uint32_t tickstart = 0U;
03096   __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
03097 
03098   /* Init tickstart for timeout management*/
03099   tickstart = HAL_GetTick();
03100 
03101   /* Wait until TXE flag is set */
03102   do
03103   {
03104     if(count-- == 0U)
03105     {
03106       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03107       break;
03108     }
03109   }
03110   while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
03111 
03112   /* Disable TXE and ERR interrupt */
03113   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
03114 
03115   /* Check Busy flag */
03116   if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
03117   {
03118     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03119   }
03120 
03121   /* Clear overrun flag in 2 Lines communication mode because received is not read */
03122   if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
03123   {
03124     __HAL_SPI_CLEAR_OVRFLAG(hspi);
03125   }
03126 
03127   hspi->State = HAL_SPI_STATE_READY;
03128   if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
03129   {
03130     HAL_SPI_ErrorCallback(hspi);
03131   }
03132   else
03133   {
03134     HAL_SPI_TxCpltCallback(hspi);
03135   }
03136 }
03137 
03138 /**
03139   * @}
03140   */
03141 
03142 /**
03143   * @brief  Handle abort a Tx or Rx transaction.
03144   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03145   *               the configuration information for SPI module.
03146   * @retval None
03147   */
03148 static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi)
03149 {
03150   __IO uint32_t tmpreg = 0U;
03151   __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
03152 
03153   /* Wait until TXE flag is set */
03154   do
03155   {
03156     if(count-- == 0U)
03157     {
03158       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
03159       break;
03160     }
03161   }
03162   while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
03163 
03164   /* Disable SPI Peripheral */
03165   __HAL_SPI_DISABLE(hspi);    
03166 
03167   /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
03168   CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE));
03169 
03170   /* Flush DR Register */
03171   tmpreg = (*(__IO uint32_t *)&hspi->Instance->DR);
03172 
03173   /* To avoid GCC warning */
03174   UNUSED(tmpreg);
03175 }
03176 
03177 /**
03178   * @brief  Handle abort a Tx or Rx transaction.
03179   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
03180   *               the configuration information for SPI module.
03181   * @retval None
03182   */
03183 static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi)
03184 {
03185   /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */
03186   CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE));
03187 
03188   /* Disable SPI Peripheral */
03189   __HAL_SPI_DISABLE(hspi);
03190 }
03191 /**
03192   * @}
03193   */
03194 #endif /* HAL_SPI_MODULE_ENABLED */
03195 
03196 /**
03197   * @}
03198   */
03199 
03200 /**
03201   * @}
03202   */
03203 
03204 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/