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++

Need helpl with DMA

Altera_Forum
Honored Contributor II
1,175 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