LPC1768+SSP0+GPDMA some problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1768+SSP0+GPDMA some problem

222 Views
Lee_Lee
Contributor I

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);
 
}
Labels (1)
0 Kudos
Reply
1 Reply

131 Views
Harry_Zhang
NXP Employee
NXP Employee

Hi @Lee_Lee 

I think DMA is' reading empty SSP FIFO ', but due to an incorrect access width, data has not been written correctly into memory.

What are you currently configuring

(0x00<<18)//源数据宽度
(0x00<<21)//目的数据宽度
But in LPC:

The DR register of SSP is a 16 bit register

Harry_Zhang_0-1765963833177.png

 

Even if you are using 8-bit SPI mode, DMA access to SSP0->DR must still be 16 bit access.

DMA did not actually write data correctly into memory
The result is that BUF remains unchanged.

So i think you can try to change the source and des width to 16.

BR

Harry

0 Kudos
Reply