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.

Missing PWM updates using uDMA

I configured a DMA channel in scatter/gather to run a number of tasks, copying a table in memory and writing it to a PWM CMPA register. At the end of the table, an interrupt is generated to restart the process over.

By connecting a scope to the PWM output pin and manipluating the input table (the one get copied to the PWM CMPA register), I can see if all the updates are happing or not.

Since DMA can't get triggered by a PWM event, it is triggered by an edge event on the GPIO pin that is configured as a PWM. The PWM is set to update immediately (I.E. not sync to counter equal to 0).

By looking at the scope I can see that some of the table entries are not affecting the PWM output.

I originally had the GPIO configured to trigger on the falling edge but I changed it to the rising edge. This gives the DMA more time to copy the next table value to the PWM. This seems to work in a limited test situation. However, it indicates that it takes a not so insignificant amount of time for the GPIO to trigger the DMA to execute the next DMA task and for that task to actually copy a new value to the PWM. I would have thought this would happen in only several cycles (80MHz MCU = 12.5ns) but it seems to take a lot more. Something on the order of microseconds.

When I switched to rising edge, giving more time before the next PWM cycle, it worked better.

Is DMA in scatter/gather mode with a GPIO trigger that slow? Or am I still missing something?

Thanks

 

  • Hello Maxpower,

    What is PWM Frequency? Also what is the CPU state when the update is happening. Is it in WFI state or polling some flag?

    Regards
    Amit
  • PWM frequency is 480KHz
    The CPU does not interact with DMA or PWMs at all except when the DMA transfer tasks are complete, and interrupt restarts the DMA to execute the tasks again.
  • Is there any information on how long it takes an interrupt to trigger uDMA and for that uDMA to move just 1 32 bit value using scatter-gather mode?

    Thanks

  • Hello Maxpower,

    From the time the signal level changes, it takes 2-3 clocks of synchronization before the Interrupt is asserted. Then it takes a ~8 clock cycles for the CPU to recognize the interrupt and get to the interrupt handler (assuming no prefetch). After that depending on the manner the interrupt handler is interrupt there would be a certain number of clocks for the execution to reach DMA trigger.

    This all can be found by toggling a GPIO in the same place as the DMA trigger and measuring the time from the PWM edge to the GPIO toggle. Once the DMA request is asserted then it takes 6 clock cycles for the DMA to commence the data transfer if it is Idle.

    Now looking at the previous post 480KHz PWM is workable with the DMA. Can you probably the share the simplified code so that I can test it on a LaunchPad

    Regards
    Amit
  • Amit,

        Thank you for the information. Unfortunately I can't share code (ITC restrictions).

    Adding up all the cycles you describe, this should not be an issue.

    In my case, the interrupt handler does not get executed until after all the tasks in the scatter-gather mode are complete.

    The delay from the PWM edge, to GPIO trigger, to DMA primary channel copying the next task to the alternate channel and executing it seems to take somewhere between 1.25us and 2.5us. Given that this is an 80MHz proc with a 12.5ns cycle time, that is more than 1200 cycles!

    Additionally, since DMA seems to be taking too long, the interrupt does not happen in time to restart the DMA tasks before the next PWM period. So the last pwm value is repeated.

    I improved things a little by switching to down count PWM so the edge happens at the beginning of the PWM period giving the entire time for the next DMA task to run. I am still having an issue with the last task, which triggers the interrupt. It

    Thanks

  • Hello Maxpower,

    The delay of 1.25us-2.5us is not possible. As a simple experiment you may want to instead use the DMA to set a GPIO pin that can be used to measure the time difference. I reckon it is not going to be 1.25us but lesser than that.

    Since you cannot share the project code: I would ask you to create a simpler code which does the same operation and send that to us.

    Regards
    Amit
  • Amit,

    I agree, it can't be that long.

    Assuming that the DMA is fast enough to transfer a new compare value before the next period, can you think of a scenario where a uDMA task does not execute or the PWM compare value is kept from updating for some reason?

    I would like to try to set up the GPIO test you propose to do the timing. For now, I am assuming it is fast enough. There must be another issue.

    Thanks for your help!
  • Hello Maxpower,

    Without seeing the configuration code for PWM (at least) I can't say for sure. You have to give me something to work with here.

    Regards
    Amit
  • @Maxpower,

    Like you - I'm a client user - and it appears (almost) that you are asking Amit to, "Prove a negative."    As you know - that's most difficult.

    You've made certain considered assumptions - it is unlikely that Amit (or multiple others) can fully anticipate these - thus your seeking further assistance - without properly "bounding or broadly describing your methods" - immensely complicates & extends Amit's job...

  • @cb1 - I appreciate that. I know it is hard. I am new to this chip but have a short deadline to get things working. I am just reaching out any way I can and dealing with the restrictions I have. I am the only embedded person here so no one else to talk to.

    I realize without code and being able to give specifics, there is only so much someone can do. I really appreciate all the help so far.

    Sometimes there are gotchas that the experts are aware of. I was just hoping one of those gotchas was a little more obvious in my case.

    Thanks
  • Hello Maxpower,

    Good point. Are you using the Synchronous update or Immediate update for the PWM Count Register Update?

    , always do appreciate your support on the forum.

    Regards
    Amit
  • Then a quick question in the hopes that it may spark something. I haven't used uDMA but took a quick scan to see how it prioritised and noted that the core has priority over the DMA. Which raises the question, are you certain the core is giving up access to the appropriate busses?

    Robert
  • Amit, the short answer is, I don't know. I have to admit I am a little confused how this chip does things (again, I am more familiar with C2000). According to the documentation, PWMnCTL only options are local sync and global sync. In this case, it is set to local sync. What register would configure it for immediate?

    Given the timing test (see below), I don't believe this is a PWM issue.

    I implemented your idea about updating a GPIO instead of a PWM so I could look at the timing. I can see that the uDMA is executing each task far quicker, as you said it would. Additionally, the ISR, after the last DMA task, is executed very soon after. So it is not a case where the DMA is taking too long to trigger events. However, there seems to be a delay of several microseconds from when the DMA is restarted (I am using MAP_uDMAChannelScatterGatherSet and MAP_uDMAChannelEnable). I can see several PWM cycles go by before it starts again.

    Thanks for all your help and insights!
  • Robert, I thought of this as well. I am not sure how to answer that yet. Up until I did the timing test that Amit suggested (that s having the DMA update a GPIO and comparing the PWM and GPIO), it appears the DMA is running quickly and keeping up. It looks like at the end of the cycle where it needs to be restarted, it takes several microseconds to restart. I am going to focus on this area next.

    Thanks!
  • Hello Maxpower,

    Again, it does come down to the PWM configuration. But from the description so far it seems to be all correct.

    Also if you can show from a scope plot of what the sequence must be and what is being on a scope it could be useful information as well.

    The last thing to check would be if the wrong value happens at the time when the DMA table is being re-initialized by the CPU

    Regards
    Amit
  • I recall from (several) reads of the µDMA chapter w/in the MCU Manual that it was complex - and in places seemed subject to interpretation - neither good for a new user - especially one under time constraint.

    While the entirety of a complete code block proves too much - might a much simpler, "Sequence of operations" be listed?   The intent is to offer (immediate) benefit to this poster - yet provide some beginning for the (future) APP Note - long needed - for the µDMA.

    The variance between, "time expected" and "time achieved" seems wide enough that an (incorrect or extra sequence) may be in play.   A proper sequence - which may then be "execution time" logged/mapped by poster & vendor expert - may be one method to (more quickly) resolve...  

  • Thank you everyone for taking the time to post and help me out.
    I made some progress today. I toggled a GPIO pin in the ISR to time how long it was taking to re-configure and re-start the uDMA channel to repeat the sequence to the PWM. It showed that is was taking a long time. I think I posted earlier about this. But at that point, I assumed it was the DMA taking a long time to re-start. However, I narrowed it down to a couple of things. The code is running out of FLASH, above 40MHz, so it is single cycle execution (like I had assumed). Additionally, the MPA_ routines supplied with TIVAWare are compiled for debug. There are quite a lot of ASSERT macros in the debug code. This is not helping. Going into this, I assumed the code was executing fast enough and that it was a configuration issue.
    I optimized the ISR by just doing the minimal re-configuration and directly writing to the hardware registers. It seems now the DMA channel is re-starting prior to the next PWM edge.
    This can further be optimized by executing this ISR out of RAM.
    It looks like it is working now.Again, thank you all for helping.
  • Hello Maxpower,

    Good debug. You may want to remove the ASSERT statements altogether since they would b more useful during development. The TM4C123 above 40Mhz uses wait state. At and below 40Mhz it is working in zero wait state mode.

    Regards
    Amit
  • No thanks earned - nor sought - by this reporter.   Yet good job on your part - and special thanks for providing the project's "history" and the good description of how you've "resolved."

    In a (mythical) "perfect world" - some listing of (usual) sequence calls and their (expected) execution times may, "Speed, Ease & Enhance" poster development efforts... In the uber demanding case of µDMA - such "detail" may prove of very high value...