TUKS MCU Introductory course / TUKS-COURSE-THERMOMETER

Fork of TUKS-COURSE-TIMER by TUKS MCU Introductory course

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers stm32l4xx_hal_spi.c Source File

stm32l4xx_hal_spi.c

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