/**************************************************************************//**
|
* @file pan_hal_spi.c
|
* @version V0.0.0
|
* $Revision: 1 $
|
* $Date: 23/09/10 $
|
* @brief Panchip series SPI (Serial Peripheral Interface) HAL source file.
|
* @note
|
* Copyright (C) 2023 Panchip Technology Corp. All rights reserved.
|
*****************************************************************************/
|
|
|
#include "pan_hal.h"
|
|
SPI_HandleTypeDef spiHandleArray[2] =
|
{
|
{
|
.pSpix = SPI0,
|
.initObj = {0},
|
.interruptObj = {0},
|
.xferStat = SPI_STAT_NULL,
|
.pTxBuffPtr = NULL,
|
.txXferSize = 0,
|
.txXferCount = 0,
|
.pRxBuffPtr = NULL,
|
.rxXferSize = 0,
|
.rxXferCount = 0,
|
.IRQn = SPI0_IRQn, // Adjust this to appropriate IRQn_Type value
|
.rxIntCallback = NULL,
|
.txIntCallback = NULL,
|
.dmaSrc = DMAC_Peripheral_SPI0_Rx,
|
.dmaDst = DMAC_Peripheral_SPI0_Tx,
|
.errorCode = 0
|
},
|
{
|
.pSpix = SPI1,
|
.initObj = {0},
|
.interruptObj = {0},
|
.xferStat = SPI_STAT_NULL,
|
.pTxBuffPtr = NULL,
|
.txXferSize = 0,
|
.txXferCount = 0,
|
.pRxBuffPtr = NULL,
|
.rxXferSize = 0,
|
.rxXferCount = 0,
|
.IRQn = SPI1_IRQn, // Adjust this to appropriate IRQn_Type value
|
.rxIntCallback = NULL,
|
.txIntCallback = NULL,
|
.dmaSrc = DMAC_Peripheral_SPI1_Rx,
|
.dmaDst = DMAC_Peripheral_SPI1_Tx,
|
.errorCode = 0
|
}
|
};
|
|
|
|
void HAL_SPI_Init(SPI_HandleTypeDef *pSpi)
|
{
|
uint32_t tmpreg = 0;
|
//uint8_t baud_div = CalcDivisorByBaudrate(pSpi);
|
|
if(SPI_IsSpiEnabled(pSpi->pSpix))
|
SPI_DisableSpi(pSpi->pSpix);
|
|
tmpreg = pSpi->pSpix->CR0;
|
|
tmpreg &= ~(SPI_CR0_SPH_Msk | SPI_CR0_SPO_Msk | SPI_CR0_DSS_Msk);
|
tmpreg |= (
|
((pSpi->initObj.clkPhase << SPI_CR0_SPH_Pos) & SPI_CR0_SPH_Msk ) | \
|
((pSpi->initObj.clkPolarity << SPI_CR0_SPO_Pos) & SPI_CR0_SPO_Msk ) | \
|
((pSpi->initObj.dataSize << SPI_CR0_DSS_Pos) & SPI_CR0_DSS_Msk ) \
|
);
|
tmpreg &= ~(SPI_CR0_FRF_Msk);
|
tmpreg |= (pSpi->initObj.format << SPI_CR0_FRF_Pos);
|
tmpreg &= ~(SPI_CR0_SCR_Msk);
|
// tmpreg |= ((pSpi->SPI_InitStruct->SPI_baudRateDiv-1) << SPI_CR0_SCR_Pos); //Fixed SCR to 0, only use CPSR to config baudrate
|
//tmpreg |= ((baud_div-1) << SPI_CR0_SCR_Pos); //Fixed SCR to 0, only use CPSR to config baudrate
|
tmpreg |= ((pSpi->initObj.baudrateDiv-1) << SPI_CR0_SCR_Pos); //Fixed SCR to 0, only use CPSR to config baudrate
|
pSpi->pSpix->CR0 = tmpreg;
|
|
//Baudrate Config, expect_baudrate = apb_clk / ((1 + SCR) * CPSR)
|
pSpi->pSpix->CPSR = 2;//SPI_InitStruct->SPI_baudRateDiv;
|
|
//role Select
|
if(pSpi->initObj.role == SPI_RoleSlave)
|
{
|
pSpi->pSpix->CR1 |= SPI_CR1_MS_Msk;
|
}
|
else
|
{
|
pSpi->pSpix->CR1 &= ~SPI_CR1_MS_Msk;
|
}
|
|
SPI_EnableSpi(pSpi->pSpix);
|
}
|
|
void HAL_SPI_DeInit(SPI_HandleTypeDef *pSpi){
|
SPI_DisableSpi(pSpi->pSpix);
|
}
|
|
void HAL_SPI_Init_INT(SPI_HandleTypeDef *pSpi){
|
SPI_EnableIrq(pSpi->pSpix, pSpi->interruptObj.Mode);
|
}
|
|
void HAL_SPI_DeInit_INT(SPI_HandleTypeDef *pSpi){
|
SPI_DisableIrq(pSpi->pSpix, pSpi->interruptObj.Mode);
|
}
|
|
|
// Receive multiple data from specified SPI, and return the size of actual data received
|
static size_t HAL_SPI_RecvMultiDataAsync(SPI_T* pSpix, uint16_t* data, size_t expectRecvSize)
|
{
|
size_t i = 0;
|
for (; i < expectRecvSize; i++)
|
{
|
// Fetch data from Rx FIFO until it's empty
|
if (!SPI_IsRxFifoEmpty(pSpix))
|
{
|
data[i] = SPI_ReceiveData(pSpix);
|
}
|
else
|
{
|
break;
|
}
|
}
|
return i;
|
}
|
|
// Send multiple data to specified SPI, and return the size of actual data sent
|
static size_t HAL_SPI_SendMultiDataAsync(SPI_T* pSpix, const uint16_t* data, size_t expectSendSize)
|
{
|
size_t i = 0;
|
for (; i < expectSendSize; i++)
|
{
|
// Fill data into Tx FIFO until it's full
|
if (!SPI_IsTxFifoFull(pSpix))
|
{
|
SPI_SendData(pSpix, data[i]);
|
}
|
else
|
{
|
break;
|
}
|
}
|
return i;
|
}
|
|
void HAL_SPI_SendData(SPI_HandleTypeDef *pSpi, uint16_t *pBuf, size_t size, uint32_t timeout)
|
{
|
pSpi->txXferSize = size;
|
pSpi->txXferCount =0;
|
pSpi->pTxBuffPtr = pBuf;
|
|
while (pSpi->txXferCount < pSpi->txXferSize)
|
{
|
if (!SPI_IsTxFifoFull(pSpi->pSpix))
|
{
|
SPI_SendData(pSpi->pSpix, pSpi->pTxBuffPtr[pSpi->txXferCount++]);
|
}
|
}
|
while(SPI_IsBusy(pSpi->pSpix)){}
|
}
|
uint16_t debug_shuzu[20];
|
void HAL_SPI_ReceiveData(SPI_HandleTypeDef *pSpi, uint16_t *pBuf, size_t size, uint32_t timeout)
|
{
|
pSpi->rxXferCount = 0;
|
pSpi->rxXferSize =size;
|
pSpi->pRxBuffPtr = pBuf;
|
|
if(pSpi->initObj.role == SPI_RoleMaster)
|
{
|
pSpi->txXferCount = 0;
|
pSpi->txXferSize =size;
|
|
while (!(pSpi->txXferCount == pSpi->txXferSize && pSpi->rxXferCount == pSpi->rxXferSize))
|
{
|
if (pSpi->txXferCount < pSpi->txXferSize)
|
{
|
if (!SPI_IsTxFifoFull(pSpi->pSpix)) {
|
SPI_SendData(pSpi->pSpix, '\0');
|
pSpi->txXferCount++;
|
}
|
}
|
if (pSpi->rxXferCount < pSpi->rxXferSize)
|
{
|
if (!SPI_IsRxFifoEmpty(pSpi->pSpix)) {
|
pSpi->pRxBuffPtr[pSpi->rxXferCount++] = SPI_ReceiveData(pSpi->pSpix);
|
}
|
}
|
}
|
}
|
else if (pSpi->initObj.role == SPI_RoleSlave)
|
{
|
while (pSpi->rxXferCount < pSpi->rxXferSize)
|
{
|
if (!SPI_IsRxFifoEmpty(pSpi->pSpix))
|
{
|
pSpi->pRxBuffPtr[pSpi->rxXferCount++] = SPI_ReceiveData(pSpi->pSpix);
|
// debug_shuzu[pSpi->rxXferCount++]= SPI_ReceiveData(pSpi->pSpix);
|
|
}
|
}
|
}
|
}
|
|
void HAL_SPI_SendReceiveData (SPI_HandleTypeDef *pSpi, uint16_t* pSendBuf, size_t sendBufSize, uint16_t* pRecvBuf, size_t recvBufSize)
|
{
|
pSpi->rxXferCount = 0;
|
pSpi->rxXferSize =recvBufSize;
|
pSpi->pRxBuffPtr = pRecvBuf;
|
pSpi->txXferCount = 0;
|
pSpi->txXferSize =sendBufSize;
|
pSpi->pTxBuffPtr = pSendBuf;
|
|
while (!(pSpi->txXferCount == pSpi->txXferSize && pSpi->rxXferCount == pSpi->rxXferSize))
|
{
|
if (pSpi->txXferCount < pSpi->txXferSize)
|
{
|
pSpi->txXferCount += HAL_SPI_SendMultiDataAsync(pSpi->pSpix, (uint16_t*)(pSpi->pTxBuffPtr + pSpi->txXferCount), pSpi->txXferSize - pSpi->txXferCount);
|
}
|
if (pSpi->rxXferCount < pSpi->rxXferSize)
|
{
|
pSpi->rxXferCount += HAL_SPI_RecvMultiDataAsync(pSpi->pSpix, (uint16_t*)(pSpi->pRxBuffPtr + pSpi->rxXferCount), pSpi->rxXferSize - pSpi->rxXferCount);
|
}
|
}
|
}
|
|
|
void HAL_SPI_SendData_INT(SPI_HandleTypeDef *pSpi, uint16_t *pBuf, size_t size, SPI_CallbackFunc callback)
|
{
|
pSpi->xferStat = SPI_STAT_TX;
|
/* Enable Interrupt of target SPI */
|
// pSpi->interruptObj.Mode = SPI_IRQ_ALL;
|
pSpi->txXferSize = size;
|
pSpi->txXferCount =0;
|
pSpi->pTxBuffPtr = pBuf;
|
pSpi->txIntCallback = callback;
|
// HAL_SPI_Init_INT(pSpi);
|
SPI_EnableIrq(pSpi->pSpix, SPI_IRQ_TX_HALF_EMPTY);
|
NVIC_EnableIRQ(pSpi->IRQn);
|
}
|
|
void HAL_SPI_ReceiveData_INT(SPI_HandleTypeDef *pSpi, uint16_t* pBuf, size_t size,SPI_CallbackFunc callback)
|
{
|
pSpi->xferStat = SPI_STAT_RX;
|
|
pSpi->rxXferSize = size;
|
pSpi->rxXferCount =0;
|
pSpi->pRxBuffPtr = pBuf;
|
pSpi->rxIntCallback = callback;
|
SPI_EnableIrq(pSpi->pSpix, SPI_IRQ_RX_HALF_FULL | SPI_IRQ_RX_TIMEOUT);
|
NVIC_EnableIRQ(pSpi->IRQn);
|
}
|
|
void HAL_SPI_SendReceiveData_INT(SPI_HandleTypeDef *pSpi, uint16_t* pSendBuf, size_t sendBufSize,SPI_CallbackFunc sendCallback, uint16_t* pRecvBuf, size_t recvBufSize,SPI_CallbackFunc recvCallback)
|
{
|
pSpi->xferStat = SPI_STAT_RXTX;
|
|
pSpi->txXferSize = sendBufSize;
|
pSpi->txXferCount =0;
|
pSpi->pTxBuffPtr = pSendBuf;
|
pSpi->txIntCallback = sendCallback;
|
|
pSpi->rxXferSize = recvBufSize;
|
pSpi->rxXferCount =0;
|
pSpi->pRxBuffPtr = pRecvBuf;
|
pSpi->rxIntCallback = recvCallback;
|
SPI_EnableIrq(pSpi->pSpix, SPI_IRQ_ALL);
|
NVIC_EnableIRQ(pSpi->IRQn);
|
}
|
|
|
uint32_t HAL_SPI_SendData_DMA(SPI_HandleTypeDef *pSpi, uint16_t *pBuf, size_t size,SPI_CallbackFunc callback)
|
{
|
DMAC_Init(DMA);
|
NVIC_EnableIRQ(DMA_IRQn);
|
SPI_EnableDmaTx(pSpi->pSpix);
|
|
pSpi->xferStat = SPI_STAT_TX;
|
pSpi->txXferCount =0;
|
pSpi->txXferSize = size;
|
pSpi->pTxBuffPtr =pBuf;
|
uint32_t dmaChNum = 0xFF;
|
/* Get free DMA channel */
|
dmaChNum = DMAC_AcquireChannel(DMA);
|
/* Enable DMA transfer interrupt */
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_TFR);
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_DSTTFR);
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_ERR);
|
|
dma_mem2spi_config.PeripheralDst = pSpi->dmaDst;
|
DMAC_Channel_Array[dmaChNum].ConfigTmp = dma_mem2spi_config;
|
DMAC_Channel_Array[dmaChNum].CallbackSpi = callback;
|
// DMAC_Channel_Array[dmaChNum].StopFlag = false;
|
|
DMAC_Channel_Array[dmaChNum].pBuffPtr = (uint32_t *)pSpi->pTxBuffPtr;
|
DMAC_Channel_Array[dmaChNum].XferSize = pSpi->txXferSize;
|
DMAC_Channel_Array[dmaChNum].PeriMode = DMAC_Peri_SPI;
|
DMAC_SetChannelConfig(DMA, dmaChNum, &DMAC_Channel_Array[dmaChNum].ConfigTmp);
|
|
/* Condition check */
|
uint32_t DataWidthInByteSrc = DMAC_Channel_Array[dmaChNum].ConfigTmp.DataWidthSrc;
|
// uint32_t DataWidthInByteSrc = 1 << DMAC_Channel_Array[dmaChNum].ConfigTmp.DataWidthSrc;
|
uint32_t IsNotDivisible = pSpi->txXferSize % DataWidthInByteSrc;
|
uint32_t BlockSize = pSpi->txXferSize / DataWidthInByteSrc; //BlockSize = DataLen / DataWidthInByteSrc
|
|
/* Start DMA Tx channel */
|
DMAC_StartChannel(DMA, dmaChNum, pSpi->pTxBuffPtr, (void*)&(pSpi->pSpix->DR), BlockSize);
|
return dmaChNum;
|
}
|
|
uint32_t HAL_SPI_ReceiveData_DMA(SPI_HandleTypeDef *pSpi, uint16_t *pBuf, size_t size, SPI_CallbackFunc callback)
|
{
|
DMAC_Init(DMA);
|
NVIC_EnableIRQ(DMA_IRQn);
|
|
pSpi->xferStat = SPI_STAT_RX;
|
pSpi->rxXferCount =0;
|
pSpi->rxXferSize = size;
|
pSpi->pRxBuffPtr =pBuf;
|
// Initialize the DMA controller
|
uint32_t dmaChNum = 0xff;
|
/* Get free DMA channel */
|
dmaChNum = DMAC_AcquireChannel(DMA);
|
/* Enable DMA transfer interrupt */
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_TFR);
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_SRCTFR);
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_ERR);
|
|
dma_spi2mem_config.PeripheralSrc = pSpi->dmaSrc;
|
DMAC_Channel_Array[dmaChNum].ConfigTmp = dma_spi2mem_config;
|
DMAC_Channel_Array[dmaChNum].CallbackSpi = callback;
|
// DMAC_Channel_Array[dmaChNum].StopFlag = false;
|
|
DMAC_Channel_Array[dmaChNum].pBuffPtr = (uint32_t *)pSpi->pRxBuffPtr;
|
DMAC_Channel_Array[dmaChNum].XferSize = pSpi->rxXferSize;
|
DMAC_Channel_Array[dmaChNum].PeriMode = DMAC_Peri_SPI;
|
DMAC_SetChannelConfig(DMA, dmaChNum, &DMAC_Channel_Array[dmaChNum].ConfigTmp);
|
|
/* Condition check */
|
uint32_t RxDataWidthInByteSrc = DMAC_Channel_Array[dmaChNum].ConfigTmp.DataWidthSrc;
|
uint32_t RxIsNotDivisible = pSpi->rxXferSize % RxDataWidthInByteSrc;
|
uint32_t RxBlockSize = pSpi->rxXferSize / RxDataWidthInByteSrc; //BlockSize = DataLen / DataWidthInByteSrc
|
|
/*We should clear rx fifo before rx start*/
|
while (!SPI_IsRxFifoEmpty(pSpi->pSpix)) {
|
(void)(pSpi->pSpix->DR);
|
}
|
SPI_EnableDmaRx(pSpi->pSpix);
|
/* Start DMA Rx channel */
|
DMAC_StartChannel(DMA, dmaChNum, (void*)&(pSpi->pSpix->DR), pSpi->pRxBuffPtr, RxBlockSize);
|
|
return dmaChNum;
|
}
|
|
static uint32_t HAL_SPI_SendData_DMA_ForSR(SPI_HandleTypeDef *pSpi, uint16_t *pBuf, size_t size,SPI_CallbackFunc callback)
|
{
|
SPI_EnableDmaTx(pSpi->pSpix);
|
|
pSpi->xferStat = SPI_STAT_RXTX;
|
pSpi->txXferCount =0;
|
pSpi->txXferSize = size;
|
pSpi->pTxBuffPtr =pBuf;
|
uint32_t dmaChNum = 0xFF;
|
/* Get free DMA channel */
|
dmaChNum = DMAC_AcquireChannel(DMA);
|
/* Enable DMA transfer interrupt */
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_TFR);
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_DSTTFR);
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_ERR);
|
|
dma_mem2spi_config.PeripheralDst = pSpi->dmaDst;
|
DMAC_Channel_Array[dmaChNum].ConfigTmp = dma_mem2spi_config;
|
DMAC_Channel_Array[dmaChNum].CallbackSpi = callback;
|
// DMAC_Channel_Array[dmaChNum].StopFlag = false;
|
|
DMAC_Channel_Array[dmaChNum].pBuffPtr = (uint32_t *)pSpi->pTxBuffPtr;
|
DMAC_Channel_Array[dmaChNum].XferSize = pSpi->txXferSize;
|
DMAC_Channel_Array[dmaChNum].PeriMode = DMAC_Peri_SPI;
|
DMAC_SetChannelConfig(DMA, dmaChNum, &DMAC_Channel_Array[dmaChNum].ConfigTmp);
|
|
return dmaChNum;
|
}
|
|
|
static uint32_t HAL_SPI_ReceiveData_DMA_ForSR(SPI_HandleTypeDef *pSpi, uint16_t *pBuf, size_t size, SPI_CallbackFunc callback)
|
{
|
pSpi->xferStat = SPI_STAT_RXTX;
|
pSpi->rxXferCount =0;
|
pSpi->rxXferSize = size;
|
pSpi->pRxBuffPtr =pBuf;
|
// Initialize the DMA controller
|
uint32_t dmaChNum = 0xff;
|
/* Get free DMA channel */
|
dmaChNum = DMAC_AcquireChannel(DMA);
|
/* Enable DMA transfer interrupt */
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_TFR);
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_SRCTFR);
|
DMAC_ClrIntFlagMsk(DMA, dmaChNum, DMAC_FLAG_INDEX_ERR);
|
|
|
dma_spi2mem_config.PeripheralSrc = pSpi->dmaSrc;
|
DMAC_Channel_Array[dmaChNum].ConfigTmp = dma_spi2mem_config;
|
DMAC_Channel_Array[dmaChNum].CallbackSpi = callback;
|
// DMAC_Channel_Array[dmaChNum].StopFlag = false;
|
|
DMAC_Channel_Array[dmaChNum].pBuffPtr = (uint32_t *)pSpi->pRxBuffPtr;
|
DMAC_Channel_Array[dmaChNum].XferSize = pSpi->rxXferSize;
|
DMAC_Channel_Array[dmaChNum].PeriMode = DMAC_Peri_SPI;
|
DMAC_SetChannelConfig(DMA, dmaChNum, &DMAC_Channel_Array[dmaChNum].ConfigTmp);
|
|
while (!SPI_IsRxFifoEmpty(pSpi->pSpix)) {
|
(void)(pSpi->pSpix->DR);
|
}
|
SPI_EnableDmaRx(pSpi->pSpix);
|
|
return dmaChNum;
|
}
|
|
void HAL_SPI_SendReceiveData_DMA(SPI_HandleTypeDef *pSpi, uint16_t* pSendBuf, size_t sendBufSize,SPI_CallbackFunc sendCallback, uint16_t* pRecvBuf, size_t recvBufSize,SPI_CallbackFunc recvCallback)
|
{
|
uint32_t rxChNum = 0xFF;
|
uint32_t txChNum = 0xFF;
|
/* We should clear rx fifo before rx start */
|
|
DMAC_Init(DMA);
|
NVIC_EnableIRQ(DMA_IRQn);
|
txChNum = HAL_SPI_SendData_DMA_ForSR(pSpi,pSendBuf,sendBufSize,sendCallback);
|
|
rxChNum = HAL_SPI_ReceiveData_DMA_ForSR(pSpi,pRecvBuf,recvBufSize,recvCallback);
|
/* Condition check */
|
uint32_t RxDataWidthInByteSrc = DMAC_Channel_Array[rxChNum].ConfigTmp.DataWidthSrc;
|
uint32_t RxIsNotDivisible = pSpi->rxXferSize % RxDataWidthInByteSrc;
|
uint32_t RxBlockSize = pSpi->rxXferSize / RxDataWidthInByteSrc; //BlockSize = DataLen / DataWidthInByteSrc
|
|
|
/* Condition check */
|
uint32_t TxDataWidthInByteSrc = DMAC_Channel_Array[txChNum].ConfigTmp.DataWidthSrc;
|
// uint32_t DataWidthInByteSrc = 1 << DMAC_Channel_Array[dmaChNum].ConfigTmp.DataWidthSrc;
|
uint32_t TxIsNotDivisible = pSpi->txXferSize % TxDataWidthInByteSrc;
|
uint32_t TxBlockSize = pSpi->txXferSize / TxDataWidthInByteSrc; //BlockSize = DataLen / DataWidthInByteSrc
|
|
/* Start DMA Rx channel */
|
DMAC_StartChannel(DMA, rxChNum, (void*)&(pSpi->pSpix->DR), pSpi->pRxBuffPtr, RxBlockSize);
|
/* Start DMA Tx channel */
|
DMAC_StartChannel(DMA, txChNum, pSpi->pTxBuffPtr, (void*)&(pSpi->pSpix->DR), TxBlockSize);
|
}
|
|
static void SPI_HandleReceivedData(SPI_HandleTypeDef *pSpi)
|
{
|
while (!SPI_IsRxFifoEmpty(pSpi->pSpix))
|
{
|
pSpi->pRxBuffPtr[pSpi->rxXferCount++] = SPI_ReceiveData(pSpi->pSpix);
|
|
if (pSpi->rxXferCount >= pSpi->rxXferSize) // Rx buffer full // if (pSpi->rxXferCount >= pSpi->rxXferSize) //Rx buffer full
|
{
|
if (pSpi->rxIntCallback != NULL)
|
{
|
pSpi->rxIntCallback(SPI_CB_FLAG_INT, pSpi->pRxBuffPtr, pSpi->rxXferCount);
|
}
|
SPI_DisableIrq(pSpi->pSpix, SPI_IRQ_RX_HALF_FULL|SPI_IRQ_RX_TIMEOUT);
|
break;
|
}
|
}
|
}
|
|
static void SPI_HandleTransmittingData(SPI_HandleTypeDef *pSpi)
|
{
|
while (!SPI_IsTxFifoFull(pSpi->pSpix))
|
{
|
if (pSpi->txXferCount < pSpi->txXferSize)
|
{
|
SPI_SendData(pSpi->pSpix, pSpi->pTxBuffPtr[pSpi->txXferCount++]);
|
}
|
if (pSpi->txXferCount >= pSpi->txXferSize)
|
{
|
while(SPI_IsBusy(pSpi->pSpix)){}
|
SPI_DisableIrq(pSpi->pSpix, SPI_IRQ_TX_HALF_EMPTY);
|
if (pSpi->txIntCallback != NULL)
|
{
|
pSpi->txIntCallback(SPI_CB_FLAG_INT, pSpi->pTxBuffPtr, pSpi->txXferCount);
|
}
|
break;
|
}
|
}
|
if (pSpi->xferStat == SPI_STAT_TX) {
|
while (!SPI_IsRxFifoEmpty(pSpi->pSpix)) {
|
(void)(pSpi->pSpix->DR);
|
}
|
}
|
}
|
void SPI_HandleProc(SPI_HandleTypeDef *pSpi)
|
{
|
if (SPI_IsIrqActive(pSpi->pSpix, SPI_IRQ_RX_OVERRUN))
|
{
|
SPI_ClearIrq(pSpi->pSpix, SPI_IRQ_RX_OVERRUN); // Clear overrun INT flag manually
|
return;
|
}
|
|
if (SPI_IsIrqActive(pSpi->pSpix, SPI_IRQ_RX_HALF_FULL))
|
{
|
SPI_HandleReceivedData(pSpi);
|
}
|
else if (SPI_IsIrqActive(pSpi->pSpix, SPI_IRQ_RX_TIMEOUT))
|
{
|
SPI_HandleReceivedData(pSpi);
|
}
|
|
if (SPI_IsIrqActive(pSpi->pSpix, SPI_IRQ_TX_HALF_EMPTY))
|
{
|
SPI_HandleTransmittingData(pSpi);
|
}
|
}
|
|
void SPI0_IRQHandler(void)
|
{
|
SPI_HandleProc(&spiHandleArray[0]);
|
}
|
|
void SPI1_IRQHandler(void)
|
{
|
SPI_HandleProc(&spiHandleArray[1]);
|
}
|