ports: Make PWM duty_u16 have an upper value of 65535 across all ports.

The following ports used 65536 as the upper value (100% duty cycle) and are
changed in this commit to use 65535: esp8266, mimxrt, nrf, samd.

Tested that output is high at `duty_u16(65535)` and low at `duty_u16(0)`.
Also verified that at `duty_u16(32768)` the high and low pulse have the
same length.

Partially reverts #10850, commits 9c7ad68165
and 2ac643c15b.

Signed-off-by: robert-hh <robert@hammelrath.com>
This commit is contained in:
robert-hh 2024-11-04 16:04:56 +01:00 committed by Damien George
parent 5dc9eda195
commit 898407defb
7 changed files with 16 additions and 16 deletions

View file

@ -193,7 +193,7 @@ PWM Constructor
- *freq* should be an integer which sets the frequency in Hz for the
PWM cycle. The valid frequency range is 15 Hz resp. 18Hz resp. 24Hz up to > 1 MHz.
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65536``.
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65535``.
The duty cycle of a X channel can only be changed, if the A and B channel
of the respective submodule is not used. Otherwise the duty_16 value of the
X channel is 32768 (50%).
@ -231,7 +231,7 @@ is created by dividing the pwm_clk signal by an integral factor, according to th
f = pwm_clk / (2**n * m)
with n being in the range of 0..7, and m in the range of 2..65536. pmw_clk is 125Mhz
with n being in the range of 0..7, and m in the range of 2..65535. pmw_clk is 125Mhz
for MIMXRT1010/1015/1020, 150 MHz for MIMXRT1050/1060/1064 and 160MHz for MIMXRT1170.
The lowest frequency is pwm_clk/2**23 (15, 18, 20Hz). The highest frequency with
U16 resolution is pwm_clk/2**16 (1907, 2288, 2441 Hz), the highest frequency
@ -255,7 +255,7 @@ Use the :ref:`machine.ADC <machine.ADC>` class::
from machine import ADC
adc = ADC(Pin('A2')) # create ADC object on ADC pin
adc.read_u16() # read value, 0-65536 across voltage range 0.0v - 3.3v
adc.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v
The resolution of the ADC is 12 bit with 10 to 11 bit accuracy, irrespective of the
value returned by read_u16(). If you need a higher resolution or better accuracy, use

View file

@ -215,7 +215,7 @@ PWM Constructor
- *freq* should be an integer which sets the frequency in Hz for the
PWM cycle. The valid frequency range is 1 Hz to 24 MHz.
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65536``.
- *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65535``.
- *duty_ns* sets the pulse width in nanoseconds. The limitation for X channels
apply as well.
- *invert*\=True|False. Setting a bit inverts the respective output.
@ -246,7 +246,7 @@ Use the :ref:`machine.ADC <machine.ADC>` class::
from machine import ADC
adc0 = ADC(Pin('A0')) # create ADC object on ADC pin, average=16
adc0.read_u16() # read value, 0-65536 across voltage range 0.0v - 3.3v
adc0.read_u16() # read value, 0-65535 across voltage range 0.0v - 3.3v
adc1 = ADC(Pin('A1'), average=1) # create ADC object on ADC pin, average=1
The resolution of the ADC is 12 bit with 12 bit accuracy, irrespective of the

View file

@ -80,7 +80,7 @@ static void mp_machine_pwm_init_helper(machine_pwm_obj_t *self, size_t n_args, c
pwm_set_duty(args[ARG_duty].u_int, self->channel);
}
if (args[ARG_duty_u16].u_int != -1) {
pwm_set_duty(args[ARG_duty_u16].u_int * 1000 / 65536, self->channel);
pwm_set_duty(args[ARG_duty_u16].u_int * 1000 / 65535, self->channel);
}
if (args[ARG_duty_ns].u_int != -1) {
uint32_t freq = pwm_get_freq(0);
@ -164,13 +164,13 @@ static void mp_machine_pwm_duty_set(machine_pwm_obj_t *self, mp_int_t duty) {
static mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) {
set_active(self, true);
return MP_OBJ_NEW_SMALL_INT(pwm_get_duty(self->channel) * 65536 / 1024);
return MP_OBJ_NEW_SMALL_INT(pwm_get_duty(self->channel) * 65535 / 1024);
}
static void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty) {
set_active(self, false);
self->duty_ns = -1;
pwm_set_duty(duty * 1024 / 65536, self->channel);
pwm_set_duty(duty * 1024 / 65535, self->channel);
pwm_start();
}

View file

@ -36,7 +36,7 @@ void PWM_UpdatePwmDutycycle_u16(
// Setup the PWM dutycycle of channel A or B
if (pwmSignal == kPWM_PwmA) {
if (dutyCycle >= 65536) {
if (dutyCycle >= PWM_FULL_SCALE) {
base->SM[subModule].VAL2 = 0;
base->SM[subModule].VAL3 = pulseCnt;
} else {
@ -44,7 +44,7 @@ void PWM_UpdatePwmDutycycle_u16(
base->SM[subModule].VAL3 = base->SM[subModule].VAL2 + pwmHighPulse;
}
} else {
if (dutyCycle >= 65536) {
if (dutyCycle >= PWM_FULL_SCALE) {
base->SM[subModule].VAL4 = 0;
base->SM[subModule].VAL5 = pulseCnt;
} else {
@ -160,7 +160,7 @@ status_t QTMR_SetupPwm_u16(TMR_Type *base, qtmr_channel_selection_t channel, uin
if (dutyCycleU16 == 0) {
// Clear the output at the next compare
reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ClearOnCompare));
} else if (dutyCycleU16 >= 65536) {
} else if (dutyCycleU16 >= PWM_FULL_SCALE) {
// Set the output at the next compare
reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_SetOnCompare));
} else {

View file

@ -24,7 +24,7 @@ typedef struct _pwm_signal_param_u16
uint16_t deadtimeValue; // The deadtime value; only used if channel pair is operating in complementary mode
} pwm_signal_param_u16_t;
#define PWM_FULL_SCALE (65536UL)
#define PWM_FULL_SCALE (65535UL)
void PWM_UpdatePwmDutycycle_u16(PWM_Type *base, pwm_submodule_t subModule,
pwm_channels_t pwmSignal, uint32_t dutyCycle, uint16_t center);

View file

@ -285,7 +285,7 @@ static mp_obj_t mp_machine_pwm_duty_get(machine_pwm_obj_t *self) {
if (self->p_config->duty_mode[self->channel] == DUTY_PERCENT) {
return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel]);
} else if (self->p_config->duty_mode[self->channel] == DUTY_U16) {
return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel] * 100 / 65536);
return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel] * 100 / 65535);
} else {
return MP_OBJ_NEW_SMALL_INT(-1);
}
@ -301,7 +301,7 @@ static mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) {
if (self->p_config->duty_mode[self->channel] == DUTY_U16) {
return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel]);
} else if (self->p_config->duty_mode[self->channel] == DUTY_PERCENT) {
return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel] * 65536 / 100);
return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel] * 65535 / 100);
} else {
return MP_OBJ_NEW_SMALL_INT(-1);
}
@ -365,7 +365,7 @@ static void machine_hard_pwm_start(const machine_pwm_obj_t *self) {
if (self->p_config->duty_mode[i] == DUTY_PERCENT) {
pulse_width = ((period * self->p_config->duty[i]) / 100);
} else if (self->p_config->duty_mode[i] == DUTY_U16) {
pulse_width = ((period * self->p_config->duty[i]) / 65536);
pulse_width = ((period * self->p_config->duty[i]) / 65535);
} else if (self->p_config->duty_mode[i] == DUTY_NS) {
pulse_width = (uint64_t)self->p_config->duty[i] * tick_freq / 1000000000ULL;
}

View file

@ -54,7 +54,7 @@ typedef struct _machine_pwm_obj_t {
#define PWM_CLK_READY (1)
#define PWM_TCC_ENABLED (2)
#define PWM_MASTER_CLK (get_peripheral_freq())
#define PWM_FULL_SCALE (65536)
#define PWM_FULL_SCALE (65535)
#define PWM_UPDATE_TIMEOUT (2000)
#define VALUE_NOT_SET (-1)