Forum Discussion

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

DMA - memory to memory writing problem..

hi folks,

i want to write data from one address to an other via dma like in the code below, problem is, it doesn't work. first i use the macros to set the addresses and the length and then i set the byte mask and the go mask. did i forget anything?

thanks for your help

------------------


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "sys/alt_dma.h"
#include "system.h"
#include "altera_avalon_dma_regs.h"
 
/* Callback function that obtains notification that the data is received.*/
 
int
 
 
main (void)
 
{
 
int i=0;
char sMSG_tx,sMSG_rx;
memset(sMSG_rx,0,sizeof(sMSG_rx));
memset(sMSG_tx,0x55,sizeof(sMSG_tx));
for(i=0;i<8;i++)
{
printf("%d",sMSG_tx);
}
printf("\n");
for(i=0;i<8;i++)
{
printf("%d",sMSG_rx);
}
printf("\n");
/*initialize*/
IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_RS485_BASE,(
 
 
 
int) sMSG_tx); 
 
IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_RS485_BASE, (int)sMSG_rx); 
IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_RS485_BASE, 8); 
IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_RS485_BASE, ALTERA_AVALON_DMA_CONTROL_BYTE_MSK | ALTERA_AVALON_DMA_CONTROL_GO_MSK); 
while(1)
{ 
if(IORD_ALTERA_AVALON_DMA_STATUS(DMA_RS485_BASE) & (ALTERA_AVALON_DMA_STATUS_DONE_MSK))
{ 
for(i=0;i<8;i++)
{
printf("%d",sMSG_tx);
}
printf("\n");
for(i=0;i<8;i++)
{
printf("%d",sMSG_rx);
}
break;
}
}
return 0;
}
 
 
 

2 Replies

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

    1) Indent your code.

    2) The nios cpu is probably repeatedly reading the data from its cache, you need to either invalidate the relevant cache lines or do uncached reads.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    We solved the problem. After checking the system in Quartus, we saw, that the SD-RAM we used wasn't directly connected with the CPU1. We use an Cyclon3 with 2 CPU and it seems, that this was the Problem. After adding an On-Chip-Memmory and using this, or changing the accessed memmory to S-RAM it worked. For anybody who try to work with DMA and also has some problems dealing with the code, here is our working example without HAL.

    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include "sys/alt_dma.h"
    #include "system.h"
    #include "altera_avalon_dma_regs.h"
    #include "alt_types.h"
    #include "sys/alt_irq.h"
     
    static int dma_done=0,TX,RX;
     
    static void doneDMA(void* context , alt_u32 id)
    {
     usleep(10);
     dma_done++;
     IOWR_ALTERA_AVALON_DMA_STATUS(DMA_RS485_BASE, 0); 
    }
     
    int Init(void)
    {
     IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_RS485_BASE,
     ALTERA_AVALON_DMA_CONTROL_BYTE_MSK| 
     ALTERA_AVALON_DMA_CONTROL_LEEN_MSK|
     ALTERA_AVALON_DMA_CONTROL_I_EN_MSK);
     alt_irq_register(DMA_RS485_IRQ,(void*) NULL,doneDMA);
     return 0;
    }
     
    void Transfer(int where,int from,int howmuch)
    {
     dma_done=0;
     while ((IORD_ALTERA_AVALON_DMA_STATUS(DMA_RS485_BASE) &
      ALTERA_AVALON_DMA_STATUS_BUSY_MSK));
     IOWR_ALTERA_AVALON_DMA_STATUS(DMA_RS485_BASE, 0);
     IOWR_ALTERA_AVALON_DMA_LENGTH(DMA_RS485_BASE, howmuch);
     IOWR_ALTERA_AVALON_DMA_RADDRESS(DMA_RS485_BASE,(int) from);
     IOWR_ALTERA_AVALON_DMA_WADDRESS(DMA_RS485_BASE,(int) where);
     IOWR_ALTERA_AVALON_DMA_CONTROL(DMA_RS485_BASE,
      ALTERA_AVALON_DMA_CONTROL_GO_MSK |
      IORD_ALTERA_AVALON_DMA_CONTROL(DMA_RS485_BASE)); 
    }
     
    void MemInit(int base_addr,int len, int value)
    {
     int i;
     for (i=0;i<len;i++)
      IOWR_8DIRECT(base_addr,i,value);
    }
     
    int main(void)
    {
     MemInit((int)RX,0x10,3);
     MemInit((int)TX,0x10,6);
     Init();
     Transfer((int)RX,(int)TX,16);
     while(!dma_done);
     return 0; 
    }