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

SGDMA async transfer fails

Honored Contributor II

Hi guys, 


I'm creating a system on a cyclone3 development board. I also have a beMicro stick for testing. The system structure is based on the ethernet standard tutorial with QSYS. Then there is a custom component build with simulink, which i connected via DMA. As software template i use the altera webserver template. 


The code I'm using can't be that wrong, since the system works just fine on the beMicro stick(with webserver AND hello_world template). On the cyc3 board it works too, but only if i use the hello_world template as software template (hardware config is the same as with webserver). 


But using the webserver the buffer values, which should change due to the DMA transfer, just don't. The interrupts are triggered and everything looks fine, except the transfer obviously isn't performed. (that's for mem-to-stream) 

The stream-to-mem part is supposed to light up the std LEDs(0-7). Usually i get a nice running pattern. With the webserver template thought, I can see some LED action, but nothing remotely close to the pattern i programmed. 


Oh and there is one more thing. To get it all working in the first place, even on the other configurations I had to run a while loop to pause (about 3 sec) between the last buffer read/write and a async transfer. Increasing the wait time doesn't help with the config i need. 


Would be awesome if anybody has a clue how to get this running properly. 


Thanks in advance. 




here is the code i used for the mem-to-stream part: 


// DMA controller init 

struct alt_sgdma_dev *simulink_streamout_dma_controller; 



// create descriptor & terminate descriptor chain 

alt_avalon_sgdma_construct_stream_to_mem_desc(&simulink_descriptor, &terminating_descriptor, &dma_buffer, BYTES_TO_TRANSFER, 0x0); 

terminating_descriptor.control = terminating_descriptor.control & ~ALTERA_AVALON_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK; 


//register interrupt 

// set control base to stream in dev 

IOWR_ALTERA_AVALON_SGDMA_CONTROL(simulink_streamout_dma_controller->base, (IORD_ALTERA_AVALON_SGDMA_CONTROL(simulink_streamout_dma_controller->base) | 


// get current control base 

ctrl_reg_dma = IORD_ALTERA_AVALON_SGDMA_CONTROL(simulink_streamout_dma_controller->base); 

// add interrupt masks 



// assign handler to interrupt 

alt_avalon_sgdma_register_callback(simulink_streamout_dma_controller, &sgdma_out_interrupt_handler, 0, NULL); 

// set interrupt control 

IOWR_ALTERA_AVALON_SGDMA_CONTROL(simulink_streamout_dma_controller->base, ctrl_reg_dma); 

// get final control base 

ctrl_reg_dma = IORD_ALTERA_AVALON_SGDMA_CONTROL(simulink_streamout_dma_controller->base); 

printf("TX control after the initialization: %d\n", ctrl_reg_dma); 


// start non-blocking transfer 


if (alt_avalon_sgdma_do_sync_transfer(simulink_streamout_dma_controller, &simulink_descriptor) != 0) 

printf("\n Error starting TX transfer.\n\n"); 


// setup the number of symbols to transfer 

printf("Bytes to transfer: %d\n", BYTES_TO_TRANSFER); 


// start transfer 


0 Kudos
2 Replies
Honored Contributor II

How is dma_buffer defined and how do you fill it? If your CPU has a data cache you must remember to flush the data cache before you start the transfer, or use uncached memory accesses.

0 Kudos
Honored Contributor II

Great thanks ... that's it (flushing) ... works like a charm now .. even without that crappy while loop.

0 Kudos