I have GHRD and try to transfer data(0 to 127 count) from HPS RAM to FPGA OCRAM using HPS DMA.
When i look at result(showing on leds FPGA OCRAM contents) i must see leds showing 0 to 127.
But, something goes wrong and i see only 0 to 3. I guess there is zeros between numbers in FPGA OCRAM after transfer, because i see on leds 0-0-1-0-2-0-3.
And i dont know how many zeros between numbers.
But leds should show in that order: 0-1-2-3-4-5-…-127.
I cant find where i made mistake, please help me, i spend nearly 3 days, but it still dont work right way.
Maybe problem is that i use DMA wrong way?
P.s.: its bare-metal app, De1-SoC board
There is how i try to do this
firstly i setup dma:
indent preformatted text by 4 spaces
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[i] = ALT_DMA_SECURITY_DEFAULT;
}
for (int i = 0; i < 32; ++i)
{
dma_config.periph_sec[i] = ALT_DMA_SECURITY_DEFAULT;
}
for (int i = 0; i < 4; ++i)
{
dma_config.periph_mux[i] = 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 i try to make transfer:
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;
}
indent preformatted text by 4 spaces
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;
}