Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

SGDMA register question

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

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

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

    Is the base address correct?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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