- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
}
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
}

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page