我这边使用S32K314的SPI Slave DMA功能发送数据遇到一个问题,SPI采用SPI0,TX DMA0 RX DMA1。
SPI需要传输1024个字节,发送数据第一帧数据正常,后续帧都会出现前4个字节都会被随机覆盖,其他1020个数据正常。
例如,
发送 AA 55 00 01 01 02 03 04 ...
通过逻辑分析仪抓包数据为
XX XX XX XX 01 02 03 04 ...
SPI和Tx DMA初始化配置:
LPSPI0_CLK_ENABLE();
IP_LPSPI_0->CFGR1 = LPSPI_CFGR1_MASTER(0) |
LPSPI_CFGR1_PINCFG(0) |
LPSPI_CFGR1_OUTCFG(0) |
LPSPI_CFGR1_PCSCFG(0) |
LPSPI_CFGR1_MATCFG(0) |
LPSPI_CFGR1_PCSPOL(0) |
LPSPI_CFGR1_NOSTALL(0);
IP_LPSPI_0->FCR = LPSPI_FCR_RXWATER(0) | LPSPI_FCR_TXWATER(0);
IP_LPSPI_0->TCR = LPSPI_TCR_CPOL(1) | LPSPI_TCR_CPHA(1) |
LPSPI_TCR_PCS(1) |
LPSPI_TCR_LSBF(0) | LPSPI_TCR_BYSW(1) |
LPSPI_TCR_CONT(0) | LPSPI_TCR_CONTC(0) |
LPSPI_TCR_TXMSK(0) | LPSPI_TCR_RXMSK(0)
LPSPI_TCR_FRAMESZ(31 - 1) |
LPSPI_TCR_WIDTH(0);
IP_LPSPI_0->CR = LPSPI_CR_MEN(1);
DMA_CLK_ENABLE();
DMAMUX_0_CLK_ENABLE();
DMA_TCD0_CLK_ENABLE();
IP_DMAMUX_0->CFCFG[3] = DMAMUX_CHCFG_SOURCE(43);
NVIC_EnableIRQ((IRQn_Type)(DMATCD0_IRQn));
SPI和Tx DMA发送前配置:
IP_LPSPI_0->CR |= LPSPI_CR_RRF_MASK | LPSPI_CR_RTF_MASK;
IP_LPSPI_0->DER = ~(LPSPI_DER_TDDE_MASK | LPSPI_DER_RDDE_MASK);
IP_TCD->TCD0_SADDR = (uint32_t)SrcAddr;
IP_TCD->TCD0_DADDR = (uint32_t) IP_LPSPI_0->TDR;
IP_TCD->TCD0_ATTR = DMA_TCD_TCD0_ATTR_SMOD(0) |
DMA_TCD_TCD0_ATTR_SSIZE(2) |
DMA_TCD_TCD0_ATTR_DMOD(0) |
DMA_TCD_TCD0_ATTR_DSIZE(2);
IP_TCD->TCD0_SOFF = 4;
IP_TCD->TCD0_DOFF = 0;
IP_TCD->NBYTES0.TCD0_NBYTES_MLOFFNO = 4;
IP_TCD->BITER0.TCD0_BITER_ELINKNO = DMA_TCD_TCD0_BITER_ELINKNO_BITER(256);
IP_TCD->CITER0.TCD0_CITER_ELINKNO = DMA_TCD_TCD0_CITER_ELINKNO_CITER(256);
IP_TCD->TCD0_SLAST_SDA = 0;
IP_TCD->TCD0_DLAST_SGA = 0;
IP_TCD->TCD0_CSR |= DMA_TCD_TCD0_CSR_INTMAJOR(1)
~DMA_TCD_TCD0_CSR_START_MASK;
IP_LPSPI_0->DER |= LPSPI_DER_TDDE_MASK | LPSPI_DER_RDDE_MASK;
IP_TCD->CH0_INT = DMA_TCD_CH0_INT_INT(0);
IP_TCD->CH0_CSR = DMA_TCD_CH0_CSR_ERQ(1);
IP_DMAMUX_0->CFCFG[3] |= DMAMUX_CHCFG_ENBL_MASK;
TX Dma中断函数:
void DMA0_IRQHandler(void)
{
IP_LPSPI_0->DER = ~LPSPI_DER_TDDE_MASK;
LP_LPSPI_0->CR |= LPSPI_CR_RTF_MASK;
IP_LPSPI_0->CH0_CSR |= DMA_TCD_CH0_CSR_DONE(1);
IP_LPSPI_0->CH0_INT |= DMA_TCD_CH0_INT_INT(1);
IP_DMAMUX_0->CFCFG[3] = ~DMAMUX_CHCFG_ENBL_MASK;
IP_TCD->CH0_CSR = DMA_TCD_CH0_CSR_ERQ(0);
Spi0_TxHandler();
}