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