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