If anyone else is running into this issue, I've worked around it for now by:
- Make 2 duplicate independent waveforms, instead of complimentary
- Make the one channel HIGH on active and the other LOW on active
- Simulate a deadtime by making the duty cycle of one channel (deadtime ticks * 2) longer (I'm not sure if this is enough to work for edge-aligned waveforms, I use center-aligned)
- After enabling FRCTRL somewhere, set FRACVAL3 (dither for channel A) and FRACVAL5 (dither for channel B) in PWM_UpdatePwmDutycycleHighAccuracy
// During the integer division to calculate pwmHighPulse,
// any remainder was simply discarded and cut off during rounding down.
// lost_precision is the remainder that was cut off.
const double lost_precision = ((pulseCnt * dutyCycle) - (pwmHighPulse * 65535U)) / pulseCnt;
// Section 3.2.6 Fractional delay logic
// FRACVAL3 is, every pulseCnt pulses, how many pulses we want on for an extra clock tick
// NOTE: Yes, this also loses precision, but less than if we did nothing.
// We can only dither the nearest 1/pulseCnt precision, unless we use adjust
// FRACVAL3 every pulseCnt strategically.
// lost_precision / (((1 / pulseCnt) / pulseCnt)(65535)) =
// lost_precision * pulseCnt * pulseCnt / 65525
base->SM[subModule].FRACVAL3 = PWM_FRACVAL3_FRACVAL3((pulseCnt * pulseCnt * lost_precision) / 65535U);
base->SM[subModule].FRACVAL5 = PWM_FRACVAL5_FRACVAL5((pulseCnt * pulseCnt * lost_precision) / 65535U);
Thought I'd share, although not using a workaround would be ideal, thanks!