Why is it that after opening DMACR in SSP0 and transmitting some data to BUF, DMACR is reset to zero, SSP0DR keeps changing, but BUF data remains unchanged.I also tried to reopen DMACR during the interrupt, but there was still no change in the BUF data.
Below is the code configuration:
#define SPI_RX_LEN 5386
extern U8 SPIRXBUF[SPI_RX_LEN];
void DMAInit_SPI_RX(U8 *destAddr, U32 len)
{
U32 part1 = (len > 4095) ? 4095 : len;
U32 part2 = (len > 4095) ? (len - 4095) : 0;// 拆分传输(单通道最大4095字节)
LPC_SC->PCONP |= (1 << 29); // 使能GPDMA时钟
LPC_GPDMA->DMACConfig |= (1 << 0);//使能GPDMA
LPC_GPDMA->DMACIntTCClear |= 0x01; // 清除通道0传输完成标志
LPC_GPDMA->DMACIntErrClr |= 0x01; // 清除通道0错误标志
// 链表项1:传输part1字节
lli[0].srcAddr = (U32)&LPC_SSP0->DR; // 源:SPI0数据寄存器
lli[0].destAddr = (U32)destAddr; // 目的:缓冲区起始
lli[0].control = (part1 & 0x0FFF) // 传输大小(字节数)
| (0x00 << 12) // 源突发大小
| (0x00 << 15) // 目的发大小
| (0x00 << 18) //源数据宽度
| (0x00 << 21) //目的数据宽度
| (0x00 << 26) //源地址不变(外设寄存器)
| (0x01 << 27) //目的地址自增
| (1U << 31); // 使能中断
// 链表项2:传输part2字节(若需要)
if (part2 > 0)
{
lli[0].nextLLI = (U32)&lli[1]; // 指向链表项2
lli[1].srcAddr = (U32)&LPC_SSP0->DR;
lli[1].destAddr = (U32)(destAddr + part1); // 缓冲区偏移
lli[1].control = (part2 & 0x0FFF) // 传输大小(字节数)
| (0x00 << 12) // 源突发大小
| (0x00 << 15) // 目的发大小
| (0x00 << 18) //源数据宽度
| (0x00 << 21) //目的数据宽度
| (0x00 << 26) //源地址不变(外设寄存器)
| (0x01 << 27) //目的地址自增
| (1U << 31); // 使能中断
lli[1].nextLLI = 0; // 结束链表
}
else
{
lli[0].nextLLI = 0;
}
// 配置DMA通道0
LPC_GPDMACH0->DMACCConfig = 0;
LPC_GPDMACH0->DMACCLLI = (U32)&lli[0]; // 链表起始地址
LPC_GPDMACH0->DMACCSrcAddr = lli[0].srcAddr; // 源地址(SPI0 DR)
LPC_GPDMACH0->DMACCDestAddr = lli[0].destAddr; // 目的地址
LPC_GPDMACH0->DMACCControl = lli[0].control; // 控制字
LPC_GPDMACH0->DMACCConfig = (0x01 << 15) //中断错误
| (0x01 << 14) //终端计数中断
| (0x02 << 11) // 传输类型:外设到内存
| (0x00 << 6) //目的外设:存储器
| (0x01 << 1) // 源外设:SSP0 RX(参考手册)
| (0x01 << 0); // 通道使能
GPDMAEnabe();
}
void DMA_IRQHandler(void)
{
if(LPC_GPDMA->DMACIntTCStat & 0x01) // 通道0传输完成
{
LPC_GPDMA->DMACIntTCClear = 0x01; // 清除标志
//SSPSlave_Init();
// RUN_LAMP_GLITTER;
// LPC_SSP0->DMACR |= (1 << 0);
// LPC_GPDMACH0->DMACCConfig |= (0x01 << 0);
LPC_GPDMA->DMACConfig |= (1 << 0);//使能GPDMA
time++;
}
if(LPC_GPDMA->DMACIntErrStat & 0x01) // 通道0错误
{
LPC_GPDMA->DMACIntErrClr = 0x01; // 清除标志
}
}
void SSPSlave_Init(void)
{
LPC_SC->PCONP |= (1 << 21); /* 打开SSP电源 */
/*****************************************************************
* 初始化SSP的通讯方式,设置数据长度为8bit,帧格式为SPI,SCK 为低有效,
* 数据在SCK 的第二个时钟沿采样,设置位速率。
******************************************************************/
LPC_SSP0->CR0 = (0x00 << | /* SCR 设置SPI位速率 */
(0x01 << 7) | /* CPHA 时钟输出相位 */
(0x00 << 6) | /* CPOL 时钟输出极性 */
(0x00 << 4) | /* FRF 帧格式 00=SPI,01=SSI, */
/* 10=Microwire,11=保留 */
(0x07 << 0); /* DSS 数据长度,0000-0010=保留 */
/* 0011=4位,0111=8位,1111=16位*/
LPC_SSP0->CPSR = 2; /* 时钟分频寄存器*/
LPC_SSP0->CR1 = (0x00 << 3) | /* SOD 从机输出禁能,0=允许 */
(0x01 << 2) | /* MS 主从选择,1=从机 */
(0x01 << 1) | /* SSE SSP使能,1=使能 */
(0x00 << 0); /* LBM 回写模式 */
sysTimeDlay(5);
LPC_SSP0->DMACR |= (1 << 0);
}