Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
12748 Discussions

DMA - memory to memory writing problem..

Altera_Forum
Honored Contributor II
1,245 Views

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; }
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
544 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
544 Views

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; }
0 Kudos
Reply