Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

DMA 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>

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    OK.I have my problem resolved by re-enabling interrupt in the PIO ISR... using alt_irq_enable_all().