Forum Discussion

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

DMA Transfer problem

Hi,

I am trying to do a simple DMA mem to mem transfer as per the "Chap24: DMA controller core " example.

I have been at this for almost a week now and it is still not working for me. Can you please help me.

The dma transfer is getting stuck in the "while(!txrx_done)" loop. I am not getting any error messages.

Here is the status of my registers just before it enters the "while loop".

readaddress =800000, writeaddress =801000, length =80, status =2, control =fc

Here are the details of my setup:

I am using the DE2 board.

First in Qsys: DMA Controller

DMA Read Master -> SDRAM Controller slave

DMA Write Master -> SDRAM Controller slave

DMA Control-port Slave-> CPU Data Master

niosii code:

staticvolatileint txrx_done = 0;

static

void txrxdone(void * handle, void * data)

{

txrx_done = 1;

}

init code:

alt_dma_txchan txchan;

alt_dma_rxchan rxchan;

alt_u32* tx_data = (alt_u32*)0x800000;

alt_u32* rx_buffer = (alt_u32*)(0x801000);

// Create the transmit channel

if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == NULL)

{

printf ("Failed to open transmit channel\n");

exit (1);

}

// Create the receive channel

if ((rxchan = alt_dma_rxchan_open("/dev/dma_0")) == NULL)

{

printf ("Failed to open receive channel\n");

exit (1);

}

setting up transfer:

printf("Setting up DMA\n");

// Post the transmit request

if ((rc1 = alt_dma_txchan_send (txchan,

tx_data,

128,

NULL,

NULL)) < 0)

{

printf ("Failed to post transmit request, reason = %i\n", rc1);

exit (1);

}

&#12288;

if ((rc1 = alt_dma_rxchan_prepare (rxchan,

rx_buffer,

128,

txrxDone,

NULL)) < 0)

{

printf ("Failed to post read request, reason = %i\n", rc1);

exit (1);

}

while (!txrx_done);

printf ("Transfer successful!\n");

Please help!

14 Replies

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

    After you have a minimal system, if you still see the problem I would simulate the software running on the CPU. You might see something in the simulation that will give you a clue as to what is happening.

    Another thing you could try is using the macro file from the DMA driver and write the source, destination, and control fields directly to see if the behavior is any different. I forget what the file is called but it will probably be something like "altera_dma_regs.h".
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Created a minimal system. And used direct commands as you suggested.

    Still no luck :(. No clue on what's going on! I will try to simulate it next.

    I have attached the Qsys screen shot.

    IOWR_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE, 0x00);

    IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_0_BASE, SDRAM_0_BASE);

    IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_0_BASE, SDRAM_0_BASE+0x1000);

    IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_0_BASE, 128);

    IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_0_BASE, 0x008C);

    printf("Setting up DMA\n");

    while (!(IORD_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE)==0));

    &#12288;

    printf ("Transfer successful!\n");

    Results on the console:

    Setting up DMA

    readaddress =800000, writeaddress =801000, length =80, status =2, control =8c

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

    After you write the control register I would expect the status register bits [1:0] to be non-zero (either busy transferring or done). As a result you have while (!(non_zero_value == 0)); .... or in other words an infinite loop. You should mask the busy bit and keep looping until it is set:

    while ( ((IORD_ALTERA_AVALON_DMA_STATUS(DMA_0_BASE) & ALTERA_AVALON_DMA_STATUS_DONE_MSK) != ALTERA_AVALON_DMA_STATUS_DONE_MSK ) {

    // spin

    }

    If that software change still doesn't work run it in the simulation since it'll be easier to debug with the driver out of the way.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I was able to make the code work on an old Nios II devlopement Kit

    Cyclone II edition.

    Thsi means that the problem is probabily related to hardware or Qsys in the DE2 board. It is strange I am able to read and write but DMA access does not work. I will investigate that further.