TI中文支持网
TI专业的中文技术问题搜集分享网站

DMA 的 channel chain 问题

我的理解是一个channel的DMA request 可以触发另一个channel的DMA操作

在channel configuration 的channel control register 寄存器的CHAIN中设置,但是有点看不明白

CHAIN 为BIT 21-16 共6位,0h channel0 selected ,4h channel15 select, 这样的话 其它的channel 怎么设置的呢

我是用一个RTI的DMA chain一个SCI的发送DMA ,RTI的DMA可以正常操作,但是SCI的DMA没有被触发。

是否有实例可以参考

Jay:

Hi XiaoFeng,

CHAIN 寄存器每一个DMA Control Package都会有一个。

所以, 你需要在RTI的DMA Control Package中配置CHAIN,使其来触发SCI的DMA Channel。

Regards,

Jay

Ken Wang:

回复 Jay:

Hi Xiaofeng,

     非常感谢你对我们的TRM提出的问题,经过确认这确实是文档的一个小错误,我们会在下一版的手册中更新。对于CHAIN那几位的设置,正确的应该是数据 X 对应Channel(X-1),即 1对应channel0, 2对应channel1……

     如果你需要使用channel chain功能,首先你需要确认你的两个单独的DMA都能正常工作,即RTI触发DMA和 SCI的DMA。 当确认好这两个DMA都能单独正常工作以后,在RTI触发的DMA配置中将CHAIN这个位设置成SCI 的DMA所采用的channel。举个例子,如果你设置SCI的DMA选用channel3,则设置RTI对应的DMA的CHAIN 等于2.只有这样才能保证两个DMA都能正常工作在channel chain 模式。

     另外一个需要注意的是,RTI对应的DMA是硬件触发,SCI的DMA需要设置成软件触发。

XiaoFeng Jiang:

回复 Ken Wang:

使用的芯片是3137 还是不行 设置如下 应该没有错了啊 XX_RDATA 数据会定时更新,说明RTI的DMA在运行,串口收到一个字节的数据,说明SCI的DMA_SW触发了一个DMA发送,SCI的DMA应该也没有问题,SCI改成DMA_HW也不行,感觉就是CHAIN没有起作用,我明明已经设了啊,查看channel0的寄存器也是对的啊,麻烦帮我看看

还有一个就是SCI的DMA操作,上次3137的DMA发送的帖子中按照你们的示例,还是不能发送,我改成ACCESS_32_BIT就可以了,是不是你们用的是R48系列是小端的而3137是大端的原因

sciInit();

rtiInit();

dmaEnable();

dmaReqAssign(0,12 );dmaReqAssign(1,29 );

g_dmaCTRLPKT.SADD = (uint32)TT_TDATA; /* source address */g_dmaCTRLPKT.DADD = (uint32)XX_RDATA; /* destination address */g_dmaCTRLPKT.CHCTRL = 2; /* channel control */g_dmaCTRLPKT.FRCNT = 8; /* frame count */g_dmaCTRLPKT.ELCNT = 1;/* element count */g_dmaCTRLPKT.ELDOFFSET = 0; /* element destination offset */g_dmaCTRLPKT.ELSOFFSET = 0; /* element destination offset */g_dmaCTRLPKT.FRDOFFSET = 0; /* frame destination offset */g_dmaCTRLPKT.FRSOFFSET = 0; /* frame destination offset */g_dmaCTRLPKT.PORTASGN = 4; /* port b */g_dmaCTRLPKT.RDSIZE = ACCESS_8_BIT; /* read size */g_dmaCTRLPKT.WRSIZE = ACCESS_8_BIT; /* write size */g_dmaCTRLPKT.TTYPE = FRAME_TRANSFER ; /* transfer type */g_dmaCTRLPKT.ADDMODERD = ADDR_INC1; /* address mode read */g_dmaCTRLPKT.ADDMODEWR = ADDR_FIXED; /* address mode write */g_dmaCTRLPKT.AUTOINIT = AUTOINIT_ON; /* autoinit */

dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT);

g_dmaCTRLPKT.SADD = (uint32)TDATA; /* source address */g_dmaCTRLPKT.DADD = (uint32)&(scilinREG->TD) /* destination address */g_dmaCTRLPKT.CHCTRL = 0; /* channel control */g_dmaCTRLPKT.FRCNT = 8; /* frame count */g_dmaCTRLPKT.ELCNT = 1; /* element count */g_dmaCTRLPKT.ELDOFFSET = 0; /* element destination offset */g_dmaCTRLPKT.ELSOFFSET = 0; /* element destination offset */g_dmaCTRLPKT.FRDOFFSET = 0; /* frame destination offset */g_dmaCTRLPKT.FRSOFFSET = 0; /* frame destination offset */g_dmaCTRLPKT.PORTASGN = 4; /* port b */g_dmaCTRLPKT.RDSIZE = ACCESS_32_BIT; /* read size */g_dmaCTRLPKT.WRSIZE = ACCESS_32_BIT; /* write size */g_dmaCTRLPKT.TTYPE = FRAME_TRANSFER ; /* transfer type */g_dmaCTRLPKT.ADDMODERD = ADDR_INC1; /* address mode read */g_dmaCTRLPKT.ADDMODEWR = ADDR_FIXED; /* address mode write */g_dmaCTRLPKT.AUTOINIT = AUTOINIT_OFF; /* autoinit */

dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT);

dmaSetChEnable(DMA_CH0, DMA_HW);dmaSetChEnable(DMA_CH1, DMA_SW);

scilinREG->SETINIT|=1U<<16U;

rtiStartCounter(rtiCOUNTER_BLOCK0);

Ken Wang:

回复 XiaoFeng Jiang:

Hi Xiaofeng,

    我看过了你的程序,但是有几个问题需要和你再确认一下:

1. 你确定你的RTI硬件触发DMA正常操作了么?因为我看到你的程序里面没有使能RTI 对应的DMA的操作啊。具体如下所示:

    rtiREG1-> SETINT = (0x01U << 8);

    你能先单独做个RTI触发DMA的例子吧,毕竟你的程序比较大,能不能先一部分一部分来。

2. 你SCI 触发DMA的操作,改成ACCESS_32_BIT,程序运行正常吗?接收的数据完全正确?因为SCI的发送buffer不是32位的,你这样设置的话,我感觉还是会有问题的。你能再确定一下吗?

3. 我今天有空会尝试做一个完整的例子,测试没问题的话,会发上来。

Ken

XiaoFeng Jiang:

回复 Ken Wang:

1、在rtiInit中已经设置了 我的RTI的DMA操作是把TT_TDATA的8个字节字符依次搬移到XX_RDATA的单字节中,

我在调试时,暂停时可以看到XX_RDATA的数据在依次变换,所以我确定RTI的DMA没有问题。

2、确实是改为ACCESS_32_BIT就好了,发送、接收都是如此,当然需要把发送内容和接收缓存都设置成32位的才可以。

在scilinREG的定义中scilinREG->TD是32位的

比较奇怪的是我直接对进行scilinREG->TD=0x05;这种赋值操作是没有问题的;是不是编译器自己做了强制转换啊。

赞(0)
未经允许不得转载:TI中文支持网 » DMA 的 channel chain 问题
分享到: 更多 (0)