Forum Discussion

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

problem of DMA(Momery to memory)

#include"system.h"# include<stdio.h># include"altera_avalon_dma_regs.h"# include"altera_avalon_pio_regs.h"# include"alt_types.h"

alt_u8 tab[8]={'a','b','c','d','e','f','g','h'},des[8];

alt_u32 flag;

int main()

{

IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE,0X00);

IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE,tab);

IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE,des);

IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE,8);

IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE,0X289);

while(1)

{

if(0X01&IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE))

{

IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE,des[1]);

}

}

return 0;

}

the DMA seems to work,the LEN AND DONE of status register are set to 1,

but the des[8] did not receive anything from tab[8].

6 Replies

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

    How do you check the contents of des? Does your CPU have a data cache? In that case you need to bypass the cache to read des.

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

    yes,i have data cache.if i amend the code like this:

    if(0X01&IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE))

    {

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE,tab[1]);

    }

    the IO is working.

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

    Oh sorry, I didn't see the des in your IOWR macro.

    The problem if you read directly des[x] is that the data will be read from the data cache instead of main RAM, and the cache isn't updated by the DMA. One way to get around it is to use the remap function. This should work:

    #include"system.h"
    # include<stdio.h>
    # include"altera_avalon_dma_regs.h"
    # include"altera_avalon_pio_regs.h"
    # include"alt_types.h"
    #include "sys/alt_cache.h"
    alt_u8 tab={'a','b','c','d','e','f','g','h'},des;
    alt_u32 flag;
    int main()
    {
      alt_u8 *uncached_des = (alt_u8*) alt_remap_uncached(des,8);
      IOWR_ALTERA_AVALON_DMA_STATUS(DMA_BASE,0X00);
      IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_BASE,tab);
      IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_BASE,des);
      IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_BASE,8);
      IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE,0X289);
      while(1)
      {
        if(0X01&IORD_ALTERA_AVALON_DMA_STATUS(DMA_BASE))
        {
          IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE,uncached_des);
        }
      }
      return 0;
    }
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    After reading your control register, I saw that you enabled the WCON bit. You shouldn't enable it, the DMA musn't always write to the same address. Try this:

    IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_BASE,0X89);

    If it stills doesn't work, you should put a signaltap probe and see what the controller is doing.