I have an application that needs to drive 16 PWM outputs at the same frequency but changing the duty cycle on each PWM independently. This is done by setting one of the DREQ_PWM_WRAPx bits in DREQ so that the DMA pulls a value from the buffer each time the PWM value needs to change. It also looks pretty easy to ping-pong buffers using chaining so that new data can be read, for instance, via the network interface. That's awesome and very cool the way you can have lots of complicated, non-deterministic timing software running but still have cycle perfect data transfers. Big points for the Pico here.
Unfortunately, there are 16 PWMs I need to control and only 12 DMA channels.
There also doesn't seem to be any way to set a stride on the DMA transfer to allow non-contiguous reads. If that were possible, I could set a stride of 16 and a ring counter to write to all of the A slices and have another transfer going through all of the B slices.
Is the correct approach here to use one DMA to drive another?
The idea would be to have a list of 16 PWM register addresses in a buffer. The first DMA would transfer these each time PWM0 wraps to the AL2_WRITE_ADDR_TRIG control register of a second DMA channel and then cycle back around. The second would use a free running READ address with a transfer size of 2 bytes and a count of 1. The duty cycle on all the PWMs would be reset each time the first one wraps around which might lead to a one cycle delay which I could not care less about.
Does this approach sound like it would work to read all of the PWM duty cycles from a single buffer?
Unfortunately, there are 16 PWMs I need to control and only 12 DMA channels.
There also doesn't seem to be any way to set a stride on the DMA transfer to allow non-contiguous reads. If that were possible, I could set a stride of 16 and a ring counter to write to all of the A slices and have another transfer going through all of the B slices.
Is the correct approach here to use one DMA to drive another?
The idea would be to have a list of 16 PWM register addresses in a buffer. The first DMA would transfer these each time PWM0 wraps to the AL2_WRITE_ADDR_TRIG control register of a second DMA channel and then cycle back around. The second would use a free running READ address with a transfer size of 2 bytes and a count of 1. The duty cycle on all the PWMs would be reset each time the first one wraps around which might lead to a one cycle delay which I could not care less about.
Does this approach sound like it would work to read all of the PWM duty cycles from a single buffer?
Statistics: Posted by tdunning — Wed Mar 27, 2024 1:59 am — Replies 0 — Views 22