首页 文章

DMA缓冲区大小是否应与UART FIFO大小相同?

提问于
浏览
1

我在Linux平台上运行的omap4460熊猫板上为UART编写了驱动程序 . 我在UART中启用了FIFO模式的DMA . 我的用户应用程序将100字节的数据从用户空间传输到内核缓冲区(DMA缓冲区) .

一旦DMA通道被使能,来自DMA缓冲区的数据就被复制到FIFO,然后传输到UART的TSR . 由于我的FIFO大小为64字节,因此只有64字节被传输到TSR .

如何将剩余字节从DMA缓冲区传输到FIFO?/ IS是否存在溢出?

编辑:添加了以下配置代码的某些部分代表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 again

DMA在HW SYNC模式下配置 . 具有BS = 0和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] http://www.ti.com/lit/ug/swpu235ab/swpu235ab.pdf中给出的任何模式下触发DMA请求

编辑:修改了元素同步的代码 . 1.在TRM中经常观察到这句话 . 有什么设置?

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寄存器的触发电平 .

在此代码中,我使用TLR寄存器进行了设置 . 此TLR设置通过中断模式进行验证 .

1 回答

  • 2

    DMA配置为...块同步 .

    这是一个根本性的错误 .
    块同步将用于块设备,例如HDD,其具有扇区缓冲器以接收完整块,因为数据在一次操作中通过SATA(或PATA)总线传输 .
    UART是一种字符设备,每次操作传输一个字符 . 存在FIFO以确保可以接收数据(防止溢出)并且数据可用于传输(最小化空闲线路时间) . 串行链路的另一端具有未知的缓冲能力 . 如果它的缓冲有限,则应采用流量控制(使用硬件RTS / CTS或软件XON / XOFF) .
    块设备不使用流量控制 . 一旦开始块传输,就必须完成传输 . 你不能使用角色设备进行传输 .

    在串行链路上传输数据之前,必须将数据从存储器传输到UART(在这种情况下,Tx FIFO是发送寄存器的中间接口) . 您可以使用PIO或DMA执行此传输 .
    对于DMA传输,FIFO和DMA控制器必须配置为同意DMA请求的时间(和频率)以及每个DMA响应的大小 .
    请注意,DMA响应的大小与DMA缓冲区的大小(在问题的 Headers 中)或存储在计数寄存器中的DMA传输的大小不同 .

    在HW SYNC模式下配置DMA . 在BS = 1和FS = 0.ie时,在发出DMA请求时传输完整块

    假设发送的DMA传输设置为100的计数和正确的DMA缓冲区的地址,似乎Tx FIFO正在发出DMA请求 .
    然后,第一个DMA响应是针对100字节的块大小,其中FIFO实际上只捕获了64个字节 . 可能会丢弃第一个DMA响应的剩余字节 .
    当Tx FIFO耗尽时,如果它发出另一个DMA请求,则无法满足该新请求,因为DMAC认为传输"complete" . 您可以通过检查DMAC计数寄存器来检查此情况 . DMAC计数寄存器是零还是36,丢失的数量(100 - 64)字节?

    如何将剩余字节从DMA缓冲区传输到FIFO?/ IS是否发生溢出?

    要配置DMA控制器,请遵循TRM第16.5.3节“硬件同步传输”(第3627页)中概述的十个步骤,了解如何配置LCh以传输 one element per DMA request .

    总之,设置Tx FIFO以在至少有8个空格时发出DMA请求,并使用1个字节的单个元素响应DMA通道 .

相关问题