我编写了一个在omap4460平台上运行的UART驱动程序,我在UART.My用户应用程序中启用了FIFO模式下的DMA,将100个字节的数据从用户空间传输到内核缓冲区。
一旦启用DMA通道,数据从DMA缓冲区复制到FIFO,然后传输到UART.Since的TSR我的FIFO大小是64字节,只有64字节被传输到TSR。
如何将剩余的字节从DMA缓冲区传输到FIFO?/是否发生溢出?
编辑:添加了下面的部分配置代码表示UART配置
/* Software reset */
iowrite32(0x2,uart_vbaddr + UART_SYSC);
while((ioread32(uart_vbaddr + UART_SYSS) & 0x1)== 0);
/* FIFOs and DMA Settings */
lcr = ioread32(uart_vbaddr + UART_LCR);
iowrite32(UART_MODE_B,uart_vbaddr + UART_LCR);
efr = ioread32(uart_vbaddr + UART_EFR);
iowrite32(0x10,uart_vbaddr + UART_EFR);/
iowrite32(UART_MODE_A,uart_vbaddr + UART_LCR);
mcr = ioread32(uart_vbaddr + UART_MCR);
iowrite32(0x40,uart_vbaddr + UART_MCR);
iowrite32(0x09,uart_vbaddr + UART_FCR);//FIFO not getting enabled here
iowrite32(UART_MODE_B,uart_vbaddr + UART_LCR);
iowrite32(0x2,uart_vbaddr + UART_TLR);//to set for 8 spaces
iowrite32(0x0,uart_vbaddr + UART_SCR);
iowrite32(efr,uart_vbaddr + UART_EFR);
iowrite32(UART_MODE_A,uart_vbaddr + UART_LCR);
iowrite32(mcr,uart_vbaddr + UART_MCR);
iowrite32(lcr,uart_vbaddr + UART_LCR);
/* Protocol Baudrate and interrupt settings */
dll = divisor & 0xFF;
dlh = divisor >> 8;
iowrite32(0x7, uart_vbaddr + UART_MDR1);
mdrdelay();
iowrite32(UART_MODE_B, uart_vbaddr + UART_LCR);
iowrite32(dll,uart_vbaddr);
iowrite32(dlh,uart_vbaddr + UART_DLH);
iowrite32(lcr_val , uart_vbaddr + UART_LCR);
iowrite32(0, uart_vbaddr + UART_MDR1);
mdrdelay();
iowrite32(0x09,uart_vbaddr + UART_FCR);//So renabling the FIFO againDMA在HW同步mode.with BS =0 ans FS =0.ie中配置为为每个DMA请求逐个元素传输。
下面的代码给出DMA配置
/* Set the Read Port & Write Port access in CSDP */
csdp_val &= 0x00000000;
iowrite32(csdp_val,dma_map + DMA_CSDP(dma_cha_line));
/* Set the Channel Source & Destination start address */
iowrite32(bus_addr,dma_map + DMA_CSSA(dma_cha_line));
iowrite32(UART4_BASE,dma_map + DMA_CSDA(dma_cha_line));
/* CCR configuration */
ccr_val=ioread32(dma_map+DMA_CCR(dma_cha_line))
ccr_val |= (0x1 << 24);//Source triggers on the DMA
/*Frame(5) and Block(18) Synchronisation */
ccr_val &= ~(0x1 << 5);//FS
ccr_val &= ~(0x1 << 18);//BS
ccr_val |= (0x17);//CCR[4:0]
ccr_val |= (0x1 << 19);//CCR [19:20]
ccr_val &= ~(0x1 << 20);//CCR [19:20]
ccr_val |= (0x1 << 12);//source - post incremented 12:13
ccr_val &= ~(0x1 << 13);
ccr_val &= ~(0x3 << 14);//destination- constant address mode 14:15
iowrite32(ccr_val,dma_map + DMA_CCR(dma_cha_line));
ccr_val = ioread32(dma_map + DMA_CCR(dma_cha_line));
Finally after this initialiasitation.channel is enabled.如果初始化中有任何错误,请建议我,因为我只得到了64个字节,而且我也无法在TRM提供的任何模式下触发DMA请求。
编辑:为元素同步修改的代码。1.在TRM中,这句话被观察到frequently.What设置?
DMA设置必须与系统LH DMA控制器设置相对应,以确保该逻辑的正确操作。
2.这种配置正确吗?:
ccr_val |= (0x1 << 24);//Source triggers on the DMA
To regenrate the DMA request again,shouldn't I configure the DMA as destination triggered instead of source
ccr_val |= (0x1 << 24);//Destination triggers on the DMA ?这两种方法我都试过了,不幸的是结果是一样的。
3.配置FIFO.ie FCR/TLR/MDR3 3寄存器的触发级别有3种方法。
在这段代码中,我已经设置了使用TLR的registers.This TLR设置,并使用中断模式进行了验证。
发布于 2014-06-14 22:33:30
DMA配置在..。阻塞同步。
这是一个根本性的错误。
块同步将用于诸如HDD这样的块设备,当数据在一次操作中通过SATA (或PATA)总线传输时,HDD具有扇区缓冲器来接收完整的块。
UART是一个字符设备,每个操作发送一个字符。FIFO的存在是为了确保能够接收数据(防止溢出),并确保数据可用于传输(尽量减少空闲线路时间)。串行链路的另一端具有未知的缓冲能力。如果缓冲有限,则应该使用流量控制(使用硬件RTS/CTS或软件XON/XOFF)。
块设备不使用流控制。启动块传输后,必须完成传输。您不能像使用字符设备那样“暂停”传输。
在串行链路上传输数据之前,必须将数据从存储器传输到UART (在这种情况下,Tx FIFO是发送寄存器的中间接口)。您可以使用PIO或DMA来执行此传输。
对于DMA传输,FIFO和DMA控制器都必须配置成在什么时候(和多久) DMA请求以及每个DMA响应的大小。
请注意,DMA响应的大小与DMA缓冲区的大小(如问题的标题中所示)或存储在计数寄存器中的DMA传输的大小不同。
DMA在HW同步mode.with BS =1 ans FS =0中配置为在经过DMA请求时传输完整块
假设传输的DMA传输设置为100计数和正确DMA缓冲区的地址,则Tx FIFO似乎正在发出DMA请求。
然后,第一个DMA响应用于100个字节的块大小,其中FIFO实际上只捕获了64个字节。这个第一个DMA响应的剩余字节可能会被丢弃。
当Tx FIFO耗尽时,如果它提出另一个DMA请求,那么这个新请求就不能满足,因为DMAC认为传输是“完全的”。您可以通过检查DMAC计数寄存器来检查此条件。DMAC计数寄存器是零还是36,丢失的字节数(100 - 64)?
如何将剩余的字节从DMA缓冲区传输到FIFO?/是否发生溢出?
要配置DMA控制器,请按照TRM第16.5.3节,硬件同步传输(第3627页)中概述的10个步骤来配置LCh,以便在每个DMA请求中传输一个元素。
总之,设置Tx以在至少有8个空空间时发出DMA请求,并设置DMA通道来响应1字节的单个元素。
https://stackoverflow.com/questions/24180786
复制相似问题