This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Setting up EDMA for periodic triggering

Hi all,

I'd like to know if there are any available examples showing how to setup a DMA transfer using the EDMA controller, and prepare it to be periodically-triggered, such as timer based.


If you can point to some examples or application notes that would be great.


Thanks a lot!
Ezequiel

  • Hi Ezequiel,

    Which processor are you asking about? There are a lot of posts on EDMA on this forum. You can browse through them by using the "Search Community" tool located on top right of the forum page.

  • This is a very complex task.

    First of all, not all timers are able to trigger EDMA. There is no errata for this problem. TI has not checked all 96 possible EDMA event inputs.

    I have used DMTIMER 4. It works. Timer 3 does not work. Timer 0 runs only with the RC oscillator.

    Second, the timer triggers a EDMA channel which is set up to reset the DMA event from the timer.

    You have to write 2 timer registers in order to enable the second EDMA event:

    - 0x07 into the IRQSTATUS register (reset IRQ flags)

    - 0x00 into the IRQ_EOI register.

    From this DMA channel, use chaining to trigger a second DMA channel which is doing the "real work":

    regards

    Wolfgang

  • Hi Wolfgang,

    Thanks a lot for your reply. I've done some of this, but I'm still working on it. Given I'm working on Linux (mainline-based) I'm using the dmtimer and the EDMA APIs.

    So far, I've been able to trigger a mem2mem DMA transfer, triggered by the timer4 interrupt. I'm still working on this, given I need to prepare a periodic trigger with no CPU intervention, to copy from an incremental memory source, to a fixed MMIO destination. I'm not sure this is possible, but so far I'm making progress. The goal is to implement a PWM-based audio driver.

    Regarding your reply, you confused me a bit about this two chained DMA channels. Why do you need two?
    Do you have some test code so I can take a look?

    BTW: If anyone needs some Linux-based example, I can post some of mine.

    Thanks a lot!
    Ezequiel

  • You need 2 DMA channels.

    If Timer 4 is triggering a EDMA event, you have to RESET this event. If the event is not reset, there is only 1 trigger. But you want N triggers. So you have to reset the event source. You need a DMA channel for this. You have to clear 2 registers of the timer. The channel is set up: source = memory filled with the required values (0x07, 0). And the destination increment is set up to be the difference of the register addresses.

    If you do it right, you will have a continous stream of trigger events from the timer to the EDMA.

    And for doing the "real work", you use DMA chaining to another channel.


    My "test code" is a very complex DMA machine, doing LED pwm, SPI, and keyboard scanning all by DMA. It's confusing.

    regards

    Wolfgang

  • Hi Wolfgang,

    Thanks for the explanation. I know managed to prepare two chained DMA transfers, the first to clear the timer IRQ status and EOI registers, and the second one to do the real work.

  • Wolfgang Muees1 said:

    You need 2 DMA channels.

    If Timer 4 is triggering a EDMA event, you have to RESET this event. If the event is not reset, there is only 1 trigger. But you want N triggers. So you have to reset the event source. You need a DMA channel for this. You have to clear 2 registers of the timer. The channel is set up: source = memory filled with the required values (0x07, 0). And the destination increment is set up to be the difference of the register addresses.



    In fact, I'm using 3 DMA channels. The first DMA transfer is triggered by the timer IRQ, and writes the IRQ_STATUS timer register (offset 0x28 in the AM33xx), which clears the pending IRQ status.

    Then, the second DMA clears the timer register IRQ_EOI (0x20 in the AM33xx), which allows to trigger another DMA event.

    The third DMA is where the real work happens.

    In my tests, I observed that the writes to the IRQ_STATUS and IRQ_EOI *must* be done in the right order. Otherwise, if the IRQ_EOI is cleared before the IRQ_STATUS, a second DMA event will be queued, given there's still a pending IRQ. Therefore, I need to use one DMA channel for each of these registers.

    I'm wondering if this is correct, given it sounds like a lot of overhead, to be wasting three channels just to accomplish a simple periodic DMA transfer. Given the complexity of this EDMA controller, I think users would benefit from having a few code samples to show how EDMA works in complex scenarios (beyond the silly mem2mem manual triggered sample that's currently available).

  • You only need 1 DMA channel for the timer.

    The address offset is a SIGNED integer., so you can put 0x20-0x28 = -8 into the offset.

    regards

    Wolfgang

  • Yes, that worked. I prepared an AB-sync transfer with a negative offset between destination arrays in a frame to write to offset 0x28 first and offset 0x20 later.


    Thanks again for all the help!

  • Hi Wolfgang,

    You said timer 3 does not work : what does not work ?

    Because I made some change in the files :

    arch/arm/mach-omap2/devices.c -> DMA event from the timer 3 is cross mapped
    arch/arm/mach-omap2/omap_hwmod_33xx_data.c -> define that timer 3 has EDMA resource

    And I receive the DMA request from the timer.

    I only have 2 problems :

    - I must initialise and start the timer 2 times so that it generate the interrupt.

    - I have a strange effect, when I remove the SD card from my system, then I become also DMA request from the timer ...

    When you said that the timer 3 don't work, what is the problem from your side ?

    Thank

    Best regards

    Catherine

  • Catherine,

    With timer 3, I have problems to get the DMA event from the timer.

    I switched to timer 4 and did not examine the timer 3 problem any deeper.

    regards

    Wolfgang

  • Wolfgang,

    Thank you for the response !

    regards

    Catherine