mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
Diff: targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_spi.c
- Revision:
- 180:96ed750bd169
- Parent:
- 156:95d6b41a828b
--- a/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_spi.c Thu Dec 07 14:01:42 2017 +0000 +++ b/targets/TARGET_STM/TARGET_STM32F0/device/stm32f0xx_hal_spi.c Wed Jan 17 15:23:54 2018 +0000 @@ -2,8 +2,6 @@ ****************************************************************************** * @file stm32f0xx_hal_spi.c * @author MCD Application Team - * @version V1.5.0 - * @date 04-November-2016 * @brief SPI HAL module driver. * This file provides firmware functions to manage the following * functionalities of the Serial Peripheral Interface (SPI) peripheral: @@ -60,9 +58,24 @@ (##) HAL_SPI_DeInit() (##) HAL_SPI_Init() [..] - Using the HAL it is not possible to reach all supported SPI frequency with the differents SPI Modes, - the following table resume the max SPI frequency reached with data size 8bits/16bits, - according to frequency used on APBx Peripheral Clock (fPCLK) used by the SPI instance : + The HAL drivers do not allow reaching all supported SPI frequencies in the different SPI + modes. Refer to the source code (stm32xxxx_hal_spi.c header) to get a summary of the + maximum SPI frequency that can be reached with a data size of 8 or 16 bits, depending on + the APBx peripheral clock frequency (fPCLK) used by the SPI instance. + + [..] + Data buffer address alignment restriction: + (#) In case more than 1 byte is requested to be transferred, the HAL SPI uses 16-bit access for data buffer. + But there is no support for unaligned accesses on the Cortex-M0 processor. + So, if the user wants to transfer more than 1 byte, it shall ensure that 16-bit aligned address is used for: + (##) pData parameter in HAL_SPI_Transmit(), HAL_SPI_Transmit_IT(), HAL_SPI_Receive() and HAL_SPI_Receive_IT() + (##) pTxData and pRxData parameters in HAL_SPI_TransmitReceive() and HAL_SPI_TransmitReceive_IT() + (#) There is no such restriction when going through DMA by using HAL_SPI_Transmit_DMA(), HAL_SPI_Receive_DMA() + and HAL_SPI_TransmitReceive_DMA(). + + @endverbatim + + Additional table : DataSize = SPI_DATASIZE_8BIT: +----------------------------------------------------------------------------------------------+ @@ -120,7 +133,6 @@ (#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA() (#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA() - @endverbatim ****************************************************************************** * @attention * @@ -262,7 +274,7 @@ /** * @brief Initialize the SPI according to the specified parameters * in the SPI_InitTypeDef and initialize the associated handle. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval HAL status */ @@ -349,7 +361,7 @@ /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/ /* Configure : SPI Mode, Communication Mode, Clock polarity and phase, NSS management, - Communication speed, First bit, CRC calculation state */ + Communication speed, First bit and CRC calculation state */ WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) | hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation)); @@ -361,7 +373,7 @@ } #endif /* USE_SPI_CRC */ - /* Configure : NSS management, TI Mode and Rx Fifo Threshold */ + /* Configure : NSS management, TI Mode, NSS Pulse, Data size and Rx Fifo Threshold */ WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode | hspi->Init.NSSPMode | hspi->Init.DataSize) | frxth); @@ -387,7 +399,7 @@ /** * @brief De-Initialize the SPI peripheral. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval HAL status */ @@ -421,7 +433,7 @@ /** * @brief Initialize the SPI MSP. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -437,7 +449,7 @@ /** * @brief De-Initialize the SPI MSP. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -490,11 +502,11 @@ /** * @brief Transmit an amount of data in blocking mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent - * @param Timeout: Timeout duration + * @param pData pointer to data buffer + * @param Size amount of data to be sent + * @param Timeout Timeout duration * @retval HAL status */ HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) @@ -502,6 +514,13 @@ uint32_t tickstart = 0U; HAL_StatusTypeDef errorcode = HAL_OK; + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (Size > 1U)) + { + /* in this case, 16-bit access is performed on Data + So, check Data is 16-bit aligned address */ + assert_param(IS_SPI_16BIT_ALIGNED_ADDRESS(pData)); + } + /* Check Direction parameter */ assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); @@ -561,7 +580,7 @@ /* Transmit data in 16 Bit mode */ if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) { - if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01)) + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U)) { hspi->Instance->DR = *((uint16_t *)pData); pData += sizeof(uint16_t); @@ -591,7 +610,7 @@ /* Transmit data in 8 Bit mode */ else { - if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01)) + if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01U)) { if (hspi->TxXferCount > 1U) { @@ -669,11 +688,11 @@ /** * @brief Receive an amount of data in blocking mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size: amount of data to be received - * @param Timeout: Timeout duration + * @param pData pointer to data buffer + * @param Size amount of data to be received + * @param Timeout Timeout duration * @retval HAL status */ HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) @@ -684,6 +703,13 @@ uint32_t tickstart = 0U; HAL_StatusTypeDef errorcode = HAL_OK; + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (Size > 1U)) + { + /* in this case, 16-bit access is performed on Data + So, check Data is 16-bit aligned address */ + assert_param(IS_SPI_16BIT_ALIGNED_ADDRESS(pData)); + } + if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES)) { hspi->State = HAL_SPI_STATE_BUSY_RX; @@ -733,7 +759,7 @@ } #endif /* USE_SPI_CRC */ - /* Set the Rx Fido threshold */ + /* Set the Rx FiFo threshold */ if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) { /* set fiforxthresold according the reception data length: 16bit */ @@ -899,12 +925,12 @@ /** * @brief Transmit and Receive an amount of data in blocking mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param pTxData: pointer to transmission data buffer - * @param pRxData: pointer to reception data buffer - * @param Size: amount of data to be sent and received - * @param Timeout: Timeout duration + * @param pTxData pointer to transmission data buffer + * @param pRxData pointer to reception data buffer + * @param Size amount of data to be sent and received + * @param Timeout Timeout duration * @retval HAL status */ HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, @@ -919,6 +945,14 @@ uint32_t txallowed = 1U; HAL_StatusTypeDef errorcode = HAL_OK; + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (Size > 1U)) + { + /* in this case, 16-bit access is performed on Data + So, check Data is 16-bit aligned address */ + assert_param(IS_SPI_16BIT_ALIGNED_ADDRESS(pTxData)); + assert_param(IS_SPI_16BIT_ALIGNED_ADDRESS(pRxData)); + } + /* Check Direction parameter */ assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); @@ -971,8 +1005,8 @@ } #endif /* USE_SPI_CRC */ - /* Set the Rx Fido threshold */ - if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (hspi->RxXferCount > 1)) + /* Set the Rx Fifo threshold */ + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (hspi->RxXferCount > 1U)) { /* set fiforxthreshold according the reception data length: 16bit */ CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); @@ -1191,16 +1225,23 @@ /** * @brief Transmit an amount of data in non-blocking mode with Interrupt. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @param pData pointer to data buffer + * @param Size amount of data to be sent * @retval HAL status */ HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) { HAL_StatusTypeDef errorcode = HAL_OK; + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (Size > 1U)) + { + /* in this case, 16-bit access is performed on Data + So, check Data is 16-bit aligned address */ + assert_param(IS_SPI_16BIT_ALIGNED_ADDRESS(pData)); + } + /* Check Direction parameter */ assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); @@ -1274,16 +1315,23 @@ /** * @brief Receive an amount of data in non-blocking mode with Interrupt. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @param pData pointer to data buffer + * @param Size amount of data to be sent * @retval HAL status */ HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) { HAL_StatusTypeDef errorcode = HAL_OK; + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (Size > 1U)) + { + /* in this case, 16-bit access is performed on Data + So, check Data is 16-bit aligned address */ + assert_param(IS_SPI_16BIT_ALIGNED_ADDRESS(pData)); + } + if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER)) { hspi->State = HAL_SPI_STATE_BUSY_RX; @@ -1319,16 +1367,16 @@ hspi->TxXferCount = 0U; hspi->TxISR = NULL; - /* check the data size to adapt Rx threshold and the set the function for IT treatment */ + /* Check the data size to adapt Rx threshold and the set the function for IT treatment */ if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) { - /* set fiforxthresold according the reception data length: 16 bit */ + /* Set fiforxthresold according the reception data length: 16 bit */ CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); hspi->RxISR = SPI_RxISR_16BIT; } else { - /* set fiforxthresold according the reception data length: 8 bit */ + /* Set fiforxthresold according the reception data length: 8 bit */ SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); hspi->RxISR = SPI_RxISR_8BIT; } @@ -1378,11 +1426,11 @@ /** * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param pTxData: pointer to transmission data buffer - * @param pRxData: pointer to reception data buffer - * @param Size: amount of data to be sent and received + * @param pTxData pointer to transmission data buffer + * @param pRxData pointer to reception data buffer + * @param Size amount of data to be sent and received * @retval HAL status */ HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) @@ -1390,6 +1438,14 @@ uint32_t tmp = 0U, tmp1 = 0U; HAL_StatusTypeDef errorcode = HAL_OK; + if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (Size > 1U)) + { + /* in this case, 16-bit access is performed on Data + So, check Data is 16-bit aligned address */ + assert_param(IS_SPI_16BIT_ALIGNED_ADDRESS(pTxData)); + assert_param(IS_SPI_16BIT_ALIGNED_ADDRESS(pRxData)); + } + /* Check Direction parameter */ assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); @@ -1456,15 +1512,15 @@ } #endif /* USE_SPI_CRC */ - /* check if packing mode is enabled and if there is more than 2 data to receive */ + /* Check if packing mode is enabled and if there is more than 2 data to receive */ if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (hspi->RxXferCount >= 2U)) { - /* set fiforxthresold according the reception data length: 16 bit */ + /* Set fiforxthresold according the reception data length: 16 bit */ CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); } else { - /* set fiforxthresold according the reception data length: 8 bit */ + /* Set fiforxthresold according the reception data length: 8 bit */ SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); } @@ -1486,16 +1542,19 @@ /** * @brief Transmit an amount of data in non-blocking mode with DMA. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param pData: pointer to data buffer - * @param Size: amount of data to be sent + * @param pData pointer to data buffer + * @param Size amount of data to be sent * @retval HAL status */ HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) { HAL_StatusTypeDef errorcode = HAL_OK; + /* check tx dma handle */ + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx)); + /* Check Direction parameter */ assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); @@ -1555,7 +1614,7 @@ hspi->hdmatx->XferAbortCallback = NULL; CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX); - /* packing mode is enabled only if the DMA setting is HALWORD */ + /* Packing mode is enabled only if the DMA setting is HALWORD */ if ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)) { /* Check the even/odd of the data size + crc if enabled */ @@ -1595,20 +1654,28 @@ /** * @brief Receive an amount of data in non-blocking mode with DMA. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @note In case of MASTER mode and SPI_DIRECTION_2LINES direction, hdmatx shall be defined. + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param pData: pointer to data buffer + * @param pData pointer to data buffer * @note When the CRC feature is enabled the pData Length must be Size + 1. - * @param Size: amount of data to be sent + * @param Size amount of data to be sent * @retval HAL status */ HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) { HAL_StatusTypeDef errorcode = HAL_OK; + /* check rx dma handle */ + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx)); + if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER)) { hspi->State = HAL_SPI_STATE_BUSY_RX; + + /* check tx dma handle */ + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx)); + /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size); } @@ -1656,7 +1723,7 @@ #endif /* USE_SPI_CRC */ #if defined (STM32F030x6) || defined (STM32F030x8) || defined (STM32F031x6)|| defined (STM32F038xx) || defined (STM32F051x8) || defined (STM32F058xx) - /* packing mode management is enabled by the DMA settings */ + /* Packing mode management is enabled by the DMA settings */ if ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)) { /* Restriction the DMA data received is not allowed in this mode */ @@ -1668,14 +1735,14 @@ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMARX); if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) { - /* set fiforxthresold according the reception data length: 16bit */ + /* Set fiforxthresold according the reception data length: 16bit */ CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); } else { - /* set fiforxthresold according the reception data length: 8bit */ + /* Set fiforxthresold according the reception data length: 8bit */ SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); - + if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) { /* set fiforxthresold according the reception data length: 16bit */ @@ -1730,12 +1797,12 @@ /** * @brief Transmit and Receive an amount of data in non-blocking mode with DMA. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param pTxData: pointer to transmission data buffer - * @param pRxData: pointer to reception data buffer + * @param pTxData pointer to transmission data buffer + * @param pRxData pointer to reception data buffer * @note When the CRC feature is enabled the pRxData Length must be Size + 1 - * @param Size: amount of data to be sent + * @param Size amount of data to be sent * @retval HAL status */ HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, @@ -1744,6 +1811,10 @@ uint32_t tmp = 0U, tmp1 = 0U; HAL_StatusTypeDef errorcode = HAL_OK; + /* check rx & tx dma handles */ + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx)); + assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx)); + /* Check Direction parameter */ assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); @@ -1802,18 +1873,19 @@ } #endif + /* Reset the threshold bit */ CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMATX | SPI_CR2_LDMARX); - /* the packing mode management is enabled by the DMA settings according the spi data size */ + /* The packing mode management is enabled by the DMA settings according the spi data size */ if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) { - /* set fiforxthreshold according the reception data length: 16bit */ + /* Set fiforxthreshold according the reception data length: 16bit */ CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); } else { - /* set fiforxthresold according the reception data length: 8bit */ + /* Set fiforxthresold according the reception data length: 8bit */ SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) @@ -1832,7 +1904,7 @@ if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD) { - /* set fiforxthresold according the reception data length: 16bit */ + /* Set fiforxthresold according the reception data length: 16bit */ CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD); if ((hspi->RxXferCount & 0x1U) == 0x0U) @@ -1918,25 +1990,46 @@ HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi) { HAL_StatusTypeDef errorcode; + __IO uint32_t count, resetcount; /* Initialized local variable */ errorcode = HAL_OK; + resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); + count = resetcount; /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)) { hspi->TxISR = SPI_AbortTx_ISR; - while (hspi->State != HAL_SPI_STATE_ABORT) + /* Wait HAL_SPI_STATE_ABORT state */ + do { + if (count-- == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } } + while (hspi->State != HAL_SPI_STATE_ABORT); + /* Reset Timeout Counter */ + count = resetcount; } if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) { hspi->RxISR = SPI_AbortRx_ISR; - while (hspi->State != HAL_SPI_STATE_ABORT) + /* Wait HAL_SPI_STATE_ABORT state */ + do { + if (count-- == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } } + while (hspi->State != HAL_SPI_STATE_ABORT); + /* Reset Timeout Counter */ + count = resetcount; } /* Clear ERRIE interrupts in case of DMA Mode */ @@ -2052,26 +2145,47 @@ { HAL_StatusTypeDef errorcode; uint32_t abortcplt ; + __IO uint32_t count, resetcount; /* Initialized local variable */ errorcode = HAL_OK; abortcplt = 1U; + resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); + count = resetcount; /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */ if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)) { hspi->TxISR = SPI_AbortTx_ISR; - while (hspi->State != HAL_SPI_STATE_ABORT) + /* Wait HAL_SPI_STATE_ABORT state */ + do { + if (count-- == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } } + while (hspi->State != HAL_SPI_STATE_ABORT); + /* Reset Timeout Counter */ + count = resetcount; } if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) { hspi->RxISR = SPI_AbortRx_ISR; - while (hspi->State != HAL_SPI_STATE_ABORT) + /* Wait HAL_SPI_STATE_ABORT state */ + do { + if (count-- == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } } + while (hspi->State != HAL_SPI_STATE_ABORT); + /* Reset Timeout Counter */ + count = resetcount; } /* Clear ERRIE interrupts in case of DMA Mode */ @@ -2213,7 +2327,7 @@ /** * @brief Pause the DMA Transfer. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for the specified SPI module. * @retval HAL status */ @@ -2233,7 +2347,7 @@ /** * @brief Resume the DMA Transfer. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for the specified SPI module. * @retval HAL status */ @@ -2253,7 +2367,7 @@ /** * @brief Stop the DMA Transfer. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for the specified SPI module. * @retval HAL status */ @@ -2284,7 +2398,7 @@ /** * @brief Handle SPI interrupt request. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for the specified SPI module. * @retval None */ @@ -2380,7 +2494,7 @@ /** * @brief Tx Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -2396,7 +2510,7 @@ /** * @brief Rx Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -2412,7 +2526,7 @@ /** * @brief Tx and Rx Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -2428,7 +2542,7 @@ /** * @brief Tx Half Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -2444,7 +2558,7 @@ /** * @brief Rx Half Transfer completed callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -2460,7 +2574,7 @@ /** * @brief Tx and Rx Half Transfer callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -2476,7 +2590,7 @@ /** * @brief SPI error callback. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -2529,7 +2643,7 @@ /** * @brief Return the SPI handle state. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval SPI state */ @@ -2541,7 +2655,7 @@ /** * @brief Return the SPI error code. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval SPI error code in bitmap format */ @@ -2566,7 +2680,7 @@ /** * @brief DMA SPI transmit process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ @@ -2613,7 +2727,7 @@ /** * @brief DMA SPI receive process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ @@ -2704,7 +2818,7 @@ /** * @brief DMA SPI transmit receive process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ @@ -2789,7 +2903,7 @@ /** * @brief DMA SPI half transmit process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ @@ -2802,7 +2916,7 @@ /** * @brief DMA SPI half receive process complete callback - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ @@ -2815,7 +2929,7 @@ /** * @brief DMA SPI half transmit receive process complete callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ @@ -2828,7 +2942,7 @@ /** * @brief DMA SPI communication error callback. - * @param hdma: pointer to a DMA_HandleTypeDef structure that contains + * @param hdma pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA module. * @retval None */ @@ -2986,7 +3100,7 @@ /** * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3036,7 +3150,7 @@ #if (USE_SPI_CRC != 0U) /** * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3068,7 +3182,7 @@ /** * @brief Tx 8-bit handler for Transmit and Receive in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3114,7 +3228,7 @@ /** * @brief Rx 16-bit handler for Transmit and Receive in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3148,7 +3262,7 @@ #if (USE_SPI_CRC != 0U) /** * @brief Manage the CRC 16-bit receive for Transmit and Receive in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3172,7 +3286,7 @@ /** * @brief Tx 16-bit handler for Transmit and Receive in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3210,7 +3324,7 @@ #if (USE_SPI_CRC != 0U) /** * @brief Manage the CRC 8-bit receive in Interrupt context. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3235,7 +3349,7 @@ /** * @brief Manage the receive 8-bit in Interrupt context. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3268,7 +3382,7 @@ #if (USE_SPI_CRC != 0U) /** * @brief Manage the CRC 16-bit receive in Interrupt context. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3291,7 +3405,7 @@ /** * @brief Manage the 16-bit receive in Interrupt context. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3324,7 +3438,7 @@ /** * @brief Handle the data 8-bit transmit in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3348,7 +3462,7 @@ /** * @brief Handle the data 16-bit transmit in Interrupt mode. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3374,12 +3488,12 @@ /** * @brief Handle SPI Communication Timeout. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param Flag: SPI flag to check - * @param State: flag state to check - * @param Timeout: Timeout duration - * @param Tickstart: tick start value + * @param Flag SPI flag to check + * @param State flag state to check + * @param Timeout Timeout duration + * @param Tickstart tick start value * @retval HAL status */ static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, @@ -3426,12 +3540,12 @@ /** * @brief Handle SPI FIFO Communication Timeout. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param Fifo: Fifo to check - * @param State: Fifo state to check - * @param Timeout: Timeout duration - * @param Tickstart: tick start value + * @param Fifo Fifo to check + * @param State Fifo state to check + * @param Timeout Timeout duration + * @param Tickstart tick start value * @retval HAL status */ static HAL_StatusTypeDef SPI_WaitFifoStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Fifo, uint32_t State, @@ -3487,10 +3601,10 @@ /** * @brief Handle the check of the RX transaction complete. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. - * @param Timeout: Timeout duration - * @param Tickstart: tick start value + * @param Timeout Timeout duration + * @param Tickstart tick start value * @retval HAL status */ static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart) @@ -3524,9 +3638,9 @@ /** * @brief Handle the check of the RXTX or TX transaction complete. - * @param hspi: SPI handle - * @param Timeout: Timeout duration - * @param Tickstart: tick start value + * @param hspi SPI handle + * @param Timeout Timeout duration + * @param Tickstart tick start value * @retval HAL status */ static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart) @@ -3537,18 +3651,26 @@ SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); return HAL_TIMEOUT; } + /* Control the BSY flag */ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK) { SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); return HAL_TIMEOUT; } + + /* Control if the RX fifo is empty */ + if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, Timeout, Tickstart) != HAL_OK) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); + return HAL_TIMEOUT; + } return HAL_OK; } /** * @brief Handle the end of the RXTX transaction. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3605,7 +3727,7 @@ /** * @brief Handle the end of the RX transaction. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3647,7 +3769,7 @@ /** * @brief Handle the end of the TX transaction. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ @@ -3686,21 +3808,32 @@ /** * @brief Handle abort a Rx transaction. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi) { + __IO uint32_t count; + /* Disable SPI Peripheral */ __HAL_SPI_DISABLE(hspi); + count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); + /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE)); - while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) + /* Check RXNEIE is disabled */ + do { + if (count-- == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } } + while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)); /* Control the BSY flag */ if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) @@ -3719,18 +3852,29 @@ /** * @brief Handle abort a Tx or Rx/Tx transaction. - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains + * @param hspi pointer to a SPI_HandleTypeDef structure that contains * the configuration information for SPI module. * @retval None */ static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi) { + __IO uint32_t count; + + count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); + /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */ CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE)); - while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)) + /* Check TXEIE is disabled */ + do { + if (count-- == 0U) + { + SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); + break; + } } + while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)); if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) {