From 0f07a9b96e16bf98d35e8319ec8b47885ce25066 Mon Sep 17 00:00:00 2001 From: Joshua Broekhuijsen Date: Sun, 22 Oct 2023 21:04:01 -0500 Subject: [PATCH 1/2] Fixed the RP2040 interrupt problem --- ports/raspberrypi/common-hal/pulseio/PulseIn.c | 9 +++++++++ ports/raspberrypi/common-hal/pulseio/PulseIn.h | 1 + 2 files changed, 10 insertions(+) diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.c b/ports/raspberrypi/common-hal/pulseio/PulseIn.c index 346c0951ed0f..042f2415b021 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.c @@ -56,6 +56,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, self->idle_state = idle_state; self->start = 0; self->len = 0; + self->len_target = 0; common_hal_rp2pio_statemachine_construct(&self->state_machine, pulsein_program, MP_ARRAY_SIZE(pulsein_program), @@ -133,6 +134,8 @@ void common_hal_pulseio_pulsein_interrupt(void *self_in) { self->buffer[buf_index] = (uint16_t)result; if (self->len < self->maxlen) { self->len++; + self->len_target++; // The interrupt will only cause a problem in either len or len_target, not both. + // So we can just check for a match, and choose the higher. } else { self->start = (self->start + 1) % self->maxlen; } @@ -174,7 +177,13 @@ uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t *self) { } uint16_t value = self->buffer[self->start]; self->start = (self->start + 1) % self->maxlen; + self->len_target--; self->len--; + if (self->len != self->len_target) { + uint16_t len_accurate = self->len > self->len_target ? self->len : self->len_target; + self->len_target = len_accurate; + self->len = len_accurate; + } return value; } diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.h b/ports/raspberrypi/common-hal/pulseio/PulseIn.h index 8694f75e6263..9db15a687f1f 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.h +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.h @@ -43,6 +43,7 @@ typedef struct { volatile bool last_level; volatile uint32_t level_count; volatile uint16_t len; + volatile uint16_t len_target; volatile uint16_t start; rp2pio_statemachine_obj_t state_machine; } pulseio_pulsein_obj_t; From ecf5a6be97e52e145ba75d0681d5e856195aecd4 Mon Sep 17 00:00:00 2001 From: Joshua Broekhuijsen Date: Mon, 23 Oct 2023 18:00:21 -0500 Subject: [PATCH 2/2] Changed to interrupt guards --- ports/raspberrypi/common-hal/pulseio/PulseIn.c | 11 ++--------- ports/raspberrypi/common-hal/pulseio/PulseIn.h | 1 - 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.c b/ports/raspberrypi/common-hal/pulseio/PulseIn.c index 042f2415b021..70d542246ed3 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.c @@ -56,7 +56,6 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, self->idle_state = idle_state; self->start = 0; self->len = 0; - self->len_target = 0; common_hal_rp2pio_statemachine_construct(&self->state_machine, pulsein_program, MP_ARRAY_SIZE(pulsein_program), @@ -134,8 +133,6 @@ void common_hal_pulseio_pulsein_interrupt(void *self_in) { self->buffer[buf_index] = (uint16_t)result; if (self->len < self->maxlen) { self->len++; - self->len_target++; // The interrupt will only cause a problem in either len or len_target, not both. - // So we can just check for a match, and choose the higher. } else { self->start = (self->start + 1) % self->maxlen; } @@ -176,14 +173,10 @@ uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t *self) { mp_raise_IndexError_varg(translate("pop from empty %q"), MP_QSTR_PulseIn); } uint16_t value = self->buffer[self->start]; + common_hal_mcu_disable_interrupts(); self->start = (self->start + 1) % self->maxlen; - self->len_target--; self->len--; - if (self->len != self->len_target) { - uint16_t len_accurate = self->len > self->len_target ? self->len : self->len_target; - self->len_target = len_accurate; - self->len = len_accurate; - } + common_hal_mcu_enable_interrupts(); return value; } diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.h b/ports/raspberrypi/common-hal/pulseio/PulseIn.h index 9db15a687f1f..8694f75e6263 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.h +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.h @@ -43,7 +43,6 @@ typedef struct { volatile bool last_level; volatile uint32_t level_count; volatile uint16_t len; - volatile uint16_t len_target; volatile uint16_t start; rp2pio_statemachine_obj_t state_machine; } pulseio_pulsein_obj_t;