diff --git a/ports/raspberrypi/common-hal/pulseio/PulseOut.c b/ports/raspberrypi/common-hal/pulseio/PulseOut.c index edf0bd028c..093d52a2db 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseOut.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseOut.c @@ -46,15 +46,16 @@ volatile uint16_t current_duty_cycle; static uint32_t min_pulse = 0; static alarm_id_t cur_alarm; -void pulse_finish(void) { +void pulse_finish(pwmio_pwmout_obj_t *carrier) { pulse_index++; - // Turn off the current alarm - cancel_alarm(cur_alarm); // Turn pwm pin off by setting duty cyle to 1. - common_hal_pwmio_pwmout_set_duty_cycle(pwmout_obj,1); + common_hal_pwmio_pwmout_set_duty_cycle(carrier,1); if (pulse_index >= pulse_length) { return; } + if (pulse_index % 2 == 0) { + common_hal_pwmio_pwmout_set_duty_cycle(carrier,current_duty_cycle); + } uint64_t delay = pulse_buffer[pulse_index]; if (delay < min_pulse) { delay = min_pulse; @@ -62,16 +63,13 @@ void pulse_finish(void) { cur_alarm = 0; // if the alarm cannot be set, try again with a longer delay while (cur_alarm == 0) { - cur_alarm = add_alarm_in_us(delay, pulseout_interrupt_handler, NULL, false); + cur_alarm = add_alarm_in_us(delay, pulseout_interrupt_handler, carrier, false); delay = delay + 1; } - if (pulse_index % 2 == 0) { - common_hal_pwmio_pwmout_set_duty_cycle(pwmout_obj,current_duty_cycle); - } } int64_t pulseout_interrupt_handler(alarm_id_t id, void *user_data) { - pulse_finish(); + pulse_finish(user_data); return 0; } @@ -88,10 +86,12 @@ void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t *self, refcount++; pwmout_obj = (pwmio_pwmout_obj_t *)carrier; current_duty_cycle = common_hal_pwmio_pwmout_get_duty_cycle(pwmout_obj); + pwm_set_enabled(carrier->slice,false); + common_hal_pwmio_pwmout_set_duty_cycle(pwmout_obj,1); self->pin = carrier->pin->number; self->slice = carrier->slice; - pwm_set_enabled(pwmout_obj->slice,false); - min_pulse = (1000000 / pwmout_obj->actual_frequency) / 2; + self->carrier = pwmout_obj; + min_pulse = (1000000 / carrier->actual_frequency) / 2; } bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t *self) { @@ -111,9 +111,19 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t *self, uint16_t *pu pulse_index = 0; pulse_length = length; - add_alarm_in_us(pulses[0], pulseout_interrupt_handler, NULL, false); - common_hal_pwmio_pwmout_set_duty_cycle(pwmout_obj,current_duty_cycle); - pwm_set_enabled(pwmout_obj->slice,true); + common_hal_pwmio_pwmout_set_duty_cycle(self->carrier,current_duty_cycle); + pwm_set_enabled(self->slice,true); + uint64_t delay = pulse_buffer[0]; + if (delay < min_pulse) { + delay = min_pulse; + } + alarm_id_t init_alarm = 0; + // if the alarm cannot be set, try again with a longer delay + while (init_alarm == 0) { + init_alarm = add_alarm_in_us(delay, pulseout_interrupt_handler, self->carrier, false); + delay = delay + 1; + } + cur_alarm = init_alarm; while (pulse_index < length) { // Do other things while we wait. The interrupts will handle sending the @@ -122,5 +132,5 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t *self, uint16_t *pu } // Short delay to give pin time to settle before disabling PWM common_hal_mcu_delay_us(min_pulse); - pwm_set_enabled(pwmout_obj->slice,false); + pwm_set_enabled(self->slice,false); } diff --git a/ports/raspberrypi/common-hal/pulseio/PulseOut.h b/ports/raspberrypi/common-hal/pulseio/PulseOut.h index 8dcebdba98..5c44973c93 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseOut.h +++ b/ports/raspberrypi/common-hal/pulseio/PulseOut.h @@ -28,6 +28,7 @@ #define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H #include "common-hal/microcontroller/Pin.h" +#include "common-hal/pwmio/PWMOut.h" #include "src/common/pico_time/include/pico/time.h" #include "py/obj.h" @@ -38,9 +39,10 @@ typedef struct { mp_obj_base_t base; uint8_t pin; uint8_t slice; + pwmio_pwmout_obj_t *carrier; } pulseio_pulseout_obj_t; void pulseout_reset(void); int64_t pulseout_interrupt_handler(alarm_id_t id, void *user_data); -#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H +#endif // MICROPY_INCLUDED_ATMEL SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H