Block when setting duty_cycle until the new value is taken
This commit is contained in:
parent
080e5233b4
commit
e87e1d8175
@ -38,27 +38,12 @@
|
||||
#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h"
|
||||
#include "src/common/pico_time/include/pico/time.h"
|
||||
|
||||
static uint8_t refcount = 0;
|
||||
volatile alarm_id_t cur_alarm = 0;
|
||||
|
||||
void turn_off(uint8_t slice) {
|
||||
// Set the current counter value near the top so that the output is low. The
|
||||
// - 2 gives us a little wiggle room for enabling and disabling the slice.
|
||||
// The top + 1 ensure we don't end up lower than the cc (and therefore high.)
|
||||
uint32_t top = MAX(pwm_hw->slice[slice].cc + 1, pwm_hw->slice[slice].top - 2);
|
||||
// Disable interrupts so this happens as fast as possible.
|
||||
common_hal_mcu_disable_interrupts();
|
||||
pwm_hw->slice[slice].ctr = top;
|
||||
// Enable for at least one cycle so that the new counter value takes effect.
|
||||
pwm_hw->slice[slice].csr = PWM_CH0_CSR_EN_BITS;
|
||||
pwm_hw->slice[slice].csr = 0;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
void pulse_finish(pulseio_pulseout_obj_t *self) {
|
||||
self->pulse_index++;
|
||||
// Turn pwm pin off by setting duty cyle to 1.
|
||||
common_hal_pwmio_pwmout_set_duty_cycle(&self->carrier, 1);
|
||||
// Turn pwm pin off by setting duty cyle to 0.
|
||||
common_hal_pwmio_pwmout_set_duty_cycle(&self->carrier, 0);
|
||||
if (self->pulse_index >= self->pulse_length) {
|
||||
return;
|
||||
}
|
||||
@ -91,15 +76,12 @@ void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t *self,
|
||||
uint16_t duty_cycle) {
|
||||
|
||||
pwmout_result_t result = common_hal_pwmio_pwmout_construct(
|
||||
&self->carrier, pin, duty_cycle, frequency, false);
|
||||
&self->carrier, pin, 0, frequency, false);
|
||||
|
||||
// This will raise an exception and not return if needed.
|
||||
common_hal_pwmio_pwmout_raise_error(result);
|
||||
|
||||
self->current_duty_cycle = duty_cycle;
|
||||
pwm_set_enabled(self->carrier.slice, false);
|
||||
turn_off(self->carrier.slice);
|
||||
common_hal_pwmio_pwmout_set_duty_cycle(&self->carrier, 1);
|
||||
self->pin = self->carrier.pin->number;
|
||||
self->slice = self->carrier.slice;
|
||||
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
|
||||
self->pulse_length = length;
|
||||
|
||||
common_hal_pwmio_pwmout_set_duty_cycle(&self->carrier, self->current_duty_cycle);
|
||||
pwm_set_enabled(self->slice, true);
|
||||
uint64_t delay = self->pulse_buffer[0];
|
||||
if (delay < self->min_pulse) {
|
||||
delay = self->min_pulse;
|
||||
@ -140,7 +121,4 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t *self, uint16_t *pu
|
||||
// signal.
|
||||
RUN_BACKGROUND_TASKS;
|
||||
}
|
||||
// Ensure pin is left low
|
||||
turn_off(self->slice);
|
||||
pwm_set_enabled(self->slice,false);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
#include "py/runtime.h"
|
||||
#include "common-hal/pwmio/PWMOut.h"
|
||||
#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
|
||||
}
|
||||
// compare_count is the CC register value, which should be TOP+1 for 100% duty cycle.
|
||||
pwm_set_chan_level(self->slice, self->channel, compare_count);
|
||||
// Wait for wrap so that we know our new cc value has been applied. Clear
|
||||
// the internal interrupt and then wait for it to be set. Worst case, we
|
||||
// wait a full cycle.
|
||||
pwm_hw->intr = 1 << self->channel;
|
||||
while ((pwm_hw->en & (1 << self->channel)) != 0 &&
|
||||
(pwm_hw->intr & (1 << self->channel)) == 0 &&
|
||||
!mp_hal_is_interrupted()) {
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t common_hal_pwmio_pwmout_get_duty_cycle(pwmio_pwmout_obj_t *self) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user