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