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