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++
12590 Discussions

About DMA problem..please help me

Altera_Forum
Honored Contributor II
3,675 Views

hi all 

I have try the altera memory test project with Nios II IDE.. 

but always display "-Testing memory using DMA"... http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif  

the dma might be already open.. 

and didn`t display "Memory at 0x%X Okay"....... 

 

so...I found the code at nios forum...it should be work  

but it always display"wait for transfer to complete"...why? 

look like the same problem with memory test !? 

 

I use Quartus II 5.1 SP2 & Nios II IDE 5.1 SP1 

the exception address is sram_0 at SOPC Builder 

the program memory & .rodata & .rwdata & heap memory & stack memory are sdram_0 

 

and I sure I have connect the DMA read & write master with sdram_0 & avalon tristate bridge in the SOPC builder 

 

this is the code...please help me  

thanks.... 

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

 

/* Create the transmit channel */ 

static volatile int rx_done = 0; 

 

/* ready handler*/ 

static void done (void* handle, void* data) 

rx_done++; 

 

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

int rc; 

alt_u8 Inbuf[1024], Outbuf[1024]; 

alt_dma_txchan txchan; 

alt_dma_rxchan rxchan; 

 

void* tx_data = (void*) &Inbuf[0]; /* pointer to data to send */ 

void* rx_buffer = (void*) &Outbuf[0]; /* pointer to rx buffer */ 

 

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

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

exit (1); 

/* Create the receive channel */ 

if ((rxchan = alt_dma_rxchan_open("/dev/avalon_dma")) == NULL) 

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

exit (1); 

/* Post the transmit request */ 

if ((rc = alt_dma_txchan_send (txchan,tx_data,1024,NULL,NULL)) < 0) 

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

exit (1); 

/* Post the receive request */ 

if ((rc = alt_dma_rxchan_prepare (rxchan,rx_buffer,1024,done,NULL)) < 0) 

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

exit (1); 

/* wait for transfer to complete */ 

printf ("wait for transfer to complete\n"); 

while (!rx_done); 

printf("Transfer successful!\n"); 

return 0; 

}
0 Kudos
30 Replies
Altera_Forum
Honored Contributor II
202 Views

why the while(!txrx_done); loop never complete? pls help...

0 Kudos
Altera_Forum
Honored Contributor II
202 Views

Hy everyone .. 

I am trying to experiment with this DMA things too.  

The result:  

testing ssram & sdram : dma operation content of ssram_0:before DMA operation 0: 0 1: 1 2: 2 3: 3 4: 4 5: 5 6: 6 7: 7 8: 8 9: 9 10: a 11: b 12: c 13: d 14: e 15: f content of sdram_1:before 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 I don'd get the result after that.. seems like it stuck on  

while(!txrx_done);  

or txrx_done never go to 1 ? 

 

Besides, "content of sdram_1:before DMA operation " is always changing. Sometimes it'll become : 

0: 33 1: 33 2: 33 3: 33 4: 33 5: 33 6: 33 7: 33 8: 33 9: 33 10: 33 11: 33 12: 33 13: 33 14: 33 15: 33  

 

Any reply will be appreciated Thank you:-P 

Yuyex:o
0 Kudos
Altera_Forum
Honored Contributor II
202 Views

besides , I changed the code to : 

/* Post the transmit request */ if ((tc = alt_dma_txchan_send (txchan, tx_data, 0x10, NULL, NULL)) < 0) { printf ("Failed to post transmit request, reason = %i\n", tc); exit (1); } else { printf ("Succeed to post transmit request when tc = %i\n",tc); //exit (1); } /* Post the receive request */ if ((rc = alt_dma_rxchan_prepare (rxchan, rx_buffer, 0x10, txrxDone, NULL)) < 0) { printf ("Failed to post read request, reason = %i\n", rc); exit (1); } else { printf ("Succeed to post read request when rc = %i\n",rc); printf ("txrx_done = %d",txrx_done); }
0 Kudos
Altera_Forum
Honored Contributor II
202 Views

How about your txrxDone function? 

Ensure that the txrx_done variable is declared as volatile to prevent any optimisations from reading the value properly. 

Check that tx_data and rx_buffer are pointed to valid memory areas, and memories the DMA's avalon masters are actually connected to. 

If it still doesn't work, put some Signaltap probes on the DMA component to see what it is doing and if/where it gets stuck.
0 Kudos
Altera_Forum
Honored Contributor II
202 Views

And don't forget to flush/bypass the data cache where appropriate.

0 Kudos
Altera_Forum
Honored Contributor II
202 Views

 

--- Quote Start ---  

How about your txrxDone function? 

Ensure that the txrx_done variable is declared as volatile to prevent any optimisations from reading the value properly. 

--- Quote End ---  

 

 

I have declared it already. 

 

 

--- Quote Start ---  

 

Check that tx_data and rx_buffer are pointed to valid memory areas, and memories the DMA's avalon masters are actually connected to. 

--- Quote End ---  

I think I have connected it right. (*picture attached) 

void* tx_data = (void*)SSRAM_BASE; /* pointer to data to send */ void* rx_buffer = (void*)SDRAM_1_BASE; /* pointer to rx buffer */  

--- Quote Start ---  

 

If it still doesn't work, put some Signaltap probes on the DMA component to see what it is doing and if/where it gets stuck. 

--- Quote End ---  

I haven't tried this coz I don't know how to do it :(  

 

 

--- Quote Start ---  

And don't forget to flush/bypass the data cache where appropriate. 

--- Quote End ---  

 

Sorry but I don'g get it.. I am new to SOPC stuff. can you please give more explanation? 

 

Besides , from this thread http://www.alteraforum.com/forum/showthread.php?t=13023 ,it seems like this code (or the code from NIOS II Software's Developer user guide) have some bug, since "while (!dma_done);" doesn't work at all. I have changed it by using if-statement  

if (txrx_done == 1) { printf ("Transfer Function Done!\n"); /* Post the receive request */ if ((rc = alt_dma_rxchan_prepare (rxchan, rx_buffer, 0x10, rx_done, NULL)) < 0) { printf ("Failed to post read request, reason = %i\n", rc); exit (1); } else { printf ("Succeed to post read request when rc = %i\n",rc); printf ("txrx_done = %d\n",txrx_done); //printf ("done = %d",done); } but it still doesnt work! :confused: 

Is it a bug on the callback function?? since txrx_done never become 1. 

//callback function when DMA transfer done static void tx_done(void * handle, void * data) { txrx_done = 1; } Any reply will be appreciated:) 

Yuyex:)
0 Kudos
Altera_Forum
Honored Contributor II
202 Views

TO_BE_DONE

0 Kudos
Altera_Forum
Honored Contributor II
202 Views

The problem with the if is that if it is executed before the DMA transfer ends, then you will exit your main function without displaying anything. That's why the original code had a while(). Besides I don't think it's a good idea to wait for the end of the tx operation before setting the tx channel. I don't know how the HAL driver is written, but there is probably nothing happening in the DMA until both the transmit and receive channels have been configured. 

 

You should have a look at the turorials to learn how to use SignalTap. It is relatively easy to use and is an essential debugging tool in those kind of situations.
0 Kudos
Altera_Forum
Honored Contributor II
202 Views

Thank you for your reply Daixiwen:o, 

 

Btw , is it true that this "SignalTap" function can only be used in Quartus II and NIOS II version 11.0 or later? 

Since I am using Quartus 10.1 and NIOS II 10.1. 

 

Besides, seems like it's using Qsys rather than SOPC? (page.11 on the PDF) 

 

Source : http://www.altera.com/literature/an/an446.pdf 

 

Or you guys have some good examples for me to practice this "SignalTap" function?:) 

 

Thank you in advance, 

Yuyex:o
0 Kudos
Altera_Forum
Honored Contributor II
202 Views

No SignalTap can be used with older versions of Quartus and SOPC builder without any problems.

0 Kudos
Reply