diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c index 7ea20321b2..b825579dbe 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c @@ -125,6 +125,9 @@ void pulsein_interrupt_handler(uint8_t channel) { } void pulsein_reset() { +#ifdef SAMD21 + rtc_end_pulsein(); +#endif refcount = 0; pulsein_tc_index = 0xff; overflow_count = 0; @@ -221,6 +224,10 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, // Set config will enable the EIC. pulsein_set_config(self, true); +#ifdef SAMD21 + rtc_start_pulsein(); +#endif + } bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) { @@ -231,6 +238,9 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { if (common_hal_pulseio_pulsein_deinited(self)) { return; } +#ifdef SAMD21 + rtc_end_pulsein(); +#endif set_eic_handler(self->channel, EIC_HANDLER_NO_INTERRUPT); turn_off_eic_channel(self->channel); reset_pin_number(self->pin); diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.h b/ports/atmel-samd/common-hal/pulseio/PulseIn.h index 89b61a83ac..99358178f2 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.h +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.h @@ -50,5 +50,11 @@ void pulsein_reset(void); void pulsein_interrupt_handler(uint8_t channel); void pulsein_timer_interrupt_handler(uint8_t index); +#ifdef SAMD21 +void rtc_set_continuous(void); +void rtc_start_pulsein(void); +void rtc_end_pulsein(void); +#endif + #endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 48bd3211b5..e892e6cde5 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -91,6 +91,23 @@ #if CIRCUITPY_PEW #include "common-hal/_pew/PewPew.h" #endif +volatile bool hold_interrupt = false; +#ifdef SAMD21 +void rtc_start_pulsein(void) { + rtc_set_continuous(); + hold_interrupt = true; +} + +void rtc_end_pulsein(void) { + hold_interrupt = false; +} + +void rtc_set_continuous(void) { + while (RTC->MODE0.STATUS.bit.SYNCBUSY); + RTC->MODE0.READREQ.reg = RTC_READREQ_RREQ | RTC_READREQ_RCONT | 0x0010; + while (RTC->MODE0.STATUS.bit.SYNCBUSY); +} +#endif extern volatile bool mp_msc_enabled; @@ -489,6 +506,11 @@ void port_interrupt_after_ticks(uint32_t ticks) { // We'll interrupt sooner with an overflow. return; } +#ifdef SAMD21 + if (hold_interrupt) { + return; + } +#endif RTC->MODE0.COMP[0].reg = current_ticks + (ticks << 4); RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0; @@ -503,7 +525,7 @@ void port_sleep_until_interrupt(void) { } #endif common_hal_mcu_disable_interrupts(); - if (!tud_task_event_ready()) { + if (!tud_task_event_ready() && !hold_interrupt) { __DSB(); __WFI(); }