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