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++
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Streaming DMA UART

Altera_Forum
Honored Contributor II
1,258 Views

Quartus II Version 4.00 SP1 Full Version  

Nios II Version 1.0.0 (With SP1) 

 

I'm trying to create a very simple system of streaming characters from memory UART using the DMA. The purpose is just to test the DMA streaming function(s).  

 

The system consist of a Nios II/s cpu along with 24kbytes of onchip ram for the code. The peripherals consist of two uarts along with the DMA. The dma read master is connected to the onchip ram, and the dma write master is connected to the second uart (verified). Both uarts use the default configuration. It also has sram defined in the system, but I don't have it being used within the code anymore (I was originally trying to stream from it to the uart).  

 

The first uart is setup in the system library to be used as the stdout, stderr, stdin. The onchip ram is set within the system library as the program memory, read-only memory, and read/write memory. 

 

The issue I'm having is the actual DMA transfer never completes. The dma_done function within my code never gets called, and I don't see any data come out of the second uart.  

 

Here is the code. 

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

 

alt_u8 buffer[16] __attribute__ ((section (".onchip_ram"))) = { 

0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, /* 0-9 */ 

0x61, 0x62, 0x63, 0x64, 0x65, 0x66 }; /* a-f */ 

 

static volatile int dma_complete = 0; 

 

void dma_done (void* handle) 

dma_complete = 1; 

 

int main(int argc, char* argv[], char* envp[]) 

{  

int rc; 

void* tx_data = (void*) &buffer[0]; 

printf("Hello from Nios II!\n"); 

alt_dma_txchan tx; 

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

printf("Failed to open device!\n"); 

exit(1); 

alt_dma_txchan_ioctl(tx, ALT_DMA_RX_STREAM_ON, (void*) 0x01); 

dma_complete = 0; 

if ((rc = alt_dma_txchan_send (tx, tx_data, 4, dma_done, NULL)) < 0 ) 

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

exit(1); 

while (!dma_complete); 

alt_dma_txchan_close (tx); 

printf("Transaction Complete!\n"); 

return 0; 

 

Small C library, and Reduced device drivers are checked to get it to fit within the 24k bytes. It takes up about 9k, and the rest is for the stack + heap. 

 

My belief is that I don&#39;t have the address of the uart defined correctly. I tried using the base address of that uart plus the offset to the write register, but that didn&#39;t work either. I haven&#39;t seen an example of a streaming dma function that shows me how to define it.
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
524 Views

Update:  

 

Fixed the issue with the addressing, specified 8 bit transfers, and changed it around to use external memory. I also specified within the SOPC to only allow 8 bit transfers for the DMA. I&#39;m not sure why I had to specify it in both the C code and the SOPC. It now seems to work. I haven&#39;t tested it with onchip memory yet.  

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

 

alt_u8 buffer[16] __attribute__ ((section (".ext_ram"))); 

 

static volatile int dma_complete = 0; 

 

void dma_done (void* handle) 

dma_complete = 1; 

 

int main(int argc, char* argv[], char* envp[]) 

{  

int rc; 

buffer[0] = 0x30; 

buffer[1] = 0x31; 

buffer[2] = 0x32; 

buffer[3] = 0x33; 

void* tx_data = (void*) &buffer[0]; 

printf("Hello from Nios II!\n"); 

alt_dma_txchan tx; 

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

printf("Failed to open device!\n"); 

exit(1); 

alt_dma_txchan_ioctl(tx, ALT_DMA_SET_MODE_8, NULL); 

alt_dma_txchan_ioctl(tx, ALT_DMA_RX_STREAM_ON, (void*) UART1_BASE+1); 

dma_complete = 0; 

if ((rc = alt_dma_txchan_send (tx, tx_data, 4, dma_done, NULL)) < 0 ) 

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

exit(1); 

while (!dma_complete); 

alt_dma_txchan_close (tx); 

printf("Transaction Complete!\n"); 

return 0; 

}
0 Kudos
Altera_Forum
Honored Contributor II
524 Views

i try to use your code successfull . 

After i use structure data instead buffer of bytes . 

So in this case the dma continually send butes and my pc  

became crazy . 

Then i try to fill your buffer from my data structure but the same occur . 

http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif  

Very strange  

In pc side i&#39;m using vc#.net with a rs232 dll . 

I post my code  

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

typedef struct conn{ 

alt_u16 data1; 

alt_u16 data2; 

alt_u16 data3; 

alt_u16 data4; 

}Master; 

 

alt_u8 buffer[16] __attribute__ ((section (".ext_ram"))); 

Master data;// __attribute__ ((section (".ext_ram"))); 

 

 

 

static volatile int dma_complete = 0; 

 

void dma_done (void* handle) 

dma_complete = 1; 

 

int main(int argc, char* argv[], char* envp[]) 

{  

int rc; 

//buffer[0] = 0x30; 

//buffer[1] = 0x31; 

//buffer[2] = 0x32; 

//buffer[3] = 0x33; 

data.data1=10; 

data.data2=20; 

data.data3=30; 

data.data4=40; 

data.data5=50; 

data.data6=60; 

data.data7=70; 

data.data8=80; 

 

alt_u8 i; 

alt_u8* pDati; 

alt_u8 size = sizeof(data);  

pDati = (alt_u8*)&data; //Point the first byte of my structure  

for(i=0; i< size; ++i) 

buffer[i] = *(pDati+i);  

 

 

void* tx_data = (void*) &buffer[0];//data;//&buffer[0]; 

printf("Hello from Nios II!\n"); 

printf("size:%u\r",size); 

alt_dma_txchan tx; 

if ((tx = alt_dma_txchan_open("/dev/dma_0")) == NULL) 

printf("Failed to open device!\n"); 

exit(1); 

alt_dma_txchan_ioctl(tx, ALT_DMA_SET_MODE_8, NULL); 

alt_dma_txchan_ioctl(tx, ALT_DMA_RX_STREAM_ON, (void*) UART_0_BASE+1); 

dma_complete = 0; 

if ((rc = alt_dma_txchan_send (tx, tx_data, 16, dma_done, NULL)) < 0 ) 

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

exit(1); 

while (!dma_complete); 

alt_dma_txchan_close (tx); 

printf("Transaction Complete!\n"); 

 

printf(" :%u,%u,%u,%u,%u,%u,%u,%u\r",buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buff 

er[7]); 

return 0; 

}  

 

The last printf i use prints the correct value of 16 bytes buffer . 

But the pc receive totally differents datas. 

Printf shows to me correct data in buffer : 

buffer[0]=10 

buffer[1]=0 

buffer[2]=20 

buffer[3]=0 

............ 

in the pc i recevice  

58-58-10-30-58-58-10-30-58-58-10-30-58-58-10-30 

Do you have some idea? 

ciao  

walter
0 Kudos
Reply