Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

How to connect UART and DMA?

Honored Contributor II

In the document "Embedded Peripherals IP", I find following paragraph: 

"The UART core's Avalon-MM interface optionally implements Avalon-MM transfers with flow control. Flow control allows an Avalon-MM master peripheral to write data only when the UART core is ready to accept another character, and to read data only when the core has data available." 

Can anybody tell me how to implement this flow control, for I always failed to use UART in DMA model.  

The following code is that I used to write data to UART. Finally I can get "Transfer successful!" , but NO words disappear in the UART Monitor. 


# include <stdio.h># include <stdlib.h># include "sys/alt_dma.h"# include "altera_avalon_uart_regs.h"# include "system.h"# include "alt_types.h" 


static volatile int tx_done = 0; 

volatile static alt_u8 chr[3] = {'A','B','C'} ; 


static void done (void* handle) 



int main() 

int rc; 

alt_dma_txchan txchan; 

void* source_buff_ptr = (void*) chr;  


void* destination_buff_ptr = (void*)IOADDR_ALTERA_AVALON_UART_TXDATA(DEBUG_UART_BASE);  


if((txchan = alt_dma_txchan_open("/dev/dma")) == NULL) 

printf ("Failed to open transmit channel\n"); 

exit (1); 


if ((rc = alt_dma_txchan_ioctl(txchan, ALT_DMA_TX_ONLY_ON, destination_buff_ptr)) < 0) 

printf ("Failed to set ioctl, reason = %i\n", rc); 

exit (1); 


if((rc = alt_dma_txchan_ioctl(txchan,ALT_DMA_SET_MODE_8 ,NULL))<0) 

printf("Failed to set mode 8\n"); 



if ((rc = alt_dma_txchan_send(txchan, source_buff_ptr, 3, done, NULL)) < 0) 

printf ("Failed to post transmit request, reason = %i\n", rc); 

exit (1); 


while (!tx_done); 

printf ("Transfer successful!\n"); 

return 0; 

0 Kudos
3 Replies
Honored Contributor II

Still no solve.  


1. My developing software is Quartus II 10.1. 


2. I used a scope to watch the wave of TX pin. If I write the UART writedata register directly, I can see the right wave. However, when I use DMA to trans this data, the TX will be hold high. 


3. When debug on the hardware, I find the dma status will go to 0x03 soon after the alt_dma_txchan_send is run. But still no wave appears on TX pin. The UART writedata register is never changed. 


4. When I use signaltap II to watch the dma signals, "writedata, write_n, waitforrequest, writeaddress", all value is what I want. But there is one question, the data rate is half of the cpu clk. I don't believe a writting operation to a UART writedata registor can be so fast. However, the writeaddress is do the UART TXDATA registor. 


I am sure the connection of UART, SRAM and DMA is right, and I am so puzzled. Could anybody help me??? 

Thank your very much!!
0 Kudos
Honored Contributor II

The problem is solved.I just change the destination address. Use (void *)(UART_Base+1)to replace destination_buff_ptr in the code "rc = alt_dma_txchan_ioctl(txchan, ALT_DMA_TX_ONLY_ON, destination_buff_ptr". But I don't understand why, because the register is 32 bit width.....

0 Kudos
Honored Contributor II

did U really solve the problem? How is the flow controll between DMA and UART working? 


please take a look at my post. I do not understand it. Thanks
0 Kudos