Altera_Forum
Honored Contributor
16 years agoDMA transfer called from PIO ISR
Hi,
I want to test DMA transfer from memory to memory. I tried to use MemTest example design to do it. Everything is ok when I call this funcion once - in main(). But when I try to trigger DMA transfer from PIO ISR - nothing happens. It looks like PIO ISR is not even called, because I can't see a text which should appear or flashing LED. When I comment the line where DMA transfer function is called, everything works (everything but DMA of course). MemDMATest - does dma transfer dma_done - dma irq isr handle_button_interrupts - PIO irq isr init_button_pio - registers and configures PIO irq Here is my code: <div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'># include <stdio.h># include <alt_types.h># include <io.h># include <string.h># include "altera_avalon_pio_regs.h"# include "sys/alt_irq.h"# include "system.h"# include "sys/alt_dma.h"# include "sys/alt_cache.h"# include "alt_types.h"# include "io.h" volatile int edge_capture; volatile int led=1; # define src (volatile char*) 0x02101100# define target (volatile char*) 0x02101080 static volatile int rx_done = 0; static volatile int rx_done_bak = 0; static void dma_done (void* handle, void* data) { rx_done_bak++; rx_done=rx_done_bak; } static int MemDMATest(unsigned int memory_base) { int rc; alt_dma_txchan txchan; alt_dma_rxchan rxchan; if ((txchan = alt_dma_txchan_open("/dev/dma")) == NULL) { exit (1); } printf("TXCHAN opened..."); if ((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL) { exit (1); } if ((rc = alt_dma_txchan_send (txchan, src, 4, NULL, NULL)) < 0) { exit (1); } if ((rc = alt_dma_rxchan_prepare (rxchan, target, 4, (alt_rxchan_done*)dma_done, NULL)) < 0) { exit (1); } while (!rx_done); rx_done = 0; alt_dma_txchan_close(txchan); alt_dma_rxchan_close(rxchan); return 0; } static void handle_button_interrupts(void* context, alt_u32 id) { /* cast the context pointer to an integer pointer. */ volatile int* edge_capture_ptr = (volatile int*) context; /* * Read the edge capture register on the button PIO. * Store value. */ if(led==1) led=0; else led=1; IOWR_32DIRECT(LEDS_PIO_BASE,0,led); *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(BUTTONS_PIO_BASE); /* Write to the edge capture register to reset it. */ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTONS_PIO_BASE, 0); /* reset interrupt capability for the Button PIO. */ IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTONS_PIO_BASE, 0xf); usleep(500000); printf("Start"); MemDMATest(SRAM_16BIT_512K_0_BASE); printf("Test: OK"); } static void init_button_pio() { /* Recast the edge_capture pointer to match the alt_irq_register() function prototype. */ void* edge_capture_ptr = (void*) &edge_capture; /* Enable all 4 button interrupts. */ IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTONS_PIO_BASE, 0xf); /* Reset the edge capture register. */ IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTONS_PIO_BASE, 0x0); /* Register the ISR. */ alt_irq_register( BUTTONS_PIO_IRQ, edge_capture_ptr, handle_button_interrupts ); } int main() { printf("Start...\n"); init_button_pio(); while(1); return 0; }</div>