Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20704 Discussions

Nios Uart And Dma

Altera_Forum
Honored Contributor II
1,516 Views

HI: 

I try to transfer datas from uart to onchip memory using DMA,following code is my programme,I use uart assistant to transfer data per 1000m second ,but sometimes I can see the right datas on onchip memory but sometimes i can not. 

 

#include <stdio.h> 

#include "system.h" 

#include "string.h" 

#include <stddef.h> 

#include <stdlib.h> 

#include "sys/alt_dma.h" 

#include "alt_types.h" 

#include "altera_avalon_uart_regs.h" 

 

 

//main &#20027;&#31243;&#24207; 

int main() 

 

int rc; 

void * rx_buffer = (void*) 0x27000; 

alt_dma_rxchan rx; 

rx = alt_dma_rxchan_open("/dev/dma_uart5"); 

 

/* Obtain a handle for the device */ 

if (rx != null

printf("dma start."); 

while(1) 

/* Post the receive request */ 

 

alt_dma_rxchan_ioctl(rx,ALT_DMA_SET_MODE_8,null); 

alt_dma_rxchan_ioctl(rx, 

ALT_DMA_RX_ONLY_ON,(void*) UART_5_BASE); 

 

if ((rc=alt_dma_rxchan_prepare(rx,rx_buffer,20, 

null, null))< 0)  

printf ("Error: failed to post receive request,reason = %i\n", rc); 

exit (1); 

 

alt_dma_rxchan_close (rx); 

printf("done!"); 

 

return 0; 

 

 

 

 

0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
698 Views

Hi, 

 

I also want to transmit data from UART to memory by using DMA and I have the same problem you discribe. So I´m glad to see that I´m not the only one with that problem. But first of all I think you don´t really know what a DMA should do. So I´m wondering why prepare DMA without using the interrupt handle. The next think is that you close DMA after prepare him in order to open DMA again cause you are in an endless while loop. That doesn´t seem to make sense. You have to wait till DMA has finished. Thats why you have to use the DMA interrupt handle - I think. 

 

And last you should begin with a transfer of 4 Byte. I realized that the DMA works better with a small transfer size than with a large one.
0 Kudos
Altera_Forum
Honored Contributor II
698 Views

hi , 

my problem has been resolved ,the uart ip has "end of packet"selection,if you use it,it sets zero as the end character,so if your characters to be transferred include zero,the uart will stop the transfer when it meets zero .:)
0 Kudos
Altera_Forum
Honored Contributor II
698 Views

hi, 

kind of new in the nios world, trying to use dma with my uart... 

you wrote :  

 

void * rx_buffer = (void*) 0x27000; 

 

can you explain this please ?  

 

I understand that DMA is a cpu feature, is it a default or I need to add it to my system ? 

 

how do you access the the in coming data ? 

thank you...
0 Kudos
Altera_Forum
Honored Contributor II
698 Views

 

--- Quote Start ---  

hi , 

my problem has been resolved ,the uart ip has "end of packet"selection,if you use it,it sets zero as the end character,so if your characters to be transferred include zero,the uart will stop the transfer when it meets zero .:) 

--- Quote End ---  

 

 

Hi, 

 

Currently I got problem with DMA as Rx channel :(. What I'm trying to don now is I want to verify whether the DMA can handle data transfer from a PIO to memory. So in my verification system here, I'm doing a loopback test by adding two PIOs in my SOPC system which functions as the data transmitter (the PIO's name is PIO_DUMY_OUTPUT) and receiver (the PIO's name is PIO_DATA_8BIT), respectively. I connected those PIO's in my verilog code. 

 

Here is my code : 

volatile static int txrx_done = 0; // callback function when DMA transfer done static void txrxDone (void * handle, void * data) { txrx_done = 1; } void initMEM(int base_addr, int len, int data) { int i; for (i=0; i<len; i++) { IOWR_8DIRECT(base_addr+i, 0, 33); } } // peripheral - memory transfer 1 void pio_transfer() { int rc, i, mode; int dma_len = 0x25; alt_dma_rxchan rxchan; void * rx_buffer = (void*) DDR3_TOP_BASE; txrx_done = 0; // ------------------------------------------------------------------------------- printf("testing peripheral to memory dma operation\n"); initMEM(DDR3_TOP_BASE,dma_len,3); printf("content of the memory content before DMA operation : \n"); for (i=0; i<dma_len; i++) { printf("%d : %x\n", i, IORD_8DIRECT(DDR3_TOP_BASE,i)); } // ------------------------------------------------------------------------------- if((rxchan = alt_dma_rxchan_open("/dev/dma_data_8bit")) == NULL) { printf("Failed to open receive channel\n"); exit(1); } // ------------------------------------------------------------------------------- if(alt_dma_rxchan_ioctl(rxchan,ALT_DMA_SET_MODE_8,NULL)<0) { exit(1); } printf("debug0 \n"); check_dma(); if(alt_dma_rxchan_ioctl(rxchan,ALT_DMA_RX_ONLY_ON, (void*) PIO_DATA_8BIT_BASE)<0) { exit(1); } // ------------------------------------------------------------------------------- printf("debug1 \n"); if((rc = alt_dma_rxchan_prepare(rxchan, rx_buffer, dma_len, NULL, NULL))<0) { printf("Failed to post receive request, reason = %i\n", rc); exit(1); } // ------------------------------------------------------------------------------- printf("PIO : generate, transmit, and receive the dummy data\n"); for (i=0; i<dma_len; i++) { IOWR_ALTERA_AVALON_PIO_DATA(PIO_DUMY_OUTPUT_BASE, 3*i+2); printf("PIO : receiving dummy data : %d - %d\n",IORD_ALTERA_AVALON_PIO_DATA(PIO_DATA_8BIT_BASE), txrx_done); } IOWR_ALTERA_AVALON_PIO_DATA(PIO_DUMY_OUTPUT_BASE, '\0'); //write end-of-packet character // ------------------------------------------------------------------------------- printf("debug2 \n"); check_dma(); printf("wait DMA transfer is completed\n"); //while(!txrx_done); //alt_dma_rxchan_close (rxchan); printf("Transfer is success\n"); check_dma(); // ------------------------------------------------------------------------------- printf("content of the memory DDR3 content after DMA operation : \n"); for (i=0; i<dma_len; i++) { printf("%d : %x\n", i, IORD_8DIRECT(DDR3_TOP_BASE,i)); } // ------------------------------------------------------------------------------- } 

 

And here is the result : 

content of the memory content before DMA operation : 0 : 21 1 : 21 2 : 21 3 : 21 4 : 21 5 : 21 6 : 21 7 : 21 8 : 21 9 : 21 10 : 21 11 : 21 12 : 21 13 : 21 14 : 21 15 : 21 16 : 21 17 : 21 18 : 21 19 : 21 20 : 21 21 : 21 22 : 21 23 : 21 24 : 21 25 : 21 26 : 21 27 : 21 28 : 21 29 : 21 30 : 21 31 : 21 32 : 21 33 : 21 34 : 21 35 : 21 36 : 21 PIO : generate, transmit, and receive the dummy data PIO : receiving dummy data : 2 - 0 PIO : receiving dummy data : 5 - 0 PIO : receiving dummy data : 8 - 0 PIO : receiving dummy data : 11 - 0 PIO : receiving dummy data : 14 - 0 PIO : receiving dummy data : 17 - 0 PIO : receiving dummy data : 20 - 0 PIO : receiving dummy data : 23 - 0 PIO : receiving dummy data : 26 - 0 PIO : receiving dummy data : 29 - 0 PIO : receiving dummy data : 32 - 0 PIO : receiving dummy data : 35 - 0 PIO : receiving dummy data : 38 - 0 PIO : receiving dummy data : 41 - 0 PIO : receiving dummy data : 44 - 0 PIO : receiving dummy data : 47 - 0 PIO : receiving dummy data : 50 - 0 PIO : receiving dummy data : 53 - 0 PIO : receiving dummy data : 56 - 0 PIO : receiving dummy data : 59 - 0 PIO : receiving dummy data : 62 - 0 PIO : receiving dummy data : 65 - 0 PIO : receiving dummy data : 68 - 0 PIO : receiving dummy data : 71 - 0 PIO : receiving dummy data : 74 - 0 PIO : receiving dummy data : 77 - 0 PIO : receiving dummy data : 80 - 0 PIO : receiving dummy data : 83 - 0 PIO : receiving dummy data : 86 - 0 PIO : receiving dummy data : 89 - 0 PIO : receiving dummy data : 92 - 0 PIO : receiving dummy data : 95 - 0 PIO : receiving dummy data : 98 - 0 PIO : receiving dummy data : 101 - 0 PIO : receiving dummy data : 104 - 0 PIO : receiving dummy data : 107 - 0 PIO : receiving dummy data : 110 - 0 content of the memory DDR3 content after DMA operation : 0 : 0 1 : 0 2 : 0 3 : 0 4 : 0 5 : 0 6 : 0 7 : 0 8 : 0 9 : 0 10 : 0 11 : 0 12 : 0 13 : 0 14 : 0 15 : 0 16 : 0 17 : 0 18 : 0 19 : 0 20 : 0 21 : 0 22 : 0 23 : 0 

 

So anyone can tell me why the DMA can't write correctly the data that received by PIO_DATA_8BIT to DDR3 ? Is my loopback test wrong? Is it possible to handle data transfer from a PIO to memory like what I'm doing? :confused: 

 

Thanks before, I really appreciate any comments and help :)
0 Kudos
Reply