Skip to content

Commit e87e1d8

Browse files
committed
Block when setting duty_cycle until the new value is taken
1 parent 080e523 commit e87e1d8

File tree

2 files changed

+12
-25
lines changed

2 files changed

+12
-25
lines changed

ports/raspberrypi/common-hal/pulseio/PulseOut.c

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,12 @@
3838
#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h"
3939
#include "src/common/pico_time/include/pico/time.h"
4040

41-
static uint8_t refcount = 0;
4241
volatile alarm_id_t cur_alarm = 0;
4342

44-
void turn_off(uint8_t slice) {
45-
// Set the current counter value near the top so that the output is low. The
46-
// - 2 gives us a little wiggle room for enabling and disabling the slice.
47-
// The top + 1 ensure we don't end up lower than the cc (and therefore high.)
48-
uint32_t top = MAX(pwm_hw->slice[slice].cc + 1, pwm_hw->slice[slice].top - 2);
49-
// Disable interrupts so this happens as fast as possible.
50-
common_hal_mcu_disable_interrupts();
51-
pwm_hw->slice[slice].ctr = top;
52-
// Enable for at least one cycle so that the new counter value takes effect.
53-
pwm_hw->slice[slice].csr = PWM_CH0_CSR_EN_BITS;
54-
pwm_hw->slice[slice].csr = 0;
55-
common_hal_mcu_enable_interrupts();
56-
}
57-
5843
void pulse_finish(pulseio_pulseout_obj_t *self) {
5944
self->pulse_index++;
60-
// Turn pwm pin off by setting duty cyle to 1.
61-
common_hal_pwmio_pwmout_set_duty_cycle(&self->carrier, 1);
45+
// Turn pwm pin off by setting duty cyle to 0.
46+
common_hal_pwmio_pwmout_set_duty_cycle(&self->carrier, 0);
6247
if (self->pulse_index >= self->pulse_length) {
6348
return;
6449
}
@@ -91,15 +76,12 @@ void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t *self,
9176
uint16_t duty_cycle) {
9277

9378
pwmout_result_t result = common_hal_pwmio_pwmout_construct(
94-
&self->carrier, pin, duty_cycle, frequency, false);
79+
&self->carrier, pin, 0, frequency, false);
9580

9681
// This will raise an exception and not return if needed.
9782
common_hal_pwmio_pwmout_raise_error(result);
9883

9984
self->current_duty_cycle = duty_cycle;
100-
pwm_set_enabled(self->carrier.slice, false);
101-
turn_off(self->carrier.slice);
102-
common_hal_pwmio_pwmout_set_duty_cycle(&self->carrier, 1);
10385
self->pin = self->carrier.pin->number;
10486
self->slice = self->carrier.slice;
10587
self->min_pulse = (1000000 / self->carrier.actual_frequency);
@@ -123,7 +105,6 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t *self, uint16_t *pu
123105
self->pulse_length = length;
124106

125107
common_hal_pwmio_pwmout_set_duty_cycle(&self->carrier, self->current_duty_cycle);
126-
pwm_set_enabled(self->slice, true);
127108
uint64_t delay = self->pulse_buffer[0];
128109
if (delay < self->min_pulse) {
129110
delay = self->min_pulse;
@@ -140,7 +121,4 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t *self, uint16_t *pu
140121
// signal.
141122
RUN_BACKGROUND_TASKS;
142123
}
143-
// Ensure pin is left low
144-
turn_off(self->slice);
145-
pwm_set_enabled(self->slice,false);
146124
}

ports/raspberrypi/common-hal/pwmio/PWMOut.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <stdint.h>
2828

29+
#include "lib/utils/interrupt_char.h"
2930
#include "py/runtime.h"
3031
#include "common-hal/pwmio/PWMOut.h"
3132
#include "shared-bindings/pwmio/PWMOut.h"
@@ -235,6 +236,14 @@ extern void common_hal_pwmio_pwmout_set_duty_cycle(pwmio_pwmout_obj_t *self, uin
235236
}
236237
// compare_count is the CC register value, which should be TOP+1 for 100% duty cycle.
237238
pwm_set_chan_level(self->slice, self->channel, compare_count);
239+
// Wait for wrap so that we know our new cc value has been applied. Clear
240+
// the internal interrupt and then wait for it to be set. Worst case, we
241+
// wait a full cycle.
242+
pwm_hw->intr = 1 << self->channel;
243+
while ((pwm_hw->en & (1 << self->channel)) != 0 &&
244+
(pwm_hw->intr & (1 << self->channel)) == 0 &&
245+
!mp_hal_is_interrupted()) {
246+
}
238247
}
239248

240249
uint16_t common_hal_pwmio_pwmout_get_duty_cycle(pwmio_pwmout_obj_t *self) {

0 commit comments

Comments
 (0)