Skip to content

Commit

Permalink
mimxrt/hal/pwm_backport: Make PWM symmetric, and round division calcs.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
robert-hh authored and dpgeorge committed Mar 8, 2022
1 parent 4774501 commit e0b9701
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions ports/mimxrt/hal/pwm_backport.c
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit e0b9701

Please sign in to comment.