- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, may I know how to transfer data from peripheral to memory using DMA? It is quite confusing from memory-to-memory transfer. please help! thanks!
- Tags:
- Include
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
DMA is Avalon-MM (memory map) and SGDMA is Avalon-ST (streaming memory)
memory-to-memory (onchip to sdram, sram to sdram) stream-to-memory (buffer array to sdram, buffer to sram) memory-to-stream (sdram to buffer array, sram to buffer). You should read more about Avalon Interface Spec. Sean- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
So, is it cannot use DMA to transfer data between peripheral and memory?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What are you trying to do with DMA? You can transfer data from peripheral to your sdram, but you have to write your interface protocols and make connected to it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to transfer data from peripheral (adding number) to SDRAM. Is there any reference or tutorial to write the interface protocol?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If you are using DMA (Avalon-MM), there is Avalon-MM templates already at Altera website.
If you are using SGDMA (Avalon-ST), then you have to write your own protocols to connect your peripheral to Avalon-ST. Sean- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In my SOPC, i saw everything is Avalon MM Slave/Master. So is it consider as Avalon MM? Besides, my SDRAM is Avalon MM too, how to change to Avalon ST? Sorry, i am new. I can hardly understand. Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would use the following rather than the stock ACDS SGDMA:
http://www.altera.com/support/examples/nios2/exm-modular-scatter-gather-dma.html Cheers, slacker- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have done my DMA, which means I have to re-do to use SGDMA?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For Avalon-ST the typical minimal signals are data, ready, and valid. You connect a ST source (provider of data) to a ST sink (receiver of data). The data transfers between the source and sink when valid (from source) and ready (from sink) are both high. So if you have a component that provides/accepts a stream of data then ST is probably your best choice for an interface.
There are three DMAs discussed in this thread: 1) DMA on ACDS (old DMA that only supports MM transfers) 2) SGDMA on ACDS (DMA that supports MM and MM to/from ST transfers) 3) mSGDMA design example (hybrid of# 1 and# 2.... kinda) All three DMAs are not software compatible so before choosing a DMA make sure you are picking the right one for the task. So figure out what interface your custom component is going to use first then pick the DMA that makes the most sense to pair up with it. Also consider if you need scatter-gather or if having the CPU starting up the DMA for each transfer is sufficient for what you are doing. # 1 and# 3 have similar usage models whereas# 2 in my opinion is very different and the most difficult to program software around it. We won't be able to make a recommendation until knowing more about what your requirements are.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My requirement is connecting the DMA to a peripheral(eg adder of 2 number) to SDRAM. The input to the peripheral is user defined and once the adding process is completed, it will transfer the result to SDRAM. I wish to use DMA on the transferring of the result. Of course, real project is for image processing. I just used simple example to enhance understanding since I am starting from zero.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried out some code from this forum. I cannot write the result from peripheral to SDRAM. my code is as follow:
--- Quote Start --- # include "io.h"# include <stdio.h># include <unistd.h># include <sys/alt_dma.h># include "altera_avalon_pio_regs.h"# include "alt_types.h"# include "system.h"# include "sys/alt_timestamp.h" # ifndef datax # define datax 0x0# endif# ifndef datay # define datay 0x1# endif# ifndef datau # define datau 0x2# endif /* unsigned long add_h(unsigned long a, unsigned long b); unsigned long add_h(unsigned long a, unsigned long b) { long result; IOWR(AVALON_0_BASE,datax,a); IOWR(AVALON_0_BASE,datay,b); result = IORD(AVALON_0_BASE,datau); return result; } */ static volatile int rx_done = 0; static void transfer_done (void* handle, void* data) { rx_done++; } void mem2mem_DMA(unsigned int dst, int length, unsigned long a, unsigned long b) { void *rx_data = (void *) dst; alt_dma_rxchan rxchan; int ret_code; IOWR(AVALON_0_BASE,datax,a); // Data x IOWR(AVALON_0_BASE,datay,b); // Data y /* Create the receive channel */ if ((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL) { printf("Failed to open receive channel\n"); exit (1); } ret_code = alt_dma_rxchan_ioctl(rxchan, ALT_DMA_SET_MODE_32, NULL); if (ret_code) { printf("Error: SET_MODE_32: %d.\n", ret_code); exit(1); } ret_code = alt_dma_rxchan_ioctl(rxchan, ALT_DMA_RX_ONLY_ON, (void*)(AVALON_0_BASE)); if (ret_code) { printf("Error: ALT_DMA_RX_STREAM_ON: %d.\n", ret_code); exit(1); } /* Post the receive request */ if ((ret_code = alt_dma_rxchan_prepare(rxchan, rx_data, length, transfer_done, NULL)) < 0) { printf("Failed to post read request, reason = %i\n", ret_code); exit (1); } /* wait for transfer to complete */ while (!rx_done); printf("Transfer successful!\n\n"); } int main(void) { printf("\nThis is 32bits addition operation \n\n"); unsigned int dst = SDRAM_BASE + 0x600000; unsigned long number[100]; //unsigned long output1[100]; int i=0; int w; printf("Please specify number of sets of random number:\t "); scanf("%d", &w); for (i=0;i<w;i++) { number= 300000000;mem2mem_dma(dst, w, number, number);
}
for(i=0; i<w; i++)
{
printf("%ld\t %ld\n",number, IORD(dst, i)); } return 0; } --- Quote End --- My peripheral address is AVALON_0_BASE. This peripheral will add up 2 number, x and y. In this case, I set both x and y to be number[i], that is 300000000. Please assist. Thanks! really headache dealing with DMA.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think, what you are trying to do is not possible in this way.
First, your periphereal is memory mapped, so you are correct using the DMA. But DMA only makes sense when transferring multiple data in one run. Let me give you an example: For a serial interface, you could have the DMA transferring the contents of a buffer to the periphereal. For the opposite direction, you could use the DMA too, but not at the same time. (You could use a second DMA, if you wanted to send and receive parallel, allthough I don't think that would be neccessary). As a DMA is typically much faster than the periphereal, the DMA had to wait until the periphereal finished processing a value, before delivering the next one. Therefore, periphereals usually employ a buffer (e.g. a FIFO), so the DMA can write or read an amount of data in one run. The more data you can transfer at once, the more efficient it gets to use a DMA. Your code seems to use the DMA to deliver one value at a time. It does not make sense to setup the DMA to transfer 1 value of x, one value of y and one value of z. It would make more sense to add a fifo to your periphereal, and transmit the whole array of number[] for x, then for y, then have your periphereal calulate the result, and then again fetch the whole result[] via DMA. So you'd have to add 3 FIFOs to your periphereal, and some control to start a calculation once you have all data transmitted.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I see.. no wonder i cant get anything... what is FIFO? so, now i need to change my peripheral only? is there any example?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Not really.
I used the megawizard to create a custom megafunction dcFifo, and used that in my code. It will be a bit tricky, because you will need to implement logic that fetches data for your periphereal, but the Avalon side is pretty straightforward.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
do you mind to explain further? or maybe is there any tutorial about this? i have to understand the simple one like now, so i can implement in image processing... thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
FIFO is a type of RAM, namely First In First Out.
You can use it to queue data for processing. Have a look at the user guide from altera (http://www.altera.com/literature/ug/ug_fifo.pdf).- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, correct me if I am wrong: For my peripheral now, I have to create a memory to fit in the peripheral, all the result of computation is stored in the memory first, then, use DMA to transfer it to SDRAM. Am I right? is that consider as peripheral to memory transfer or still memory to memory transfer?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is a periphereal to memory transfer, as the DMA dosn't know about what your periphereal does with the data.
The difference between memory and periphereal access is, that the DMA increments addresses for memory access, but not for periphereal access. (Just a side note: If your periphereal implements a memory interface (e.g. like the Opencores I2S does), it would be neccessary to use memory-to-memory transfer.)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to make a peripheral to memory transfer. So, I add a RAM from Megawizard to my peripheral. Is that it? Besides, what are the differences between FIFO and RAM1port in Megawizard?
Besides, if DMA does not increase the memory address for peripheral, how does it transfer the data?![](/skins/images/C4F7392A5C68ACA60290C9576F107044/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page