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 register question

Altera_Forum
Honored Contributor II
1,597 Views

I am having some trouble implementing SGDMA. The problem appears to be that I cannot actually access the SGDMA controller core registers. On page 25-7 of http://www.altera.com/literature/ug/ug_embedded_ip.pdf it says that I should be able to read and write the registers. When I try to write the next_descriptor_register and read it back the value never changes, it is always 0. I have tried this with two SGDMA cores so far and both show the same result. 

 

Is this normal? 

 

Thanks, 

John
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
319 Views

What way are you using for accessing registers? HAL driver? IORD/IOWR? Pointers? 

Is the base address correct?
0 Kudos
Altera_Forum
Honored Contributor II
319 Views

There are two reasons for getting "0" from registers when reading 

1) When register has only write access 

2) When reg doesn't get enough time to flush out the data (condition  

dependent) 

 

Your case is second one. 

 

next_descriptor_register is equivalent to next_descriptor_pointer??? 

If yes,then when you are getting "0" value from that register,at that time,check the "Busy" bit of the status register,It should be "1" 

 

To read that register,Altera said in that document that first you write "0" on the "RUN" bit of the control register and then check (monitor-while loop) "busy" bit of the status register 

when it becomes zero,then u read "next_descriptor_pointer".Now it should give u some values as you are expected for your design. 

In short,Logic should be like this to read, 

 

run=0; 

while(busy!=0); 

temp_read=iord(<base_add>,reg_offset); 

 

Hope this info will help you
0 Kudos
Altera_Forum
Honored Contributor II
319 Views

If you are reading back the value you wrote then there is something at the requested address - so if you have the correct address, and have bypassed the data cache, then you should be accessing the dma controller's register. 

 

Can be worth checking by accessing a device register that will never return the written value (eg some bits read 0, or a 'write to clear' register).
0 Kudos
Altera_Forum
Honored Contributor II
319 Views

Sorry, should have been page 25-11 and yes I meant next_descriptor_pointer. There are two DMA controllers that I am testing with one controlled by the PCI Host and one controlled by a NIOS. I want to use the registers directly so that I can use similar code for both. The initialization for the NIOS controlled DMA is below. 

 

void dmaOutputInit() 

//clear the RUN bit in DMA_OUTPUT 

IOWR(DMA_OUTPUT_UCBASE, 1, 0x00000000); 

//wait for BUSY bit to clear 

while ((IORD(DMA_OUTPUT_UCBASE, 0)) & 0x00000010) 

//do nothing 

//set the next_descriptor_pointer in DMA_OUTPUT 

IOWR(DMA_OUTPUT_UCBASE, 2, (unsigned int)&dmaDescriptorTable[0]); 

//set the next_descriptor_pointer in the descriptor 

IOWR(&dmaDescriptorTable[0], 4, (unsigned int)&dmaDescriptorTable[0]); 

//set the destination* in the descriptor 

IOWR(&dmaDescriptorTable[0], 2, A_WR_CTRL + 4); 

//clear the OWNED_BY_HW in the descriptor 

IOWR(&dmaDescriptorTable[0], 7, 0); 

 

DMA_OUTPUT_UCBASE is the DMA_OUTPUT_BASE from the system.h file ored with 0x80000000 to bypass the cache. If I watch the memory in the memory viewer and step through the function with the debugger the registers never change.
0 Kudos
Altera_Forum
Honored Contributor II
319 Views

memory viewer ? 

Does that do cache bypass ?? 

 

Anything done through the JTAG interface is actually running code on the nios. 

 

If you have a PCI(e) slave interface that can be used to do direct avalon MM slave cycles.
0 Kudos
Altera_Forum
Honored Contributor II
319 Views

The memory viewer is in the NIOS II Debug Perspective under Window->Show View->Memory. It will show the memory at any address specified and update every time the NIOS is paused. I have watched the memory at DMA_OUTPUT_BASE and DMA_OUTPUT_UCBASE and all 3 registers stay 0.  

 

I believe that it should do cache bypass if the uncached address is specified. 

 

The PCI interface does not have DMA_OUTPUT_BASE mapped to a BAR, so I cannot use it for this DMA.
0 Kudos
Altera_Forum
Honored Contributor II
319 Views

I figured it out, Table 25-6 is listed as address offset in 32 bit data address offsets so the control register is located at byte address DMA_BASE + 16 and the next_descriptor_pointer register is at byte address DMA_BASE + 32. Thanks for all of the ideas. 

 

John
0 Kudos
Reply