2022-03-28 17:19:25 +08:00

1324 lines
36 KiB
C

#include "wm_spi.h"
static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
static void SPI_Transmit_IT(SPI_HandleTypeDef *hspi);
static void SPI_EndTransmit_IT(SPI_HandleTypeDef *hspi);
static void SPI_Receive_IT(SPI_HandleTypeDef *hspi);
static void SPI_EndReceive_IT(SPI_HandleTypeDef *hspi);
/**
* @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
* the configuration information for SPI module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
{
if (hspi == NULL)
{
return HAL_ERROR;
}
assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
assert_param(IS_SPI_MODE(hspi->Init.Mode));
// assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
assert_param(IS_SPI_NSS(hspi->Init.NSS));
assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
assert_param(IS_SPI_BIG_OR_LITTLE(hspi->Init.FirstByte));
if (hspi->State == HAL_SPI_STATE_RESET)
{
hspi->Lock = HAL_UNLOCKED;
HAL_SPI_MspInit(hspi);
}
hspi->State = HAL_SPI_STATE_BUSY;
__HAL_SPI_DISABLE_TXRX(hspi);
WRITE_REG(hspi->Instance->CH_CFG, (hspi->Init.NSS | SPI_CH_CFG_CLEARFIFOS));
WRITE_REG(hspi->Instance->SPI_CFG, (hspi->Init.Mode | hspi->Init.CLKPolarity | hspi->Init.CLKPhase | hspi->Init.FirstByte));
WRITE_REG(hspi->Instance->CLK_CFG, hspi->Init.BaudRatePrescaler);
__HAL_SPI_SET_CS_HIGH(hspi);
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->State = HAL_SPI_STATE_READY;
return HAL_OK;
}
/**
* @brief De-Initialize the SPI peripheral.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
{
if (hspi == NULL)
{
return HAL_ERROR;
}
assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
hspi->State = HAL_SPI_STATE_BUSY;
__HAL_SPI_DISABLE_TXRX(hspi);
HAL_SPI_MspDeInit(hspi);
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->State = HAL_SPI_STATE_RESET;
__HAL_UNLOCK(hspi);
return HAL_OK;
}
/**
* @brief Initialize the SPI MSP.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
__attribute__((weak)) void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
UNUSED(hspi);
}
/**
* @brief De-Initialize the SPI MSP.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
__attribute__((weak)) void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
{
UNUSED(hspi);
}
/**
* @brief Transmit an amount of data in blocking mode.
* @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
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
{
uint32_t tickstart, data = 0, i = 0;
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t fifo_count = 0, block_cnt = 0, tx_block_cnt = 0, tx_size = 0;
__HAL_LOCK(hspi);
tickstart = HAL_GetTick();
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
goto error;
}
if ((pData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
__HAL_SPI_CLEAR_FIFO(hspi);
__HAL_SPI_ENABLE_TX(hspi);
hspi->State = HAL_SPI_STATE_BUSY_TX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pRxBuffPtr = (uint8_t *)NULL;
hspi->RxXferSize = 0U;
hspi->RxXferCount = 0U;
block_cnt = Size / BLOCK_SIZE;
while (tx_block_cnt <= block_cnt)
{
if (tx_block_cnt < block_cnt)
{
tx_size = BLOCK_SIZE;
}
else
{
tx_size = Size % BLOCK_SIZE;
}
hspi->pTxBuffPtr = (uint8_t *)(pData + (tx_block_cnt * BLOCK_SIZE));
hspi->TxXferSize = tx_size;
hspi->TxXferCount = tx_size;
__HAL_SPI_SET_CLK_NUM(hspi, tx_size * 8);
__HAL_SPI_SET_START(hspi);
while (hspi->TxXferCount > 0U)
{
fifo_count = (32 - __HAL_SPI_GET_TXFIFO(hspi)) / 4;
while((fifo_count > 0) && (hspi->TxXferCount > 0))
{
data = 0;
for (i = 0; i < hspi->TxXferCount; i++)
{
if (i == 4)
{
break;
}
data |= (hspi->pTxBuffPtr[i] << (i * 8));
}
hspi->pTxBuffPtr += sizeof(uint8_t) * i;
hspi->TxXferCount -= i;
WRITE_REG(hspi->Instance->TXDATA, data);
if (fifo_count > 0)
{
fifo_count--;
}
}
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
while (__HAL_SPI_GET_FLAG(hspi, SPI_INT_SRC_DONE) != SPI_INT_SRC_DONE)
{
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
__HAL_SPI_CLEAR_FLAG(hspi, SPI_INT_SRC_DONE);
tx_block_cnt++;
}
error:
__HAL_SPI_DISABLE_TX(hspi);
hspi->State = HAL_SPI_STATE_READY;
__HAL_UNLOCK(hspi);
return errorcode;
}
/**
* @brief Receive an amount of data in blocking mode.
* @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
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size, uint32_t Timeout)
{
uint32_t tickstart, data = 0, i = 0;
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t fifo_count = 0, block_cnt = 0, rx_block_cnt = 0, rx_size = 0;
__HAL_LOCK(hspi);
tickstart = HAL_GetTick();
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
goto error;
}
if ((pData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
__HAL_SPI_CLEAR_FIFO(hspi);
__HAL_SPI_ENABLE_RX(hspi);
hspi->State = HAL_SPI_STATE_BUSY_RX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = (uint8_t *)NULL;
hspi->TxXferSize = 0U;
hspi->TxXferCount = 0U;
block_cnt = Size / BLOCK_SIZE;
while (rx_block_cnt <= block_cnt)
{
if (rx_block_cnt < block_cnt)
{
rx_size = BLOCK_SIZE;
}
else
{
rx_size = Size % BLOCK_SIZE;
}
hspi->pRxBuffPtr = (uint8_t *)(pData + rx_block_cnt * BLOCK_SIZE);
hspi->RxXferSize = rx_size;
hspi->RxXferCount = rx_size;
__HAL_SPI_SET_CLK_NUM(hspi, rx_size * 8);
__HAL_SPI_SET_START(hspi);
while (hspi->RxXferCount > 0U)
{
fifo_count = __HAL_SPI_GET_RXFIFO(hspi) / 4;
while ((fifo_count > 0) || (__HAL_SPI_GET_FLAG(hspi, SPI_INT_SRC_DONE) == SPI_INT_SRC_DONE))
{
data = READ_REG(hspi->Instance->RXDATA);
for (i = 0; i < 4; i++)
{
if (i == hspi->RxXferCount)
{
break;
}
hspi->pRxBuffPtr[i] = (data >> (i * 8)) & 0xFF;
}
hspi->pRxBuffPtr += sizeof(uint8_t) * i;
hspi->RxXferCount -= i;
if (fifo_count > 0)
{
fifo_count--;
}
if((hspi->RxXferCount == 0))
{
break;
}
}
if ((((HAL_GetTick() - tickstart) >= Timeout) && ((Timeout != HAL_MAX_DELAY))) || (Timeout == 0U))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
while (__HAL_SPI_GET_FLAG(hspi, SPI_INT_SRC_DONE) != SPI_INT_SRC_DONE)
{
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
__HAL_SPI_CLEAR_FLAG(hspi, SPI_INT_SRC_DONE);
rx_block_cnt++;
}
error :
__HAL_SPI_DISABLE_RX(hspi);
hspi->State = HAL_SPI_STATE_READY;
__HAL_UNLOCK(hspi);
return errorcode;
}
/**
* @brief Transmit and Receive an amount of data in blocking mode.
* @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
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint32_t Size,
uint32_t Timeout)
{
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t tickstart, data = 0, i = 0;
uint32_t fifo_count = 0, block_cnt = 0, tx_block_cnt = 0, tx_size = 0;
__HAL_LOCK(hspi);
tickstart = HAL_GetTick();
if (!((hspi->State == HAL_SPI_STATE_READY) || (hspi->State == HAL_SPI_STATE_BUSY_RX)))
{
errorcode = HAL_BUSY;
goto error;
}
if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
if (hspi->State != HAL_SPI_STATE_BUSY_RX)
{
hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
}
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
__HAL_SPI_CLEAR_FIFO(hspi);
__HAL_SPI_ENABLE_TXRX(hspi);
block_cnt = Size / BLOCK_SIZE;
while (tx_block_cnt <= block_cnt)
{
if (tx_block_cnt < block_cnt)
{
tx_size = BLOCK_SIZE;
}
else
{
tx_size = Size % BLOCK_SIZE;
}
hspi->pRxBuffPtr = (uint8_t *)(pRxData + (tx_block_cnt * BLOCK_SIZE));
hspi->RxXferCount = tx_size;
hspi->RxXferSize = tx_size;
hspi->pTxBuffPtr = (uint8_t *)(pTxData + (tx_block_cnt * BLOCK_SIZE));
hspi->TxXferCount = tx_size;
hspi->TxXferSize = tx_size;
__HAL_SPI_SET_CLK_NUM(hspi, tx_size * 8);
__HAL_SPI_SET_START(hspi);
while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
{
fifo_count = (32 - __HAL_SPI_GET_TXFIFO(hspi)) / 4;
while ((fifo_count > 0) && (hspi->TxXferCount > 0U))
{
data = 0;
for (i = 0; i < hspi->TxXferCount; i++)
{
if (i == 4)
{
break;
}
data |= (hspi->pTxBuffPtr[i] << (i * 8));
}
hspi->pTxBuffPtr += sizeof(uint8_t) * i;
hspi->TxXferCount -= i;
WRITE_REG(hspi->Instance->TXDATA, data);
if (fifo_count > 0)
{
fifo_count--;
}
}
fifo_count = __HAL_SPI_GET_RXFIFO(hspi) / 4 ;
while ((fifo_count > 0) || (__HAL_SPI_GET_FLAG(hspi, SPI_INT_SRC_DONE) == SPI_INT_SRC_DONE))
{
data = READ_REG(hspi->Instance->RXDATA);
for (i = 0; i < 4; i++)
{
if (i == hspi->RxXferCount)
{
break;
}
hspi->pRxBuffPtr[i] = (data >> (i * 8)) & 0xFF;
}
hspi->pRxBuffPtr += sizeof(uint8_t) * i;
hspi->RxXferCount -= i;
if (fifo_count > 0)
{
fifo_count--;
}
if (hspi->RxXferCount == 0)
{
break;
}
}
if ((((HAL_GetTick() - tickstart) >= Timeout) && ((Timeout != HAL_MAX_DELAY))) || (Timeout == 0U))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
while (__HAL_SPI_GET_FLAG(hspi, SPI_INT_SRC_DONE) != SPI_INT_SRC_DONE)
{
if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
__HAL_SPI_CLEAR_FLAG(hspi, SPI_INT_SRC_DONE);
tx_block_cnt++;
}
error :
__HAL_SPI_DISABLE_TXRX(hspi);
hspi->State = HAL_SPI_STATE_READY;
__HAL_UNLOCK(hspi);
return errorcode;
}
/**
* @brief Transmit an amount of data in non-blocking mode with Interrupt.
* @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
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size)
{
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t len = 0, data = 0, i = 0;
__HAL_LOCK(hspi);
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
goto error;
}
if ((pData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
__HAL_SPI_CLEAR_FIFO(hspi);
hspi->State = HAL_SPI_STATE_BUSY_TX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = (uint8_t *)pData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
hspi->pRxBuffPtr = (uint8_t *)NULL;
hspi->RxXferSize = 0U;
hspi->RxXferCount = 0U;
len = (hspi->TxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->TxXferCount;
__HAL_SPI_SET_CLK_NUM(hspi, (len * 8));
for (i = 0; i < hspi->TxXferCount; i++)
{
if (i == 4)
{
break;
}
data |= ((hspi->pTxBuffPtr + hspi->TxXferSize - hspi->TxXferCount)[i] << (i * 8));
}
hspi->Instance->TXDATA = data;
hspi->TxXferCount -= i;
__HAL_SPI_ENABLE_TX(hspi);
__HAL_SPI_CLEAR_FLAG(hspi, (SPI_INT_SRC_DONE | SPI_INT_SRC_TXOV | SPI_INT_SRC_TXUN | SPI_INT_SRC_TXRDY));
__HAL_SPI_ENABLE_IT(hspi, (SPI_INT_MASK_DONE | SPI_INT_MASK_TXUN | SPI_INT_SRC_TXRDY));
__HAL_SPI_SET_START(hspi);
error:
__HAL_UNLOCK(hspi);
return errorcode;
}
/**
* @brief Receive an amount of data in non-blocking mode with Interrupt.
* @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
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size)
{
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t len = 0;
__HAL_LOCK(hspi);
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
goto error;
}
if ((pData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
__HAL_SPI_CLEAR_FIFO(hspi);
hspi->State = HAL_SPI_STATE_BUSY_RX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = (uint8_t *)NULL;
hspi->TxXferSize = 0U;
hspi->TxXferCount = 0U;
hspi->pRxBuffPtr = (uint8_t *)pData;
hspi->RxXferSize = Size;
hspi->RxXferCount = Size;
len = (hspi->RxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->RxXferCount;
__HAL_SPI_SET_CLK_NUM(hspi, (len * 8));
__HAL_SPI_ENABLE_RX(hspi);
__HAL_SPI_CLEAR_FLAG(hspi, (SPI_INT_SRC_DONE | SPI_INT_SRC_RXOV | SPI_INT_SRC_RXUN | SPI_INT_SRC_RXRDY));
__HAL_SPI_ENABLE_IT(hspi, (SPI_INT_MASK_DONE | SPI_INT_MASK_RXOV | SPI_INT_SRC_RXRDY));
__HAL_SPI_SET_START(hspi);
error:
__HAL_UNLOCK(hspi);
return errorcode;
}
/**
* @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt.
* @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
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint32_t Size)
{
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t len = 0, data = 0, i = 0;
__HAL_LOCK(hspi);
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
goto error;
}
if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
__HAL_SPI_CLEAR_FIFO(hspi);
hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = (uint8_t *)pTxData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
hspi->pRxBuffPtr = (uint8_t *)pRxData;
hspi->RxXferSize = Size;
hspi->RxXferCount = Size;
len = (hspi->TxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->TxXferCount;
__HAL_SPI_SET_CLK_NUM(hspi, (len * 8));
for (i = 0; i < hspi->TxXferCount; i++)
{
if (i == 4)
{
break;
}
data |= ((hspi->pTxBuffPtr + hspi->TxXferSize - hspi->TxXferCount)[i] << (i * 8));
}
hspi->Instance->TXDATA = data;
hspi->TxXferCount -= i;
__HAL_SPI_ENABLE_TXRX(hspi);
__HAL_SPI_CLEAR_FLAG(hspi, (SPI_INT_SRC_DONE | SPI_INT_SRC_TXOV | SPI_INT_SRC_TXUN | SPI_INT_SRC_TXRDY |
SPI_INT_SRC_RXOV | SPI_INT_SRC_RXUN | SPI_INT_SRC_RXRDY));
__HAL_SPI_ENABLE_IT(hspi, (SPI_INT_MASK_DONE | SPI_INT_MASK_TXUN | SPI_INT_SRC_TXRDY | SPI_INT_MASK_RXOV | SPI_INT_SRC_RXRDY));
__HAL_SPI_SET_START(hspi);
error:
__HAL_UNLOCK(hspi);
return errorcode;
}
/**
* @brief Transmit an amount of data in non-blocking mode with DMA.
* @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
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size)
{
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t len = 0;
assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
__HAL_LOCK(hspi);
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
goto error;
}
if ((pData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
__HAL_SPI_CLEAR_FIFO(hspi);
hspi->State = HAL_SPI_STATE_BUSY_TX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = (uint8_t *)pData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
hspi->pRxBuffPtr = (uint8_t *)NULL;
hspi->RxXferSize = 0U;
hspi->RxXferCount = 0U;
hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
hspi->hdmatx->XferAbortCallback = NULL;
len = (hspi->TxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->TxXferCount;
hspi->TxXferCount -= len;
__HAL_SPI_SET_CLK_NUM(hspi, (len * 8));
if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx,
(uint32_t)hspi->pTxBuffPtr,
(uint32_t)&hspi->Instance->TXDATA,
len))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
errorcode = HAL_ERROR;
hspi->State = HAL_SPI_STATE_READY;
goto error;
}
__HAL_SPI_ENABLE_TX(hspi);
__HAL_SPI_CLEAR_FLAG(hspi, (SPI_INT_SRC_DONE | SPI_INT_SRC_TXOV | SPI_INT_SRC_TXUN | SPI_INT_SRC_TXRDY));
__HAL_SPI_ENABLE_IT(hspi, (SPI_INT_MASK_DONE | SPI_INT_MASK_TXUN));
SET_BIT(hspi->Instance->MODE_CFG, SPI_MODE_CFG_TXDMA);
__HAL_SPI_SET_START(hspi);
error:
__HAL_UNLOCK(hspi);
return errorcode;
}
/**
* @brief Receive an amount of data in non-blocking mode with DMA.
* @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
* @note When the CRC feature is enabled the pData Length must be Size + 1.
* @param Size amount of data to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint32_t Size)
{
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t len = 0;
assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
__HAL_LOCK(hspi);
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
goto error;
}
if ((pData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
__HAL_SPI_CLEAR_FIFO(hspi);
hspi->State = HAL_SPI_STATE_BUSY_RX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pRxBuffPtr = (uint8_t *)pData;
hspi->RxXferSize = Size;
hspi->RxXferCount = Size;
hspi->pTxBuffPtr = (uint8_t *)NULL;
hspi->TxXferSize = 0U;
hspi->TxXferCount = 0U;
hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
hspi->hdmarx->XferAbortCallback = NULL;
len = (hspi->RxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->RxXferCount;
hspi->RxXferCount -= len;
__HAL_SPI_SET_CLK_NUM(hspi, (len * 8));
if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx,
(uint32_t)&hspi->Instance->RXDATA,
(uint32_t)hspi->pRxBuffPtr,
len))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
errorcode = HAL_ERROR;
hspi->State = HAL_SPI_STATE_READY;
goto error;
}
__HAL_SPI_ENABLE_RX(hspi);
__HAL_SPI_CLEAR_FLAG(hspi, (SPI_INT_SRC_DONE | SPI_INT_SRC_RXOV | SPI_INT_SRC_RXUN | SPI_INT_SRC_RXRDY));
__HAL_SPI_ENABLE_IT(hspi, (SPI_INT_MASK_DONE | SPI_INT_MASK_RXOV));
SET_BIT(hspi->Instance->MODE_CFG, SPI_MODE_CFG_RXDMA);
__HAL_SPI_SET_START(hspi);
error:
__HAL_UNLOCK(hspi);
return errorcode;
}
/**
* @brief Transmit and Receive an amount of data in non-blocking mode with DMA.
* @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
* @note When the CRC feature is enabled the pRxData Length must be Size + 1
* @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,
uint32_t Size)
{
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t len = 0;
assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
__HAL_LOCK(hspi);
if (hspi->State != HAL_SPI_STATE_READY)
{
errorcode = HAL_BUSY;
goto error;
}
if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
__HAL_SPI_CLEAR_FIFO(hspi);
hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pTxBuffPtr = (uint8_t *)pTxData;
hspi->TxXferSize = Size;
hspi->TxXferCount = Size;
hspi->pRxBuffPtr = (uint8_t *)pRxData;
hspi->RxXferSize = Size;
hspi->RxXferCount = Size;
hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
hspi->hdmatx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
hspi->hdmatx->XferAbortCallback = NULL;
hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt;
hspi->hdmarx->XferAbortCallback = NULL;
len = (hspi->TxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->TxXferCount;
hspi->TxXferCount -= len;
hspi->RxXferCount -= len;
__HAL_SPI_SET_CLK_NUM(hspi, (len * 8));
if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx,
(uint32_t)hspi->pTxBuffPtr,
(uint32_t)&hspi->Instance->TXDATA,
len))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
errorcode = HAL_ERROR;
hspi->State = HAL_SPI_STATE_READY;
goto error;
}
if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx,
(uint32_t)&hspi->Instance->RXDATA,
(uint32_t)hspi->pRxBuffPtr,
len))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
errorcode = HAL_ERROR;
hspi->State = HAL_SPI_STATE_READY;
goto error;
}
__HAL_SPI_ENABLE_TXRX(hspi);
__HAL_SPI_CLEAR_FLAG(hspi, (SPI_INT_SRC_DONE | SPI_INT_SRC_TXOV | SPI_INT_SRC_TXUN | SPI_INT_SRC_TXRDY |
SPI_INT_SRC_RXOV | SPI_INT_SRC_RXUN | SPI_INT_SRC_RXRDY));
__HAL_SPI_ENABLE_IT(hspi, (SPI_INT_MASK_DONE | SPI_INT_MASK_TXUN | SPI_INT_MASK_RXOV));
SET_BIT(hspi->Instance->MODE_CFG, (SPI_MODE_CFG_TXDMA | SPI_MODE_CFG_RXDMA));
__HAL_SPI_SET_START(hspi);
error:
__HAL_UNLOCK(hspi);
return errorcode;
}
/**
* @brief Pause the DMA Transfer.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for the specified SPI module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
{
__HAL_LOCK(hspi);
CLEAR_BIT(hspi->Instance->MODE_CFG, (SPI_MODE_CFG_TXDMA | SPI_MODE_CFG_RXDMA));
__HAL_UNLOCK(hspi);
return HAL_OK;
}
/**
* @brief Resume the DMA Transfer.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for the specified SPI module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
{
__HAL_LOCK(hspi);
if (hspi->State == HAL_SPI_STATE_BUSY_TX)
{
SET_BIT(hspi->Instance->MODE_CFG, SPI_MODE_CFG_TXDMA);
}
else if (hspi->State == HAL_SPI_STATE_BUSY_RX)
{
SET_BIT(hspi->Instance->MODE_CFG, SPI_MODE_CFG_RXDMA);
}
else if (hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
{
SET_BIT(hspi->Instance->MODE_CFG, (SPI_MODE_CFG_TXDMA | SPI_MODE_CFG_RXDMA));
}
__HAL_UNLOCK(hspi);
return HAL_OK;
}
/**
* @brief Stop the DMA Transfer.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for the specified SPI module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
{
HAL_StatusTypeDef errorcode = HAL_OK;
if (hspi->hdmatx != NULL)
{
if (HAL_OK != HAL_DMA_Abort(hspi->hdmatx))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
errorcode = HAL_ERROR;
}
}
if (hspi->hdmarx != NULL)
{
if (HAL_OK != HAL_DMA_Abort(hspi->hdmarx))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
errorcode = HAL_ERROR;
}
}
CLEAR_BIT(hspi->Instance->MODE_CFG, (SPI_MODE_CFG_TXDMA | SPI_MODE_CFG_RXDMA));
hspi->State = HAL_SPI_STATE_READY;
return errorcode;
}
/**
* @brief Handle SPI interrupt request.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for the specified SPI module.
* @retval None
*/
void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
{
uint32_t itmask = hspi->Instance->INT_MASK;
uint32_t itflag = hspi->Instance->INT_SRC;
__HAL_SPI_CLEAR_FLAG(hspi, itflag);
if (hspi->Instance->CH_CFG & SPI_CH_CFG_TXON)
{
if (((itflag & SPI_INT_SRC_TXRDY) == SPI_INT_SRC_TXRDY) && ((itmask & SPI_INT_MASK_TXRDY) == RESET))
{
SPI_Transmit_IT(hspi);
}
if (((itflag & SPI_INT_SRC_DONE) == SPI_INT_SRC_DONE) && ((itmask & SPI_INT_MASK_DONE) == RESET))
{
SPI_EndTransmit_IT(hspi);
}
if (((itflag & SPI_INT_SRC_TXUN) == SPI_INT_SRC_TXUN) && ((itmask & SPI_INT_MASK_TXUN) == RESET))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TXERR);
HAL_SPI_ErrorCallback(hspi);
}
}
if (hspi->Instance->CH_CFG & SPI_CH_CFG_RXON)
{
if (((itflag & SPI_INT_SRC_RXRDY) == SPI_INT_SRC_RXRDY) && ((itmask & SPI_INT_MASK_RXRDY) == RESET))
{
SPI_Receive_IT(hspi);
}
if (((itflag & SPI_INT_SRC_DONE) == SPI_INT_SRC_DONE) && ((itmask & SPI_INT_MASK_DONE) == RESET))
{
SPI_EndReceive_IT(hspi);
}
if (((itflag & SPI_INT_SRC_RXOV) == SPI_INT_SRC_RXOV) && ((itmask & SPI_INT_MASK_RXOV) == RESET))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_RXERR);
HAL_SPI_ErrorCallback(hspi);
}
}
}
/**
* @brief Tx Transfer completed callback.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
__attribute__((weak)) void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
UNUSED(hspi);
}
/**
* @brief Rx Transfer completed callback.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
__attribute__((weak)) void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
UNUSED(hspi);
}
/**
* @brief Tx and Rx Transfer completed callback.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
__attribute__((weak)) void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
UNUSED(hspi);
}
/**
* @brief Tx Half Transfer completed callback.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
__attribute__((weak)) void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi)
{
UNUSED(hspi);
}
/**
* @brief Rx Half Transfer completed callback.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
__attribute__((weak)) void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi)
{
UNUSED(hspi);
}
/**
* @brief Tx and Rx Half Transfer callback.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
__attribute__((weak)) void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi)
{
UNUSED(hspi);
}
/**
* @brief SPI error callback.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval None
*/
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi)
{
UNUSED(hspi);
}
/**
* @brief Return the SPI handle state.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval SPI state
*/
HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi)
{
return hspi->State;
}
/**
* @brief Return the SPI error code.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @retval SPI error code in bitmap format
*/
uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi)
{
return hspi->ErrorCode;
}
/**
* @brief DMA SPI transmit process complete callback.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
if ((hspi->TxXferCount == 0) && ((hdma->Init.Mode == DMA_MODE_NORMAL_SINGLE) || (hdma->Init.Mode == DMA_MODE_LINK_SINGLE)))
{
CLEAR_BIT(hspi->Instance->MODE_CFG, SPI_MODE_CFG_TXDMA);
}
}
/**
* @brief DMA SPI half transmit process complete callback.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma)
{
SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
if (hspi->TxXferSize <= BLOCK_SIZE)
{
HAL_SPI_TxHalfCpltCallback(hspi);
}
}
/**
* @brief DMA SPI receive process complete callback.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
{
SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
if ((hspi->RxXferCount == 0) && ((hdma->Init.Mode == DMA_MODE_NORMAL_SINGLE) || (hdma->Init.Mode == DMA_MODE_LINK_SINGLE)))
{
CLEAR_BIT(hspi->Instance->MODE_CFG, SPI_MODE_CFG_RXDMA);
}
}
/**
* @brief DMA SPI half receive process complete callback
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma)
{
SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
if (hspi->RxXferSize <= BLOCK_SIZE)
{
HAL_SPI_RxHalfCpltCallback(hspi);
}
}
/**
* @brief DMA SPI transmit receive process complete callback.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
{
SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
if ((hdma->Init.Mode == DMA_MODE_NORMAL_SINGLE) || (hdma->Init.Mode == DMA_MODE_LINK_SINGLE))
{
if ((hspi->hdmarx == hdma) && (hspi->RxXferCount == 0))
{
CLEAR_BIT(hspi->Instance->MODE_CFG, SPI_MODE_CFG_RXDMA);
}
if ((hspi->hdmatx == hdma) && (hspi->TxXferCount == 0))
{
CLEAR_BIT(hspi->Instance->MODE_CFG, SPI_MODE_CFG_TXDMA);
}
}
}
/**
* @brief DMA SPI half transmit receive process complete callback.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
{
SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent);
HAL_SPI_TxRxHalfCpltCallback(hspi);
}
static void SPI_Transmit_IT(SPI_HandleTypeDef *hspi)
{
uint32_t data = 0, i = 0;
if (((hspi->TxXferSize - hspi->TxXferCount) % BLOCK_SIZE) == 0)
{
return;
}
for (i = 0; i < hspi->TxXferCount; i++)
{
if (i == 4)
{
break;
}
data |= ((hspi->pTxBuffPtr + hspi->TxXferSize - hspi->TxXferCount)[i] << (i * 8));
}
hspi->Instance->TXDATA = data;
hspi->TxXferCount -= i;
}
static void SPI_EndTransmit_IT(SPI_HandleTypeDef *hspi)
{
uint32_t len = 0;
len = (hspi->TxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->TxXferCount;
if (len == 0)
{
#if 0
if ((hspi->hdmatx->Init.Mode == DMA_MODE_NORMAL_CIRCULAR) || (hspi->hdmatx->Init.Mode == DMA_MODE_LINK_CIRCULAR))
{
hspi->TxXferCount = hspi->TxXferSize;
len = (hspi->TxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->TxXferCount;
__HAL_SPI_SET_CLK_NUM(hspi, len * 8);
__HAL_SPI_SET_START(hspi);
}
else //if ((hspi->hdmatx->Init.Mode == DMA_MODE_NORMAL_SINGLE) || (hspi->hdmatx->Init.Mode == DMA_MODE_LINK_SINGLE))
#endif
{
__HAL_SPI_DISABLE_IT(hspi, (SPI_INT_MASK_DONE | SPI_INT_MASK_TXRDY | SPI_INT_MASK_TXUN));
if (hspi->State == HAL_SPI_STATE_BUSY_TX)
{
__HAL_SPI_DISABLE_TX(hspi);
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_TxCpltCallback(hspi);
}
else if (hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
{
__HAL_SPI_DISABLE_TX(hspi);
__HAL_SPI_DISABLE_RX(hspi);
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_TxRxCpltCallback(hspi);
}
}
}
else
{
__HAL_SPI_SET_CLK_NUM(hspi, (len * 8));
if ((hspi->Instance->MODE_CFG & SPI_MODE_CFG_TXDMA) == SPI_MODE_CFG_TXDMA)
{
HAL_DMA_Start_IT(hspi->hdmatx,
(uint32_t)(hspi->pTxBuffPtr + (hspi->TxXferSize - hspi->TxXferCount)),
(uint32_t)&(hspi->Instance->TXDATA),
len);
hspi->TxXferCount -= len;
}
else
{
uint32_t data = 0, i = 0;
for (i = 0; i < hspi->TxXferCount; i++)
{
if (i == 4)
{
break;
}
data |= ((hspi->pTxBuffPtr + hspi->TxXferSize - hspi->TxXferCount)[i] << (i * 8));
}
hspi->Instance->TXDATA = data;
hspi->TxXferCount -= i;
}
__HAL_SPI_SET_START(hspi);
}
}
static void SPI_Receive_IT(SPI_HandleTypeDef *hspi)
{
uint32_t i = 0, data = 0;
uint32_t fifo_count = __HAL_SPI_GET_RXFIFO(hspi) / 4;
while (fifo_count > 0)
{
data = READ_REG(hspi->Instance->RXDATA);
for (i = 0; i < 4; i++)
{
if (i == hspi->RxXferCount)
{
break;
}
(hspi->pRxBuffPtr + hspi->RxXferSize - hspi->RxXferCount)[i] = (data >> (i * 8)) & 0xFF;
}
hspi->RxXferCount -= i;
fifo_count--;
if((hspi->RxXferCount == 0))
{
break;
}
}
}
static void SPI_EndReceive_IT(SPI_HandleTypeDef *hspi)
{
uint32_t len = 0;
len = (hspi->RxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->RxXferCount;
if (len == 0)
{
#if 0
if ((hspi->hdmatx->Init.Mode == DMA_MODE_NORMAL_CIRCULAR) || (hspi->hdmatx->Init.Mode == DMA_MODE_LINK_CIRCULAR))
{
hspi->RxXferCount = hspi->RxXferSize;
len = (hspi->RxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : hspi->RxXferCount;
__HAL_SPI_SET_CLK_NUM(hspi, len * 8);
__HAL_SPI_SET_START(hspi);
}
else //if ((hspi->hdmatx->Init.Mode == DMA_MODE_NORMAL_SINGLE) || (hspi->hdmatx->Init.Mode == DMA_MODE_LINK_SINGLE))
#endif
{
__HAL_SPI_DISABLE_IT(hspi, (SPI_INT_MASK_DONE | SPI_INT_MASK_RXRDY | SPI_INT_MASK_RXOV));
if (hspi->State == HAL_SPI_STATE_BUSY_RX)
{
__HAL_SPI_DISABLE_RX(hspi);
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_RxCpltCallback(hspi);
}
else if (hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
{
__HAL_SPI_DISABLE_TX(hspi);
__HAL_SPI_DISABLE_RX(hspi);
hspi->State = HAL_SPI_STATE_READY;
HAL_SPI_TxRxCpltCallback(hspi);
}
}
}
else
{
__HAL_SPI_SET_CLK_NUM(hspi, len * 8);
if ((hspi->Instance->MODE_CFG & SPI_MODE_CFG_RXDMA) == SPI_MODE_CFG_RXDMA)
{
HAL_DMA_Start_IT(hspi->hdmarx,
(uint32_t)&(hspi->Instance->RXDATA),
(uint32_t)(hspi->pRxBuffPtr + (hspi->RxXferSize - hspi->RxXferCount)),
len);
hspi->RxXferCount -= len;
}
else
{
SPI_Receive_IT(hspi);
}
__HAL_SPI_SET_START(hspi);
}
}