Forum Discussion
NiosII DMA Tutorial
Hello, may I know where can I get NiosII DMA Tutorial? Currently, I am doing a project to implement DMA on FPGA board. So I would to refer to some tutorials that can help me. Thanks.
25 Replies
- Altera_Forum
Honored Contributor
--- Quote Start --- Hi Cris Long time no see. Thank you for helping me last time. Now I can do data transfer from FIFO to DDR3 via DMA correctly. However, this time I would like to ask your suggestion again. Currently I'm using three DMAs in my SOPC system to handle three different data transfers from three different FIFOs to a DDR3 memory. I have verified each FIFO and DMA data transfer and all of them work well. The problem occurs when I put all FIFOs and DMAs in one SOPC system design. I ran the DMA data transfer in sequence (not parallel). Somehow my Nios software hung / stopped. From the Nios software debugging, it was noticed that the Nios software might stop in different location, but mostly it stopped when it tried to open the DMA ('alt_dma_rxchan_open' function) or when it checked the DMA data transfer volatile indicator variable. Do you have any idea what caused my software hung? Or do you have any suggestion how to figure out the reason behind this problem? Thanks ... looking forward any replies from you guys! --- Quote End --- thank you firstly,i want to ask u about how to do data transfer from FIFO to DDR3 via DMA correctly? - Altera_Forum
Honored Contributor
Thanks Cris. I will try that.
Please take a look at my other thread too ^.^ - Altera_Forum
Honored Contributor
You understood correctly. That sequence is correct.
Anyway I don't know how to make the RD signal available outside the sopc system. You must expose the Avalon PIO read (or select) signal, so I think you probably need a modified version of the pio core. Maybe there's a way to export that signal, but I've never made something alike. You can try this workaround: use a tristate bus with a fake sram component; discard address,wr and rd signals; connect data to your fifo and use cs signal to update fifo output. - Altera_Forum
Honored Contributor
Thanks a lot Cris!! Last question, how can i connect the RD signal that the DMA gives before reading to the FIFO that is outsite my system? I probably have to read it from somewhere. I looked into the embbeded periphals guide from ALTERA but found nothing regarding this RD signal to synchronize with the fifo.
If i understood correctly it should happen like that: 1. DMA sends RD signal 2. FIFO gets the RD signal 3. FIFO updated the output data 4. DMA reads from output data Thanks a lot Cris you are helping me so much! - Altera_Forum
Honored Contributor
This piece of code sets the bit manually.
I don't know if there also is a specific function/macro to change the bit. # include "altera_avalon_dma_regs.h" int reg; reg = IORD_ALTERA_AVALON_DMA_CONTROL (dma_base_address); IOWR_ALTERA_AVALON_DMA_CONTROL (dma_base_address, reg | ALTERA_AVALON_DMA_CONTROL_RCON_MSK); - Altera_Forum
Honored Contributor
Cool, how can i set it in the software? I see is the 8th bit that i must set to 1. Where can i find examples of that? Thanks
- Altera_Forum
Honored Contributor
--- Quote Start --- I have a fifo outside my sopc system that is connected to a 8bits PIO in my sopc system. I want to read this 8 bits from my PIO and write to a DDR memory. How should the code look like? --- Quote End --- The code will be very similar to the previous one. The only difference being you need to read from a fixed address, i.e. the PIO base address: so you must set the RCON bit in the DMA control register. As I remarked somewhere in this thread, you also need a signal to pop data out of the fifo for every dma read access. Cris - Altera_Forum
Honored Contributor
Thanks a lot for this posts, Cris i can tranfer from my onchip memory to my sdram memory without any problems. But now i want to do something differnt. Really simmilar to what fightingdreamer did.
I have a fifo outside my sopc system that is connected to a 8bits PIO in my sopc system. I want to read this 8 bits from my PIO and write to a DDR memory. How should the code look like? (While i ask i am trying to modify your code) Thanks a lot. Fightingdreaming, do you have any tips? I saw you did exactly what i am trying to do. - Altera_Forum
Honored Contributor
@ Aprado
Hi, you can also learn about it from here http://www.alteraforum.com/forum/showthread.php?t=16850&highlight=dma+about , they discussed about DMA-memory data transfer and shared some code @ Cris Hi Cris, sorry for asking you again using this thread. Currently I'm discussing a problem about changing Nios's IP address in other thread http://www.alteraforum.com/forum/showthread.php?p=105881#post105881 . If you don't mind, please kindly to check it, maybe you have some advices for my problem :( Thank you! - Altera_Forum
Honored Contributor
Hi aprado,
I have this piece of code for a simple dma core. I think you need to make a few changes in order to use with your sgdma core.# include "sys/alt_dma.h"# include "altera_avalon_dma.h" # define DMA_LENGTH 512 volatile int dma_complete; short rx_buffer; // pointer to rx buffer short tx_buffer; // pointer to tx buffer void dma_done (void* handle, void* data) { int rc; // turn the LED off (for DEBUG) rc = IORD_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, rc & ~0x10); dma_complete = 1; } int test_dma(void) { int rc; alt_dma_txchan txchan; alt_dma_rxchan rxchan; void* tx_data = (void*) tx_buffer; // pointer to data to send dma_complete = 0; // Create the transmit channel if ((txchan = alt_dma_txchan_open("/dev/ts_dma")) == NULL) { printf ("Failed to open transmit channel\n"); return -1; } // Create the receive channel if ((rxchan = alt_dma_rxchan_open("/dev/ts_dma")) == NULL) { printf ("Failed to open receive channel\n"); return -2; } if(alt_dma_txchan_ioctl(txchan, ALT_DMA_SET_MODE_16, NULL)<0) { return -3; } if(alt_dma_rxchan_ioctl(rxchan,ALT_DMA_SET_MODE_16,NULL)<0) { return -4; } if(alt_dma_txchan_ioctl(txchan,ALT_DMA_TX_ONLY_OFF,NULL)<0) { return -5; } if(alt_dma_rxchan_ioctl(rxchan,ALT_DMA_RX_ONLY_OFF,NULL)<0) { return -6; } printf ("Test DMA transfer...\n"); // turn a LED on (for DEBUG) rc = IORD_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, rc | 0x10); // Post the transmit request if ((rc = alt_dma_txchan_send (txchan,tx_data,DMA_LENGTH-16,NULL,NULL)) < 0) { printf ("Failed to post transmit request, reason = %i\n", rc); return -7; } // Post the receive request if ((rc = alt_dma_rxchan_prepare (rxchan,rx_buffer,DMA_LENGTH-16, dma_done,NULL)) < 0) { printf ("Failed to post read request, reason = %i\n", rc); return -8; } // wait for transfer to complete while (!dma_complete) TK_SLEEP(10); printf ("Transfer successful!\n"); return 0; }