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