Altera_Forum
Honored Contributor
14 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!why when i use my dma, the program stucks here:
--- Quote Start --- while (!rx_done); printf ("Transfer successful!\n"); --- Quote End --- pls help! thanks!I don't know why it happens.
but rx_done is not occurred anyway. you need to chase rx_done status. see you later.Hi, how to chase the status?
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.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!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?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.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.Since now you can write data at least in the first 64kb block of flash, you can test the dma transfer.
yes, but now i wish to test by using and without using dma, which is faster and better. so just 64KB of data is sufficient for this testing?
Single access to flash memory requires at least 60 to 120ns depending from your flash speed grade. then 64kb requires at least a few millisecs. The transfer time will certainly be longer (both with cpu and dma transfer) because of bus contention or other instrinsic delays.
Then, if you have a timer which can measure intervals in the ms range you can easily make the test with 64kb.