/*
* SPI硬件初始化,內存地址初始化
*/
static void Init(void)
{
uint8_t i;
/*失能SPI1*/
HAL_SPI_DeInit(&hspi1);
/*清空FpgaRevData內存*/
for(i=0;i<REV_MAX_NUM;i++)
{
memset(FpgaRevData[i],0,FPGA_DATA_PAKET_LENGTH);
}
/*初始化內存指針*/
gWritePtr=0;
gReadPtr=0;
/*使能SPI1*/
HAL_SPI_Init(&hspi1);
/*SPI DMA初始化,並開啓一次數據接收*/
HAL_SPI_Receive_DMA_INIT(&hspi1,FpgaRevData[gWritePtr],FPGA_DATA_PAKET_LENGTH);
}
/*
* SPI DMA初始化,並開啓一次數據接收,
* 關鍵是返回函數的初始化,DMA 源地址和目的地址的初始化,各標誌位的清空與開啓
* 該程序修改與HAL庫的HAL_SPI_Receive_DMA函數
*/
void HAL_SPI_Receive_DMA_INIT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
{
hspi->State = HAL_SPI_STATE_BUSY_RX;
hspi->RxXferSize = Size;
/*Init field not used in handle to zero */
hspi->RxISR = NULL;
/* Set the SPI Rx DMA transfer complete callback */
hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
/* Enable the Rx DMA Stream */
HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)(uint8_t *)pData, Size);
/* Check if the SPI is already enabled */
if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
{
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(hspi);
}
/* Enable the SPI Error Interrupt Bit */
SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
/* Enable Rx DMA Request */
SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
}
/*
* FPGA SPI1數據接收函數,一次接收6個字節數據包
* 該程序修改與HAL庫的HAL_DMA_Start_IT函數和HAL_SPI_Receive_DMA函數
*/
__INLINE void FPGA_ReadBuffer(SPI_HandleTypeDef *hspi, uint8_t *DstAddress)
{
// HAL_StatusTypeDef status = HAL_OK;
/* calculate DMA base and stream number */
// DMA_Base_Registers *regs = (DMA_Base_Registers *)(hspi->hdmarx)->StreamBaseAddress;
/* Process locked */
// __HAL_LOCK(hspi->hdmarx);
//
// if(HAL_DMA_STATE_READY == hspi->hdmarx->State)
// {
/* Change DMA peripheral state */
// hspi->hdmarx->State = HAL_DMA_STATE_BUSY;
/* Clear DBM bit */
hspi->hdmarx->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
/* Configure DMA Stream destination address */
hspi->hdmarx->Instance->M0AR = (uint32_t)(uint8_t *)DstAddress;
/* Clear all interrupt flags at correct offset within the register */
// regs->IFCR = 0x3FU << hspi->hdmarx->StreamIndex;
/* Enable Common interrupts*/
hspi->hdmarx->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
hspi->hdmarx->Instance->FCR |= DMA_IT_FE;
/* Enable the Peripheral */
__HAL_DMA_ENABLE(hspi->hdmarx);
// }
// else
// {
// /* Process unlocked */
// __HAL_UNLOCK(hspi->hdmarx);
//
// /* Return error status */
// status = HAL_BUSY;
// }
/* Check if the SPI is already enabled */
// if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
// {
// /* Enable SPI peripheral */
// __HAL_SPI_ENABLE(hspi);
// }
/* Enable the SPI Error Interrupt Bit */
SET_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE|SPI_CR2_RXDMAEN);
// /* Enable Rx DMA Request */
// SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
// return HAL_OK;
}
/*
*SPI 返回函數,打開SPI DMA開關,一次接收6個字節數據包
*/
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
if(hspi==&hspi1)
{
//HAL_SPI_DMAStop(hspi);//先關掉DMA
/* Disable the SPI DMA Tx & Rx requests */
CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);//關掉DMA其實就是執行了這個操作
if((gWritePtr + 1 == gReadPtr) || (gWritePtr == REV_MAX_NUM && gReadPtr == 0))//我的數據存儲在一個二維數組中,這裏判斷滿了
return ;
gWritePtr++;
if (gWritePtr==REV_MAX_NUM) gWritePtr=0;
FPGA_ReadBuffer(hspi,FpgaRevData[gWritePtr]);
}
}
當SPI DMA硬件初始化(SPI DMA mode爲DMA_NORMAL)後,就可以開始一次初始
化HAL_SPI_Receive_DMA_INIT,之後,當有數據到來,SPI接收完成返回函數會被調用,在返回函數中,首先關掉DMA,接收到數據後,提供下一次接收數據的地址,重新打開DMA。