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 - *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. 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 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 of the respective submodule is not used. Otherwise the duty_16 value of the
X channel is 32768 (50%). 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) 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. 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 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 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 from machine import ADC
adc = ADC(Pin('A2')) # create ADC object on ADC pin 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 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 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 - *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. 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 - *duty_ns* sets the pulse width in nanoseconds. The limitation for X channels
apply as well. apply as well.
- *invert*\=True|False. Setting a bit inverts the respective output. - *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 from machine import ADC
adc0 = ADC(Pin('A0')) # create ADC object on ADC pin, average=16 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 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 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); pwm_set_duty(args[ARG_duty].u_int, self->channel);
} }
if (args[ARG_duty_u16].u_int != -1) { 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) { if (args[ARG_duty_ns].u_int != -1) {
uint32_t freq = pwm_get_freq(0); 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) { static mp_obj_t mp_machine_pwm_duty_get_u16(machine_pwm_obj_t *self) {
set_active(self, true); 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) { static void mp_machine_pwm_duty_set_u16(machine_pwm_obj_t *self, mp_int_t duty) {
set_active(self, false); set_active(self, false);
self->duty_ns = -1; self->duty_ns = -1;
pwm_set_duty(duty * 1024 / 65536, self->channel); pwm_set_duty(duty * 1024 / 65535, self->channel);
pwm_start(); pwm_start();
} }

View File

@@ -36,7 +36,7 @@ void PWM_UpdatePwmDutycycle_u16(
// Setup the PWM dutycycle of channel A or B // Setup the PWM dutycycle of channel A or B
if (pwmSignal == kPWM_PwmA) { if (pwmSignal == kPWM_PwmA) {
if (dutyCycle >= 65536) { if (dutyCycle >= PWM_FULL_SCALE) {
base->SM[subModule].VAL2 = 0; base->SM[subModule].VAL2 = 0;
base->SM[subModule].VAL3 = pulseCnt; base->SM[subModule].VAL3 = pulseCnt;
} else { } else {
@@ -44,7 +44,7 @@ void PWM_UpdatePwmDutycycle_u16(
base->SM[subModule].VAL3 = base->SM[subModule].VAL2 + pwmHighPulse; base->SM[subModule].VAL3 = base->SM[subModule].VAL2 + pwmHighPulse;
} }
} else { } else {
if (dutyCycle >= 65536) { if (dutyCycle >= PWM_FULL_SCALE) {
base->SM[subModule].VAL4 = 0; base->SM[subModule].VAL4 = 0;
base->SM[subModule].VAL5 = pulseCnt; base->SM[subModule].VAL5 = pulseCnt;
} else { } else {
@@ -160,7 +160,7 @@ status_t QTMR_SetupPwm_u16(TMR_Type *base, qtmr_channel_selection_t channel, uin
if (dutyCycleU16 == 0) { if (dutyCycleU16 == 0) {
// Clear the output at the next compare // Clear the output at the next compare
reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ClearOnCompare)); 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 // Set the output at the next compare
reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_SetOnCompare)); reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_SetOnCompare));
} else { } 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 uint16_t deadtimeValue; // The deadtime value; only used if channel pair is operating in complementary mode
} pwm_signal_param_u16_t; } 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, void PWM_UpdatePwmDutycycle_u16(PWM_Type *base, pwm_submodule_t subModule,
pwm_channels_t pwmSignal, uint32_t dutyCycle, uint16_t center); 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) { if (self->p_config->duty_mode[self->channel] == DUTY_PERCENT) {
return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel]); return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel]);
} else if (self->p_config->duty_mode[self->channel] == DUTY_U16) { } 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 { } else {
return MP_OBJ_NEW_SMALL_INT(-1); 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) { if (self->p_config->duty_mode[self->channel] == DUTY_U16) {
return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel]); return MP_OBJ_NEW_SMALL_INT(self->p_config->duty[self->channel]);
} else if (self->p_config->duty_mode[self->channel] == DUTY_PERCENT) { } 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 { } else {
return MP_OBJ_NEW_SMALL_INT(-1); 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) { if (self->p_config->duty_mode[i] == DUTY_PERCENT) {
pulse_width = ((period * self->p_config->duty[i]) / 100); pulse_width = ((period * self->p_config->duty[i]) / 100);
} else if (self->p_config->duty_mode[i] == DUTY_U16) { } 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) { } else if (self->p_config->duty_mode[i] == DUTY_NS) {
pulse_width = (uint64_t)self->p_config->duty[i] * tick_freq / 1000000000ULL; 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_CLK_READY (1)
#define PWM_TCC_ENABLED (2) #define PWM_TCC_ENABLED (2)
#define PWM_MASTER_CLK (get_peripheral_freq()) #define PWM_MASTER_CLK (get_peripheral_freq())
#define PWM_FULL_SCALE (65536) #define PWM_FULL_SCALE (65535)
#define PWM_UPDATE_TIMEOUT (2000) #define PWM_UPDATE_TIMEOUT (2000)
#define VALUE_NOT_SET (-1) #define VALUE_NOT_SET (-1)