你好:
我想使用lpuart + edma + DMAMUX实现串口接收,
1、用dma将数据接收到一个buff中
2、怎么做可以使dma循环接收到buff中,即dma完成全接收后,如果有后续的数据,数据又从buff开始的地址开始存储;
3、如何使dma的半完成中断连续工作,我开启半完成中断,这个中断只工作一次,后续的接收只有完成中断。
Hi,
抱歉这么长时间才回复你的帖子。
RT的eDMA模块和之前很多系列产品的模块都是相同的,所以之前一些产品,例如Kinetis,MPC56xx关于eDMA的应用笔记同样适用于RT产品。我这里列举了一些关于eDMA的应用笔记供你参考:
回到你提出的eDMA如何支持循环buffer,可以参考下面的例程,希望对你有所启发:
eDMA提供modulo特性,使用 circular buffer 接受/发送数据。
For example if you want to transfer each byte as it is received by LINFlex UART into a circular buffer, that will have 16 8-bit entries you will set the TCD as below (assume using LINFlex0 and TCD[0]): uint8_t buffer[16]; // should be aligned to even address EDMA_0.TCD[0].SADDR = ((vuint32_t) &LINFLEX_0.BDRM.R + 3); EDMA_0.TCD[0].SMOD = 0; EDMA_0.TCD[0].SSIZE = 0; // Source data size = 8bit EDMA_0.TCD[0].SLAST = 0; EDMA_0.TCD[0].SOFF = 0; // Source address signed offset = 0 EDMA_0.TCD[0].DMOD = 4; // least significant 4 address bits are changed, providing circular queue of 16 bytes EDMA_0.TCD[0].DSIZE = 0; // Destination data transfer size = 8 bit EDMA_0.TCD[0].NBYTES = 1; // Transfer 1 byte per minor loop EDMA_0.TCD[0].DADDR = ((vuint32_t) &buffer[0]) ; EDMA_0.TCD[0].CITER = 1; EDMA_0.TCD[0].DOFF = 1; // After transfer, add 1 to dest addr EDMA_0.TCD[0].DLAST_SGA = 0; EDMA_0.TCD[0].BITER = 1; EDMA_0.TCD[0].BWC = 0; EDMA_0.TCD[0].MAJORLINKCH = 0; EDMA_0.TCD[0].DONE = 0; EDMA_0.TCD[0].ACTIVE = 0; EDMA_0.TCD[0].MAJORE_LINK = 0; EDMA_0.TCD[0].E_SG = 0; EDMA_0.TCD[0].D_REQ = 0; EDMA_0.TCD[0].INT_HALF = 0; EDMA_0.TCD[0].INT_MAJ = 0; EDMA_0.TCD[0].START = 0; EDMA_0.DMAERQL.R = 0x00000001; // eDMA request signal for channel 0 is enabled DMAMUX_0.CHCONFIG[0].R |= 0x97; // route LINFlex0 RX DMA request to eDMA channel 0
关于eDMA半完成触发中断,之后无法再次触发。
需要查看中断处理速度是否匹配中断发生的速度,另外中断标志位有没有及时清除。
也可以查看eDMA Error Status (ES) 寄存器,看看eDMA配置是否存在问题。
祝顺利。
Mike