mimxrt/hal/pwm_backport: Make PWM symmetric, and round division calcs.

Ensure the symmetry of PWM: the duty rate of X and Q channels was not 50%,
when it should have been.  That is evident at high frequencies, like 15Mhz
or 37.5 MHz.  At low frequencies the deviation mattered less.  The A/B
channels were fine.

Also round up or down non-integer division factors. Before, always the
floor value was used.
pull/8401/head
robert-hh 2022-02-25 20:18:24 +01:00 zatwierdzone przez Damien George
rodzic 4774501cab
commit e0b97013d0
1 zmienionych plików z 4 dodań i 4 usunięć

Wyświetl plik

@ -53,7 +53,7 @@ void PWM_SetupPwm_u16(PWM_Type *base, pwm_submodule_t subModule, pwm_signal_para
// Divide the clock by the prescale value
pwmClock = (srcClock_Hz / (1U << ((base->SM[subModule].CTRL & PWM_CTRL_PRSC_MASK) >> PWM_CTRL_PRSC_SHIFT)));
pulseCnt = pwmClock / pwmFreq_Hz;
pulseCnt = (pwmClock + (pwmFreq_Hz - 1) / 2) / pwmFreq_Hz;
base->SM[subModule].INIT = 0;
base->SM[subModule].VAL1 = pulseCnt - 1;
@ -93,9 +93,9 @@ void PWM_SetupPwmx_u16(PWM_Type *base, pwm_submodule_t subModule,
// Divide the clock by the prescale value
pwmClock = (srcClock_Hz / (1U << ((base->SM[subModule].CTRL & PWM_CTRL_PRSC_MASK) >> PWM_CTRL_PRSC_SHIFT)));
pulseCnt = pwmClock / pwmFreq_Hz;
pulseCnt = (pwmClock + (pwmFreq_Hz - 1) / 2) / pwmFreq_Hz;
base->SM[subModule].INIT = 0;
base->SM[subModule].VAL0 = ((uint32_t)duty_cycle * pulseCnt) / PWM_FULL_SCALE;
base->SM[subModule].VAL0 = ((uint32_t)duty_cycle * pulseCnt) / PWM_FULL_SCALE - 1;
base->SM[subModule].VAL1 = pulseCnt - 1;
base->SM[subModule].OCTRL = (base->SM[subModule].OCTRL & ~PWM_OCTRL_POLX_MASK) | PWM_OCTRL_POLX(!invert);
@ -137,7 +137,7 @@ status_t QTMR_SetupPwm_u16(TMR_Type *base, qtmr_channel_selection_t channel, uin
}
// Counter values to generate a PWM signal
periodCount = (srcClock_Hz / pwmFreqHz) - 1;
periodCount = ((srcClock_Hz + (pwmFreqHz - 1) / 2) / pwmFreqHz) - 2;
highCount = (periodCount * dutyCycleU16) / PWM_FULL_SCALE;
lowCount = periodCount - highCount;