This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

UART FIFO is not getting enabled.

I have enabled the FIFO as mentioned in the Programming Guide of the Technical Reference Manual.ie before setting the Baud rate.But this way does not actually enable the FIFO.Instead I tried a hit and trial by enabling the FIFO just after loading the Baud rate and UART operational mode.Fortunately FIFO is enabled.I was verifying the correctness in Interrupt Mode.

Now I want to enable the DMA mode.My new issue is when FIFO is not enabled, even though there are 100 bytes of data only 1 byte is transmitted,similarly when I enable the FIFO exactly 64 bytes(FIFO size) is transmitted.

I think DMA is not getting triggered.Please suggest me if there is any mistake.

I am using OMAP4460 panda board with Linux OS(3.4) loaded in it.

User application writes the data from user space to kernel space(DMA buffer) when the write function is called.

code below represents the UART configuration

/* 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 enabled here
	iowrite32(UART_MODE_B,uart_vbaddr + UART_LCR);
	iowrite32(0x3,uart_vbaddr + UART_TLR);
	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);//Renabling the FIFO again

DMA is configured in the HW SYNC mode.with BS =1 ans FS =0.ie to transfer complete block when DMA request is assserted

Code below gives the DMA configuration

/* Set the Read Port & Write Port access in CSDP */
csdp_val &= 0x00000000;
iowrite32(csdp_val,dma_map + DMA_CSDP(dma_cha_line));

/* CEN register configuration */
iowrite32(BUFSIZE,dma_map + DMA_CEN(dma_cha_line));

/* CFN register configuration */
iowrite32(1,dma_map + DMA_CFN(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 
ccr_val &= ~(0x1 << 13);	
ccr_val &= ~(0x3 << 14);//destination- constant address mode
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.

Please suggest me if there is any wrong in the initialization as I am getting only 64 bytes also I am unable to trigger the DMA request in any of the mode given in TRM

Thanks in advance

  • Hi,

    The UART FIFO configuration seems correct.

    I think the problem is the setting of DMA. You configure the DMA to be HW synced on block basis. You configure 1 block to be equal to 1 frame, and a frame to be equal to the BUFFSIZE (I assume this is the UART FIFO size = 64 bytes, right? ):

    iowrite32(1, dma_map + DMA_CFN(dma_cha_line));  //configure 1 block = 1frame

    iowrite32(BUFSIZE, dma_map + DMA_CEN(dma_cha_line));  //configure 1 frame = uart_fifo_size = 64 bytes

    This way the first time dma channel is enabled 64 bytes will be transferred (1block), on the next dma assertion there will be 100-64 bytes = 36 bytes, hence less than 1 block.

    I have a couple of suggestions:

    1. Can you try configuring your board to transfer 1 element per DMA request, that is FS = 0x0, BS = 0x0, and see if in uart data will be drained?

    2. Play with the configurations of CFN & CEN, so that you can transfer all 100bytes in a couple of successive DMA request, or in a single transfer.

    Best Regards,
    Yordan

  • Hi Yordan,

    Thanks for your reply.
    According to the mentioned code BUFSIZE is allocated with size of the DMA buffer which is 100 bytes.

    I think as per your statement it should be 64 bytes which is FIFO size.Then where should I mention the count of actual buffer size.

    I will try element by element transfer and revert you back with the result.

    There are some small doubts.

    1.Is this configuration correct ? :

    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 ?

    2.Is FIFO necessary to implement the DMA operation?

    3.There are 3 ways to configure the trigger level of FIFO.ie FCR/TLR/MDR3 registers.

    Should I configure only TLR registers to assert a DMA request ?/Can it be configured by registers?

    Thanks in advance

    Kind Regards

    Dino

  • Hi Yordan,

    A small update regarding Element by Element transfer.DMA request is not asserted in this mode and hence there is not data transfer between DMA buffer and UART(FIFO).

    Please come up with your suggestion.

    Thanks & Regards

    Dino David.