Forum Discussion
About DMA problem..please help me
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; }30 Replies
- Altera_Forum
Honored Contributor
why the while(!txrx_done); loop never complete? pls help...
- Altera_Forum
Honored Contributor
Hy everyone ..
I am trying to experiment with this DMA things too. The result:
I don'd get the result after that.. seems like it stuck ontesting 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
or txrx_done never go to 1 ? Besides, "content of sdram_1:before DMA operation " is always changing. Sometimes it'll become :while(!txrx_done);
Any reply will be appreciated Thank you:-P Yuyex:o0: 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 - Altera_Forum
Honored Contributor
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); } - Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
And don't forget to flush/bypass the data cache where appropriate.
- Altera_Forum
Honored Contributor
--- 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)
--- 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-statementvoid* tx_data = (void*)SSRAM_BASE; /* pointer to data to send */ void* rx_buffer = (void*)SDRAM_1_BASE; /* pointer to rx buffer */
but it still doesnt work! :confused: Is it a bug on the callback function?? since txrx_done never become 1.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); }
Any reply will be appreciated:) Yuyex:)//callback function when DMA transfer done static void tx_done(void * handle, void * data) { txrx_done = 1; } - Altera_Forum
Honored Contributor
TO_BE_DONE
- Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
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 - Altera_Forum
Honored Contributor
No SignalTap can be used with older versions of Quartus and SOPC builder without any problems.