Forum Discussion
Altera_Forum
Honored Contributor
15 years agoDMA problem
why when i use my dma, the program stucks here:
--- Quote Start --- while (!rx_done); printf ("Transfer successful!\n"); --- Quote End --- pls help! thanks!17 Replies
- Altera_Forum
Honored Contributor
akira: thanks for your explanation. now i understand better of the function. because i got the code from example and try to understand the flow of the code.
Cris72: only now i know cant use DMA between SDRAM and flash. i would like to try between flash and SDRAM but as in my other thread, i have problem in writing to flash. - Altera_Forum
Honored Contributor
You can't DMA from dram to flash. DMA is like a normal memory write: the only difference is that it's performed by DMA controller and not by CPU.
Since flash can't be written as RAM, the operation is invalid. Anyway the DMA transfer should work, although after execution you will not find in the flash memory the transferred data. I suggest in the debug phase you don't use the while(!rx_done) instruction, which involves dma interrupt. Instead, wait for a while (i.e. with a long loop) and then test if your data has been correctly transferred. You may even test the status bits for dma completion. As said above you must first change your buffers: dma from sdram to sdram, or from flash to sdram. - Altera_Forum
Honored Contributor
all right.
this code may be OK.( this is copied from NiosII example, right?) you know what is going on. after alt_dma_rxchane_pepare(); DMA is started by the function and continues transfer as long as data remain. after then, when transfer is finished the function "done" is called in background of the sequence. value in rx_done is turned into "1" then the while loop will finish due to its logic. so, I'm not sure why dma is not finished. but I wonder can you DMA from SDRAM to Flash? - Altera_Forum
Honored Contributor
Hi, this is my code:
--- Quote Start --- # include <stdio.h># include <stdlib.h># include <unistd.h># include "altera_avalon_pio_regs.h"# include "system.h"# include "alt_types.h"# include "sys/alt_dma.h"# include "sys/alt_flash.h" # include "sys/alt_flash_dev.h"# include "altera_avalon_dma_regs.h"# include "altera_avalon_dma.h" # define loop 16384# define size 65536 static volatile int rx_done = 0; static void done (void* handle, void* data) { rx_done = 1; } int main (int argc, char* argv[], char* envp[]) { alt_flash_fd* fd; int ret_code, i; int *src_ptr; int *dest_ptr; int addr; int rc; alt_dcache_flush_all(); alt_u32 start,end; alt_dma_txchan txchan; alt_dma_rxchan rxchan; addr = 0; src_ptr = SDRAM_BASE + 0x200000; //Location of data written in SDRAM dest_ptr = EXT_FLASH_BASE; //Location of data written in flash void* tx_data = (void*) SDRAM_BASE + 0x200000; /* pointer to data to send */ void* rx_buffer = (void*) EXT_FLASH_BASE + 0x100000; /* pointer to rx buffer */ //Open flash fd = alt_flash_open_dev(EXT_FLASH_NAME); if(fd!=NULL) { //Generate data into SDRAM for(i=0;i<loop;i++) { IOWR(src_ptr, i, i); } //Write data into flash while(addr < size) { ret_code = alt_write_flash(fd, addr, src_ptr+addr, 0x10000); if(ret_code != 0) { printf("Error writing into flash: %d\n", ret_code); exit(1); } addr += 0x10000; // next 64kb block } //Read from flash for(i=0;i<loop;i++) { printf("Value at %X is %d, written is %d\n", dest_ptr, *dest_ptr, IORD(src_ptr, i)); dest_ptr++; } }else { printf("Unable to open flash\n"); exit(1); } /* Create the transmit channel */ if ((txchan = alt_dma_txchan_open(DMA_NAME)) == NULL) { printf ("Failed to open transmit channel\n"); exit (1); } /* Create the receive channel */ if ((rxchan = alt_dma_rxchan_open(DMA_NAME)) == NULL) { printf ("Failed to open receive channel\n"); exit (1); } /* Post the transmit request */ if ((rc = alt_dma_txchan_send (txchan, tx_data, size, 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, size, done, NULL)) < 0) { printf ("Failed to post read request, reason = %i\n", rc); exit (1); } /* wait for transfer to complete */ while (!rx_done); printf ("Transfer successful!\n"); alt_flash_close_dev(fd); return 0; } --- Quote End --- I am not sure where it stuck because it does not return any error messages. so i assume dma is working. pls help. thanks! - Altera_Forum
Honored Contributor
you know when rx_done is changed?
it is changed in an interrupt logic. (I'm not quite sure your source code). find function which set "rx_done = 1". basically, the function is called when rx-dma is done. but rx_done is note turned into 1. so, which means dma is not done. why it is not done is ... DMA may not started. DMA may stuck in somewhere in your FPGA. - Altera_Forum
Honored Contributor
Hi, how to chase the status?
- Altera_Forum
Honored Contributor
I don't know why it happens.
but rx_done is not occurred anyway. you need to chase rx_done status. see you later.