Good day,
I’m developing the pulse generator for a 3-phase SCR rectifier. To guarantee that each thyristor gate (and its complementary clear) happens at the exact instants, I built an “edge buffer” that holds, for each edge in one mains period, the GPIO address to touch and the timer tick at which that action must occur.
The timebase is FTM3 running in output-compare with MOD = 15624 (one 0…MOD ramp per 60 Hz mains period). I use channel 6 as the event source. Every time CNT == C6V, the channel issues a DMA request; that request drives a scatter/gather (S/G) ring on DMA channel A that performs exactly one 32-bit write to the specific GPIO register (set or clear) for that edge. All S/G descriptors are linked in a circle, so the list advances one step per compare event, forever.
Immediately after each GPIO write, I must also program the next compare instant so the following edge lands at the correct tick. For that I added minor-loop channel linking: channel A is configured to minor-link to DMA channel B. Each time A completes its one-word GPIO write, it triggers B to perform one half/word write to FTM3->CONTROLS[6].CnV with the next value from a 12-element table. Channel B’s TCD is a simple cyclic transfer over that table, so it advances one entry per link and then wraps to the start for the next mains period.
It all sounds good to go, but the problem is that the CH6 events are cyclic at the same rate as the FTM 60 Hz. There are two issues: CnV is not being updated through this method, and if I manage to update it, the counter goes back to 0 when it should keep counting from where it was. Effectively what I want is to trigger 12 DMA requests on a single run of the timer from 0 to timer MOD, which so far I cannot. Using the CH6 interrupt and some code I can fix the issue, but CH6 is disabled by the DMA CH6 request.
I am attaching the code for now. Any experts, that could help on the CNV update issue?
Best regards.