Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
762 Views

SGDMA async transfer fails

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; 

simulink_streamout_dma_controller=alt_avalon_sgdma_open(SIMULINK_STREAMOUT_DMA_NAME); 

 

// 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) | 

ALTERA_AVALON_SGDMA_CONTROL_CLEAR_INTERRUPT_MSK ) ); 

// get current control base 

ctrl_reg_dma = IORD_ALTERA_AVALON_SGDMA_CONTROL(simulink_streamout_dma_controller->base); 

// add interrupt masks 

ctrl_reg_dma |= ALTERA_AVALON_SGDMA_CONTROL_IE_DESC_COMPLETED_MSK | 

ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK; 

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

sgdma_out_finished=0; 

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); 

IOWR_32DIRECT(LED_BLINKER_BASE, 0x4, BYTES_TO_TRANSFER); 

// start transfer 

IOWR_32DIRECT(LED_BLINKER_BASE, 0x0, 0x1); 

:
0 Kudos
2 Replies
Altera_Forum
Honored Contributor I
35 Views

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.

Altera_Forum
Honored Contributor I
35 Views

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

Reply