summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/atmel-samd/background.c8
-rw-r--r--ports/atmel-samd/background.h3
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/__init__.c14
-rw-r--r--ports/atmel-samd/common-hal/pulseio/PulseIn.c16
-rw-r--r--ports/atmel-samd/common-hal/pulseio/PulseIn.h1
-rw-r--r--ports/atmel-samd/tick.c7
-rw-r--r--shared-bindings/pulseio/PulseIn.c23
-rw-r--r--shared-bindings/pulseio/PulseIn.h1
8 files changed, 62 insertions, 11 deletions
diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c
index 92648f42e..4cba7a110 100644
--- a/ports/atmel-samd/background.c
+++ b/ports/atmel-samd/background.c
@@ -26,11 +26,19 @@
#include "background.h"
#include "audio_dma.h"
+#include "tick.h"
#include "usb.h"
#include "usb_mass_storage.h"
+volatile uint64_t last_finished_tick = 0;
+
void run_background_tasks(void) {
audio_dma_background();
usb_msc_background();
usb_cdc_background();
+ last_finished_tick = ticks_ms;
+}
+
+bool background_tasks_ok(void) {
+ return ticks_ms - last_finished_tick < 1000;
}
diff --git a/ports/atmel-samd/background.h b/ports/atmel-samd/background.h
index f7fb10a1f..e841049a4 100644
--- a/ports/atmel-samd/background.h
+++ b/ports/atmel-samd/background.h
@@ -27,6 +27,9 @@
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H
#define MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H
+#include <stdbool.h>
+
void run_background_tasks(void);
+bool background_tasks_ok(void);
#endif // MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H
diff --git a/ports/atmel-samd/common-hal/microcontroller/__init__.c b/ports/atmel-samd/common-hal/microcontroller/__init__.c
index c57b6939c..ad4d81ddd 100644
--- a/ports/atmel-samd/common-hal/microcontroller/__init__.c
+++ b/ports/atmel-samd/common-hal/microcontroller/__init__.c
@@ -40,18 +40,10 @@ void common_hal_mcu_delay_us(uint32_t delay) {
mp_hal_delay_us(delay);
}
-// Interrupt flags that will be saved and restored during disable/Enable
-// interrupt functions below.
-
-// ASF4's interrupt disable doesn't handle duplicate calls
-volatile uint32_t interrupt_flags;
volatile uint32_t nesting_count = 0;
void common_hal_mcu_disable_interrupts(void) {
- if (nesting_count == 0) {
- interrupt_flags = __get_PRIMASK();
- __disable_irq();
- __DMB();
- }
+ __disable_irq();
+ __DMB();
nesting_count++;
}
@@ -66,7 +58,7 @@ void common_hal_mcu_enable_interrupts(void) {
return;
}
__DMB();
- __set_PRIMASK(interrupt_flags);
+ __enable_irq();
}
extern uint32_t _ezero;
diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c
index 99a60a829..dee32bbec 100644
--- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c
+++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c
@@ -31,6 +31,7 @@
#include "atmel_start_pins.h"
#include "hal/include/hal_gpio.h"
+#include "background.h"
#include "mpconfigport.h"
#include "py/gc.h"
#include "py/runtime.h"
@@ -60,10 +61,16 @@ void pulsein_interrupt_handler(uint8_t channel) {
uint32_t current_us;
uint64_t current_ms;
current_tick(&current_ms, &current_us);
+
// current_tick gives us the remaining us until the next tick but we want the number since the
// last ms.
current_us = 1000 - current_us;
pulseio_pulsein_obj_t* self = get_eic_channel_data(channel);
+ if (!background_tasks_ok() || self->errored_too_fast) {
+ self->errored_too_fast = true;
+ common_hal_pulseio_pulsein_pause(self);
+ return;
+ }
if (self->first_edge) {
self->first_edge = false;
pulsein_set_config(self, false);
@@ -118,6 +125,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
self->first_edge = true;
self->last_us = 0;
self->last_ms = 0;
+ self->errored_too_fast = 0;
set_eic_channel_data(pin->extint_channel, (void*) self);
@@ -157,6 +165,9 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self,
// Make sure we're paused.
common_hal_pulseio_pulsein_pause(self);
+ // Reset erroring
+ self->errored_too_fast = false;
+
// Send the trigger pulse.
if (trigger_duration > 0) {
gpio_set_pin_pull_mode(self->pin, GPIO_PULL_OFF);
@@ -207,6 +218,11 @@ uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) {
return self->len;
}
+bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) {
+ uint32_t mask = 1 << self->channel;
+ return (EIC->INTENSET.reg & (mask << EIC_INTENSET_EXTINT_Pos)) == 0;
+}
+
uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self,
int16_t index) {
common_hal_mcu_disable_interrupts();
diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.h b/ports/atmel-samd/common-hal/pulseio/PulseIn.h
index 3d79b50c3..f5326d9e5 100644
--- a/ports/atmel-samd/common-hal/pulseio/PulseIn.h
+++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.h
@@ -43,6 +43,7 @@ typedef struct {
volatile bool first_edge;
volatile uint64_t last_ms;
volatile uint16_t last_us;
+ volatile bool errored_too_fast;
} pulseio_pulsein_obj_t;
void pulsein_reset(void);
diff --git a/ports/atmel-samd/tick.c b/ports/atmel-samd/tick.c
index 6cd7c7833..81841c4af 100644
--- a/ports/atmel-samd/tick.c
+++ b/ports/atmel-samd/tick.c
@@ -60,6 +60,13 @@ void tick_init() {
uint32_t ticks_per_ms = common_hal_mcu_processor_get_frequency() / 1000;
SysTick_Config(ticks_per_ms-1);
NVIC_EnableIRQ(SysTick_IRQn);
+ // Set all peripheral interrupt priorities to the lowest priority by default.
+ for (uint16_t i = 0; i < PERIPH_COUNT_IRQn; i++) {
+ NVIC_SetPriority(i, (1UL << __NVIC_PRIO_BITS) - 1UL);
+ }
+ // Bump up the systick interrupt.
+ NVIC_SetPriority(SysTick_IRQn, 1);
+ NVIC_SetPriority(USB_IRQn, 1);
}
void tick_delay(uint32_t us) {
diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c
index 736441c74..862dbd99d 100644
--- a/shared-bindings/pulseio/PulseIn.c
+++ b/shared-bindings/pulseio/PulseIn.c
@@ -219,6 +219,26 @@ const mp_obj_property_t pulseio_pulsein_maxlen_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+//| .. attribute:: paused
+//|
+//| True when pulse capture is paused as a result of :py:func:`pause` or an error during capture
+//| such as a signal that is too fast.
+//|
+STATIC mp_obj_t pulseio_pulsein_obj_get_paused(mp_obj_t self_in) {
+ pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ raise_error_if_deinited(common_hal_pulseio_pulsein_deinited(self));
+
+ return mp_obj_new_bool(common_hal_pulseio_pulsein_get_paused(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_get_paused_obj, pulseio_pulsein_obj_get_paused);
+
+const mp_obj_property_t pulseio_pulsein_paused_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&pulseio_pulsein_get_paused_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
//| .. method:: __len__()
//|
//| Returns the current pulse length
@@ -285,7 +305,10 @@ STATIC const mp_rom_map_elem_t pulseio_pulsein_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&pulseio_pulsein_resume_obj) },
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&pulseio_pulsein_clear_obj) },
{ MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&pulseio_pulsein_popleft_obj) },
+
+ // Properties
{ MP_ROM_QSTR(MP_QSTR_maxlen), MP_ROM_PTR(&pulseio_pulsein_maxlen_obj) },
+ { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&pulseio_pulsein_paused_obj) },
};
STATIC MP_DEFINE_CONST_DICT(pulseio_pulsein_locals_dict, pulseio_pulsein_locals_dict_table);
diff --git a/shared-bindings/pulseio/PulseIn.h b/shared-bindings/pulseio/PulseIn.h
index 88b6f356e..e28a3c2df 100644
--- a/shared-bindings/pulseio/PulseIn.h
+++ b/shared-bindings/pulseio/PulseIn.h
@@ -41,6 +41,7 @@ extern void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint1
extern void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self);
extern uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self);
extern uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self);
+extern bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self);
extern uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self);
extern uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index);