STM32L0 - update spi HAL driver

This is a temporary update waiting for the next official release
pull/3288/head
Laurent MEUNIER 2016-11-16 14:07:10 +01:00
parent 65db01f457
commit 64a037cc8d
1 changed files with 647 additions and 250 deletions

View File

@ -165,16 +165,31 @@
* @{
*/
#define SPI_TIMEOUT_VALUE 10U
#define SPI_DEFAULT_TIMEOUT 100U
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void SPI_TxCloseIRQHandler(SPI_HandleTypeDef *hspi);
static void SPI_TxISR(SPI_HandleTypeDef *hspi);
static void SPI_RxCloseIRQHandler(SPI_HandleTypeDef *hspi);
static void SPI_2LinesRxISR(SPI_HandleTypeDef *hspi);
static void SPI_RxISR(SPI_HandleTypeDef *hspi);
static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart);
static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
#if (USE_SPI_CRC != 0U)
static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
#endif /* USE_SPI_CRC */
static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi);
static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi);
static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi);
static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
@ -1009,7 +1024,16 @@ HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, u
hspi->State = HAL_SPI_STATE_BUSY_TX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->TxISR = &SPI_TxISR;
/* Set the function for IT treatment */
if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
{
hspi->TxISR = SPI_TxISR_16BIT;
}
else
{
hspi->TxISR = SPI_TxISR_8BIT;
}
hspi->pTxBuffPtr = pData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
@ -1083,7 +1107,15 @@ HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, ui
hspi->State = HAL_SPI_STATE_BUSY_RX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->RxISR = &SPI_RxISR;
/* Set the function for IT treatment */
if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
{
hspi->RxISR = SPI_RxISR_16BIT;
}
else
{
hspi->RxISR = SPI_RxISR_8BIT;
}
hspi->pRxBuffPtr = pData;
hspi->RxXferSize = Size;
hspi->RxXferCount = Size ;
@ -1174,16 +1206,26 @@ HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *p
/* Configure communication */
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->TxISR = &SPI_TxISR;
hspi->pTxBuffPtr = pTxData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
hspi->RxISR = &SPI_2LinesRxISR;
hspi->pRxBuffPtr = pRxData;
hspi->RxXferSize = Size;
hspi->RxXferCount = Size;
/* Set the function for IT treatment */
if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
{
hspi->RxISR = SPI_2linesRxISR_16BIT;
hspi->TxISR = SPI_2linesTxISR_16BIT;
}
else
{
hspi->RxISR = SPI_2linesRxISR_8BIT;
hspi->TxISR = SPI_2linesTxISR_8BIT;
}
/* Reset CRC Calculation */
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
@ -1812,252 +1854,11 @@ uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi)
/**
* @}
*/
/**
* @}
*/
/** @addtogroup SPI_Private
* @{
*/
/**
* @brief Interrupt Handler to close Tx transfer
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval void
*/
static void SPI_TxCloseIRQHandler(SPI_HandleTypeDef *hspi)
{
/* Wait until TXE flag is set to send data */
if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_TXE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
}
/* Disable TXE interrupt */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE));
/* Disable ERR interrupt if Receive process is finished */
if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_RXNE) == RESET)
{
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_ERR));
/* Wait until Busy flag is reset before disabling SPI */
if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_BSY, SET, SPI_TIMEOUT_VALUE) != HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
}
/* Clear OVERUN flag in 2 Lines communication mode because received is not read */
if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
{
__HAL_SPI_CLEAR_OVRFLAG(hspi);
}
/* Check if Errors has been detected during transfer */
if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
{
/* Check if we are in Tx or in Rx/Tx Mode */
if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
{
/* Set state to READY before run the Callback Complete */
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_TxRxCpltCallback(hspi);
}
else
{
/* Set state to READY before run the Callback Complete */
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_TxCpltCallback(hspi);
}
}
else
{
/* Set state to READY before run the Callback Complete */
hspi->State = HAL_SPI_STATE_READY;
/* Call Error call back in case of Error */
HAL_SPI_ErrorCallback(hspi);
}
}
}
/**
* @brief Interrupt Handler to transmit amount of data in no-blocking mode
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval void
*/
static void SPI_TxISR(SPI_HandleTypeDef *hspi)
{
/* Transmit data in 8 Bit mode */
if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
{
hspi->Instance->DR = (*hspi->pTxBuffPtr++);
}
/* Transmit data in 16 Bit mode */
else
{
hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);
hspi->pTxBuffPtr+=2U;
}
hspi->TxXferCount--;
if(hspi->TxXferCount == 0U)
{
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
/* calculate and transfer CRC on Tx line */
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
SPI_TxCloseIRQHandler(hspi);
}
}
/**
* @brief Interrupt Handler to close Rx transfer
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval void
*/
static void SPI_RxCloseIRQHandler(SPI_HandleTypeDef *hspi)
{
__IO uint16_t tmpreg = 0U;
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
/* Wait until RXNE flag is set to read CRC data */
if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, SPI_TIMEOUT_VALUE) != HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
}
/* Read CRC to reset RXNE flag */
tmpreg = hspi->Instance->DR;
UNUSED(tmpreg); /* avoid warning on tmpreg affectation with some compiler */
/* Wait until RXNE flag is reset */
if(SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_TIMEOUT_VALUE) != HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
}
/* Check if CRC error occurred */
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
/* Reset CRC Calculation */
SPI_RESET_CRC(hspi);
}
}
/* Disable RXNE interrupt */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE));
/* if Transmit process is finished */
if(__HAL_SPI_GET_IT_SOURCE(hspi, SPI_IT_TXE) == RESET)
{
/* Disable ERR interrupt */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_ERR));
if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
{
/* Disable SPI peripheral */
__HAL_SPI_DISABLE(hspi);
}
/* Check if Errors has been detected during transfer */
if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
{
/* Check if we are in Rx or in Rx/Tx Mode */
if(hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
{
/* Set state to READY before run the Callback Complete */
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_TxRxCpltCallback(hspi);
}
else
{
/* Set state to READY before run the Callback Complete */
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_RxCpltCallback(hspi);
}
}
else
{
/* Set state to READY before run the Callback Complete */
hspi->State = HAL_SPI_STATE_READY;
/* Call Error call back in case of Error */
HAL_SPI_ErrorCallback(hspi);
}
}
}
/**
* @brief Interrupt Handler to receive amount of data in 2Lines mode
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval void
*/
static void SPI_2LinesRxISR(SPI_HandleTypeDef *hspi)
{
/* Receive data in 8 Bit mode */
if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
{
(*hspi->pRxBuffPtr++) = hspi->Instance->DR;
}
/* Receive data in 16 Bit mode */
else
{
*((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
hspi->pRxBuffPtr+=2U;
}
hspi->RxXferCount--;
if(hspi->RxXferCount==0U)
{
SPI_RxCloseIRQHandler(hspi);
}
}
/**
* @brief Interrupt Handler to receive amount of data in no-blocking mode
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval void
*/
static void SPI_RxISR(SPI_HandleTypeDef *hspi)
{
/* Receive data in 8 Bit mode */
if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
{
(*hspi->pRxBuffPtr++) = hspi->Instance->DR;
}
/* Receive data in 16 Bit mode */
else
{
*((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
hspi->pRxBuffPtr+=2U;
}
hspi->RxXferCount--;
/* Enable CRC Transmission */
if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
{
/* Set CRC Next to calculate CRC on Rx side */
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
if(hspi->RxXferCount == 0U)
{
SPI_RxCloseIRQHandler(hspi);
}
}
/**
* @brief DMA SPI transmit process complete callback
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
@ -2403,6 +2204,602 @@ static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(SPI_HandleTypeDef *hspi, uin
* @}
*/
/**
* @}
*/
/**
* @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
{
/* Receive data in 8bit mode */
*hspi->pRxBuffPtr++ = *((__IO uint8_t *)&hspi->Instance->DR);
hspi->RxXferCount--;
/* check end of the reception */
if(hspi->RxXferCount == 0U)
{
#if (USE_SPI_CRC != 0U)
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
hspi->RxISR = SPI_2linesRxISR_8BITCRC;
return;
}
#endif /* USE_SPI_CRC */
/* Disable RXNE interrupt */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
if(hspi->TxXferCount == 0U)
{
SPI_CloseRxTx_ISR(hspi);
}
}
}
#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
* the configuration information for SPI module.
* @retval None
*/
static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
{
__IO uint8_t tmpreg = 0U;
/* Read data register to flush CRC */
tmpreg = *((__IO uint8_t *)&hspi->Instance->DR);
/* To avoid GCC warning */
UNUSED(tmpreg);
/* Disable RXNE interrupt */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
if(hspi->TxXferCount == 0U)
{
SPI_CloseRxTx_ISR(hspi);
}
}
#endif /* USE_SPI_CRC */
/**
* @brief Tx 8-bit handler for Transmit and Receive in Interrupt mode.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
{
*(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++);
hspi->TxXferCount--;
/* check the end of the transmission */
if(hspi->TxXferCount == 0U)
{
#if (USE_SPI_CRC != 0U)
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
__HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
return;
}
#endif /* USE_SPI_CRC */
/* Disable TXE interrupt */
__HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
if(hspi->RxXferCount == 0U)
{
SPI_CloseRxTx_ISR(hspi);
}
}
}
/**
* @brief Rx 16-bit handler for Transmit and Receive in Interrupt mode.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
{
/* Receive data in 16 Bit mode */
*((uint16_t*)hspi->pRxBuffPtr) = hspi->Instance->DR;
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount--;
if(hspi->RxXferCount == 0U)
{
#if (USE_SPI_CRC != 0U)
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
hspi->RxISR = SPI_2linesRxISR_16BITCRC;
return;
}
#endif /* USE_SPI_CRC */
/* Disable RXNE interrupt */
__HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
if(hspi->TxXferCount == 0U)
{
SPI_CloseRxTx_ISR(hspi);
}
}
}
#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
* the configuration information for SPI module.
* @retval None
*/
static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
{
/* Receive data in 16 Bit mode */
__IO uint16_t tmpreg = 0U;
/* Read data register to flush CRC */
tmpreg = hspi->Instance->DR;
/* To avoid GCC warning */
UNUSED(tmpreg);
/* Disable RXNE interrupt */
__HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
SPI_CloseRxTx_ISR(hspi);
}
#endif /* USE_SPI_CRC */
/**
* @brief Tx 16-bit handler for Transmit and Receive in Interrupt mode.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
{
/* Transmit data in 16 Bit mode */
hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount--;
/* Enable CRC Transmission */
if(hspi->TxXferCount == 0U)
{
#if (USE_SPI_CRC != 0U)
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
__HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
return;
}
#endif /* USE_SPI_CRC */
/* Disable TXE interrupt */
__HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
if(hspi->RxXferCount == 0U)
{
SPI_CloseRxTx_ISR(hspi);
}
}
}
#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
* the configuration information for SPI module.
* @retval None
*/
static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi)
{
__IO uint8_t tmpreg = 0U;
/* Read data register to flush CRC */
tmpreg = *((__IO uint8_t*)&hspi->Instance->DR);
/* To avoid GCC warning */
UNUSED(tmpreg);
SPI_CloseRx_ISR(hspi);
}
#endif /* USE_SPI_CRC */
/**
* @brief Manage the receive 8-bit in Interrupt context.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
{
*hspi->pRxBuffPtr++ = (*(__IO uint8_t *)&hspi->Instance->DR);
hspi->RxXferCount--;
#if (USE_SPI_CRC != 0U)
/* Enable CRC Transmission */
if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
{
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif /* USE_SPI_CRC */
if(hspi->RxXferCount == 0U)
{
#if (USE_SPI_CRC != 0U)
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
hspi->RxISR = SPI_RxISR_8BITCRC;
return;
}
#endif /* USE_SPI_CRC */
SPI_CloseRx_ISR(hspi);
}
}
#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
* the configuration information for SPI module.
* @retval None
*/
static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi)
{
__IO uint16_t tmpreg = 0U;
/* Read data register to flush CRC */
tmpreg = hspi->Instance->DR;
/* To avoid GCC warning */
UNUSED(tmpreg);
/* Disable RXNE and ERR interrupt */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
SPI_CloseRx_ISR(hspi);
}
#endif /* USE_SPI_CRC */
/**
* @brief Manage the 16-bit receive in Interrupt context.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
{
*((uint16_t *)hspi->pRxBuffPtr) = hspi->Instance->DR;
hspi->pRxBuffPtr += sizeof(uint16_t);
hspi->RxXferCount--;
#if (USE_SPI_CRC != 0U)
/* Enable CRC Transmission */
if((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
{
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif /* USE_SPI_CRC */
if(hspi->RxXferCount == 0U)
{
#if (USE_SPI_CRC != 0U)
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
hspi->RxISR = SPI_RxISR_16BITCRC;
return;
}
#endif /* USE_SPI_CRC */
SPI_CloseRx_ISR(hspi);
}
}
/**
* @brief Handle the data 8-bit transmit in Interrupt mode.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
{
*(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr++);
hspi->TxXferCount--;
if(hspi->TxXferCount == 0U)
{
#if (USE_SPI_CRC != 0U)
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
/* Enable CRC Transmission */
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif /* USE_SPI_CRC */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE));
SPI_CloseTx_ISR(hspi);
}
}
/**
* @brief Handle the data 16-bit transmit in Interrupt mode.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
{
/* Transmit data in 16 Bit mode */
hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
hspi->pTxBuffPtr += sizeof(uint16_t);
hspi->TxXferCount--;
if(hspi->TxXferCount == 0U)
{
#if (USE_SPI_CRC != 0U)
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
/* Enable CRC Transmission */
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif /* USE_SPI_CRC */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE));
SPI_CloseTx_ISR(hspi);
}
}
/**
* @brief Handle SPI Communication Timeout.
* @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
* @retval HAL status
*/
static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart)
{
while((hspi->Instance->SR & Flag) != State)
{
if(Timeout != HAL_MAX_DELAY)
{
if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) >= Timeout))
{
/* Disable the SPI and reset the CRC: the CRC value should be cleared
on both master and slave sides in order to resynchronize the master
and slave for their respective CRC calculation */
/* Disable TXE, RXNE and ERR interrupts for the interrupt process */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
{
/* Disable SPI peripheral */
__HAL_SPI_DISABLE(hspi);
}
/* Reset CRC Calculation */
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
SPI_RESET_CRC(hspi);
}
hspi->State= HAL_SPI_STATE_READY;
/* Process Unlocked */
__HAL_UNLOCK(hspi);
return HAL_TIMEOUT;
}
}
}
return HAL_OK;
}
/**
* @brief Handle to check BSY flag before start a new transaction.
* @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
* @retval HAL status
*/
static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart)
{
/* 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;
}
return HAL_OK;
}
/**
* @brief Handle the end of the RXTX transaction.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi)
{
uint32_t tickstart = 0U;
__IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24 / 1000);
/* Init tickstart for timeout managment*/
tickstart = HAL_GetTick();
/* Disable ERR interrupt */
__HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
/* Wait until TXE flag is set */
do
{
if(count-- == 0)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
break;
}
}
while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
/* Check the end of the transaction */
if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart)!=HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
}
/* Clear overrun flag in 2 Lines communication mode because received is not read */
if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
{
__HAL_SPI_CLEAR_OVRFLAG(hspi);
}
#if (USE_SPI_CRC != 0U)
/* Check if CRC error occurred */
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
{
hspi->State = HAL_SPI_STATE_READY;
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
__HAL_SPI_CLEAR_CRCERRFLAG(hspi);
HAL_SPI_ErrorCallback(hspi);
}
else
{
#endif /* USE_SPI_CRC */
if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
{
if(hspi->State == HAL_SPI_STATE_BUSY_RX)
{
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_RxCpltCallback(hspi);
}
else
{
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_TxRxCpltCallback(hspi);
}
}
else
{
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_ErrorCallback(hspi);
}
#if (USE_SPI_CRC != 0U)
}
#endif /* USE_SPI_CRC */
}
/**
* @brief Handle the end of the RX transaction.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi)
{
/* Disable RXNE and ERR interrupt */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
/* Check the end of the transaction */
if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
{
/* Disable SPI peripheral */
__HAL_SPI_DISABLE(hspi);
}
/* Clear overrun flag in 2 Lines communication mode because received is not read */
if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
{
__HAL_SPI_CLEAR_OVRFLAG(hspi);
}
hspi->State = HAL_SPI_STATE_READY;
#if (USE_SPI_CRC != 0U)
/* Check if CRC error occurred */
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
__HAL_SPI_CLEAR_CRCERRFLAG(hspi);
HAL_SPI_ErrorCallback(hspi);
}
else
{
#endif /* USE_SPI_CRC */
if(hspi->ErrorCode == HAL_SPI_ERROR_NONE)
{
HAL_SPI_RxCpltCallback(hspi);
}
else
{
HAL_SPI_ErrorCallback(hspi);
}
#if (USE_SPI_CRC != 0U)
}
#endif /* USE_SPI_CRC */
}
/**
* @brief Handle the end of the TX transaction.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi)
{
uint32_t tickstart = 0U;
__IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24 / 1000);
/* Init tickstart for timeout management*/
tickstart = HAL_GetTick();
/* Wait until TXE flag is set */
do
{
if(count-- == 0)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
break;
}
}
while((hspi->Instance->SR & SPI_FLAG_TXE) == RESET);
/* Disable TXE and ERR interrupt */
__HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
/* Check Busy flag */
if(SPI_CheckFlag_BSY(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
}
/* Clear overrun flag in 2 Lines communication mode because received is not read */
if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
{
__HAL_SPI_CLEAR_OVRFLAG(hspi);
}
hspi->State = HAL_SPI_STATE_READY;
if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
{
HAL_SPI_ErrorCallback(hspi);
}
else
{
HAL_SPI_TxCpltCallback(hspi);
}
}
/**
* @}
*/