Nios® II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.

Need helpl with DMA

Altera_Forum
Honored Contributor II
977 Views

Hi everyone, i need help with using DMA in bare-metal project.  

 

I have GHRD, and i need to transfer data (it just 0 to 127 count) from HPS RAM(as i understand from ftp://ftp.altera.com/up/pub/intel_material/16.1/tutorials/accessing_hps_devices_from_fpga.pdf , its address 0xffff0000) to FPGA OCRAM(its address 0xc0000000 in my system) using HPS DMA and then i show this data from FPGA OCRAM on LEDS(0xFF210040).  

 

But something goes wrong, and when i show data on leds, i see only 0-3 ,but it must be 0-1-2-3-4-..127. And leds are blinks(i see 0-0-1-0-2-0-3), so i think it is zeros between 0 and 1, 1 and 2, 2 and 3,... 

When i show on leds data direct from hps ram after initializing it, leds dont blink(i see 0-1-2-3-...-127)  

 

I really dont understand why that happens and i spend 3 days , but i still dont know what i do wrong.  

 

Please someone, help me to understand and fix it.  

 

 

 

firstly, i setup dma: 

ALT_STATUS_CODE socfpga_dma_setup(){ printf("INFO: Setup DMA System ...\n"); ALT_STATUS_CODE status = ALT_E_SUCCESS; if (status == ALT_E_SUCCESS) { // Configure everything as defaults. ALT_DMA_CFG_t dma_config; dma_config.manager_sec = ALT_DMA_SECURITY_DEFAULT; for (int i = 0; i < 8; ++i) { dma_config.irq_sec = ALT_DMA_SECURITY_DEFAULT; } for (int i = 0; i < 32; ++i) { dma_config.periph_sec = ALT_DMA_SECURITY_DEFAULT; } for (int i = 0; i < 4; ++i) { dma_config.periph_mux = ALT_DMA_PERIPH_MUX_DEFAULT; } status = alt_dma_init(&dma_config); if (status != ALT_E_SUCCESS) { printf("ERROR: alt_dma_init() failed.\n"); } } // Allocate the DMA channel if (status == ALT_E_SUCCESS) { status = alt_dma_channel_alloc_any(&channel); if (status != ALT_E_SUCCESS) { printf("ERROR: alt_dma_channel_alloc_any() failed.\n"); } else { printf("INFO: Channel %d allocated.\n", (int)(channel)); } } // Verify channel state if (status == ALT_E_SUCCESS) { ALT_DMA_CHANNEL_STATE_t state; status = alt_dma_channel_state_get(channel, &state); if (status == ALT_E_SUCCESS) { if (state != ALT_DMA_CHANNEL_STATE_STOPPED) { printf("ERROR: Bad initial channel state.\n"); status = ALT_E_ERROR; } } } if (status == ALT_E_SUCCESS) { status = alt_dma_program_init(&program); if (status != ALT_E_SUCCESS) { printf("ERROR: alt_dma_program_init() failed.\n"); } else { printf("INFO: Dma program_byffer initialized.\n"); } } if (status == ALT_E_SUCCESS) { printf("INFO: Setup of DMA successful.\n\n"); } else { printf("ERROR: Setup of DMA return non-SUCCESS %d.\n\n", (int)status); } return status; } 

 

 

then goes my main fuction: 

ALT_STATUS_CODE dma_hpsram_to_fpgaram(){ // Just base addresses of GHRD components const uint32_t ALT_LWFPGA_BASE = 0xFF200000; const uint32_t ALT_LWFPGA_LED_OFFSET = 0x00010040; const uint32_t ALT_H2F_BASE = 0xc0000000; const uint32_t ALT_H2F_OCRAM_OFFSET = 0x00000000; const uint32_t ALT_HPS_OCRAM = 0xffff0000; // turn off leds alt_write_word(ALT_LWFPGA_BASE + ALT_LWFPGA_LED_OFFSET, 0); uint32_t temp=0; uint32_t offset=0; // write 0-127 to hps ram for (uint32_t i = 0; i < 128; ++i) { alt_write_byte(ALT_HPS_OCRAM+offset,temp); temp++; offset=offset+1; } // transfer data from hps ram to fpga ocram size_t size=128; uint32_t dst=ALT_H2F_BASE+ALT_H2F_OCRAM_OFFSET; uint32_t src=ALT_HPS_OCRAM; // this function i take from altera design examples (hps dma) dma_memory_to_memory(&src, &dst, size); // check result of transfer, looking at fpga ocram contents offset=0; for (uint32_t i = 0; i < 12800000; ++i) { if(i%100000==0) { // that big numbers for making leds switch less often alt_write_byte(ALT_LWFPGA_BASE+ALT_LWFPGA_LED_OFFSET, alt_read_byte(dst+offset)); offset=offset+1; } } return ALT_E_SUCCESS; } 

 

 

it uses function from altera design examples( hps ram): 

ALT_STATUS_CODE dma_memory_to_memory(void * src, void * dst, uint32_t size) { ALT_STATUS_CODE status = ALT_E_SUCCESS; printf("INFO: Demo DMA memory to memory transfer.\n"); // Copy source buffer over destination buffer if(status == ALT_E_SUCCESS) { status = alt_dma_memory_to_memory(channel, &program, dst, src, size, false, (ALT_DMA_EVENT_t)0); } // Wait for transfer to complete if (status == ALT_E_SUCCESS) { printf("INFO: Waiting for DMA transfer to complete.\n"); ALT_DMA_CHANNEL_STATE_t channel_state = ALT_DMA_CHANNEL_STATE_EXECUTING; while((status == ALT_E_SUCCESS) && (channel_state != ALT_DMA_CHANNEL_STATE_STOPPED)) { status = alt_dma_channel_state_get(channel, &channel_state); if(channel_state == ALT_DMA_CHANNEL_STATE_FAULTING) { ALT_DMA_CHANNEL_FAULT_t fault; alt_dma_channel_fault_status_get(channel, &fault); printf("ERROR: DMA CHannel Fault: %d\n", (int)fault); status = ALT_E_ERROR; } } } return status; }
0 Kudos
0 Replies
Reply