8000 Merge pull request #901 from tannewt/pulseio_too_fast · sparkfun/circuitpython@b2d98ed · GitHub
[go: up one dir, main page]

Skip to content

Commit b2d98ed

Browse files
authored
Merge pull request adafruit#901 from tannewt/pulseio_too_fast
Prevent freezing USB during high frequency PulseIn.
2 parents 4e4d795 + 8fb34a5 commit b2d98ed

File tree

31 files changed

+608
-25
lines changed

31 files changed

+608
-25
lines changed

ports/atmel-samd/background.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,19 @@
2626
#include "background.h"
2727

2828
#include "audio_dma.h"
29+
#include "tick.h"
2930
#include "usb.h"
3031
#include "usb_mass_storage.h"
3132

33+
volatile uint64_t last_finished_tick = 0;
34+
3235
void run_background_tasks(void) {
3336
audio_dma_background();
3437
usb_msc_background();
3538
usb_cdc_background();
39+
last_finished_tick = ticks_ms;
40+
}
41+
42+
bool background_tasks_ok(void) {
43+
return ticks_ms - last_finished_tick < 1000;
3644
}

ports/atmel-samd/background.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#ifndef MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H
2828
#define MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H
2929

30+
#include <stdbool.h>
31+
3032
void run_background_tasks(void);
33+
bool background_tasks_ok(void);
3134

3235
#endif // MICROPY_INCLUDED_ATMEL_SAMD_BACKGROUND_H

ports/atmel-samd/bindings/samd/Clock.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,7 @@
4747
STATIC void samd_clock_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
4848
samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in);
4949

50-
mp_printf(print, "%q.%q.%s(", MP_QSTR_samd, MP_QSTR_clock, self->name);
51-
if (clock_get_enabled(self->type, self->index)) {
52-
mp_printf(print, "frequency=%u", clock_get_frequency(self->type, self->index));
53-
uint32_t calibration = clock_get_calibration(self->type, self->index);
54-
if (calibration) {
55-
mp_printf(print, ", calibration=%u", calibration);
56-
}
57-
}
58-
mp_printf(print, ")");
50+
mp_printf(print, "%q.%q.%q", MP_QSTR_samd, MP_QSTR_clock, self->name);
5951
}
6052

6153
//| .. attribute:: enabled

ports/atmel-samd/bindings/samd/Clock.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,39 +31,39 @@
3131

3232
typedef struct {
3333
mp_obj_base_t base;
34-
const char *name;
34+
qstr name;
3535
uint8_t type;
3636
uint8_t index;
3737
} samd_clock_obj_t;
3838

3939
#define CLOCK(_name, _type, _index) \
4040
const samd_clock_obj_t clock_ ## _name = { \
4141
{ &samd_clock_type }, \
42-
.name = #_name, \
42+
.name = MP_QSTR_ ## _name, \
4343
.type = _type, \
4444
.index = _index, \
4545
}
4646

4747
#define CLOCK_SOURCE(_name) \
4848
const samd_clock_obj_t clock_ ## _name = { \
4949
{ &samd_clock_type }, \
50-
.name = #_name, \
50+
.name = MP_QSTR_ ## _name, \
5151
.type = 0, \
5252
.index = GCLK_SOURCE_ ## _name, \
5353
}
5454

5555
#define CLOCK_GCLK(_name) \
5656
const samd_clock_obj_t clock_ ## _name = { \
5757
{ &samd_clock_type }, \
58-
.name = #_name, \
58+
.name = MP_QSTR_ ## _name, \
5959
.type = 1, \
6060
.index = _name ## _GCLK_ID, \
6161
}
6262

6363
#define CLOCK_GCLK_(_name, _extra) \
6464
const samd_clock_obj_t clock_ ## _name ## _ ## _extra = { \
6565
{ &samd_clock_type }, \
66-
.name = #_name "_" #_extra, \
66+
.name = MP_QSTR_ ## _name ## _ ## _extra, \
6767
.type = 1, \
6868
.index = _name ## _GCLK_ID_ ## _extra, \
6969
}

ports/atmel-samd/boards/arduino_zero/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,7 @@
2424

2525
#define DEFAULT_UART_BUS_RX (&pin_PA11)
2626
#define DEFAULT_UART_BUS_TX (&pin_PA10)
27+
28+
// USB is always used internally so skip the pin objects for it.
29+
#define IGNORE_PIN_PA24 1
30+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,7 @@
6868

6969
#define DEFAULT_UART_BUS_RX (&pin_PB09)
7070
#define DEFAULT_UART_BUS_TX (&pin_PB08)
71+
72+
// USB is always used internally so skip the pin objects for it.
73+
#define IGNORE_PIN_PA24 1
74+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,7 @@
7171

7272
#define DEFAULT_UART_BUS_RX (&pin_PB09)
7373
#define DEFAULT_UART_BUS_TX (&pin_PB08)
74+
75+
// USB is always used internally so skip the pin objects for it.
76+
#define IGNORE_PIN_PA24 1
77+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/feather_m0_adalogger/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@
2222

2323
#define DEFAULT_UART_BUS_RX (&pin_PA11)
2424
#define DEFAULT_UART_BUS_TX (&pin_PA10)
25+
26+
// USB is always used internally so skip the pin objects for it.
27+
#define IGNORE_PIN_PA24 1
28+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/feather_m0_basic/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@
2323

2424
#define DEFAULT_UART_BUS_RX (&pin_PA11)
2525
#define DEFAULT_UART_BUS_TX (&pin_PA10)
26+
27+
// USB is always used internally so skip the pin objects for it.
28+
#define IGNORE_PIN_PA24 1
29+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/feather_m0_express/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,7 @@
5858

5959
#define DEFAULT_UART_BUS_RX (&pin_PA11)
6060
#define DEFAULT_UART_BUS_TX (&pin_PA10)
61+
62+
// USB is always used internally so skip the pin objects for it.
63+
#define IGNORE_PIN_PA24 1
64+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/feather_m0_rfm69/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@
2323

2424
#define DEFAULT_UART_BUS_RX (&pin_PA11)
2525
#define DEFAULT_UART_BUS_TX (&pin_PA10)
26+
27+
// USB is always used internally so skip the pin objects for it.
28+
#define IGNORE_PIN_PA24 1
29+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/feather_m0_rfm9x/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@
2323

2424
#define DEFAULT_UART_BUS_RX (&pin_PA11)
2525
#define DEFAULT_UART_BUS_TX (&pin_PA10)
26+
27+
// USB is always used internally so skip the pin objects for it.
28+
#define IGNORE_PIN_PA24 1
29+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@
5757

5858
#define DEFAULT_UART_BUS_RX (&pin_PA11)
5959
#define DEFAULT_UART_BUS_TX (&pin_PA10)
60+
61+
// USB is always used internally so skip the pin objects for it.
62+
#define IGNORE_PIN_PA24 1
63+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,7 @@
4343

4444
#define DEFAULT_UART_BUS_RX (&pin_PB17)
4545
#define DEFAULT_UART_BUS_TX (&pin_PB16)
46+
47+
// USB is always used internally so skip the pin objects for it.
48+
#define IGNORE_PIN_PA24 1
49+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/gemma_m0/mpconfigboard.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
#define IGNORE_PIN_PA20 1
4141
#define IGNORE_PIN_PA21 1
4242
#define IGNORE_PIN_PA22 1
43+
// USB is always used.
44+
#define IGNORE_PIN_PA24 1
45+
#define IGNORE_PIN_PA25 1
4346
#define IGNORE_PIN_PA27 1
4447
#define IGNORE_PIN_PA28 1
4548
#define IGNORE_PIN_PA30 1

ports/atmel-samd/boards/itsybitsy_m0_express/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,7 @@
5656

5757
#define DEFAULT_UART_BUS_RX (&pin_PA11)
5858
#define DEFAULT_UART_BUS_TX (&pin_PA10)
59+
60+
// USB is always used internally so skip the pin objects for it.
61+
#define IGNORE_PIN_PA24 1
62+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,7 @@
4141

4242
#define DEFAULT_UART_BUS_RX (&pin_PA16)
4343
#define DEFAULT_UART_BUS_TX (&pin_PA17)
44+
45+
// USB is always used internally so skip the pin objects for it.
46+
#define IGNORE_PIN_PA24 1
47+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/metro_m0_express/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@
5959

6060
#define DEFAULT_UART_BUS_RX (&pin_PA11)
6161
#define DEFAULT_UART_BUS_TX (&pin_PA10)
62+
63+
// USB is always used internally so skip the pin objects for it.
64+
#define IGNORE_PIN_PA24 1
65+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,7 @@
4444

4545
#define DEFAULT_UART_BUS_RX (&pin_PA23)
4646
#define DEFAULT_UART_BUS_TX (&pin_PA22)
47+
48+
// USB is always used internally so skip the pin objects for it.
49+
#define IGNORE_PIN_PA24 1
50+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/trinket_m0/mpconfigboard.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
#define IGNORE_PIN_PA21 1
3131
#define IGNORE_PIN_PA22 1
3232
#define IGNORE_PIN_PA23 1
33+
// USB is always used internally so skip the pin objects for it.
34+
#define IGNORE_PIN_PA24 1
35+
#define IGNORE_PIN_PA25 1
3336
#define IGNORE_PIN_PA27 1
3437
#define IGNORE_PIN_PA28 1
3538
#define IGNORE_PIN_PA30 1

ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,7 @@
6464

6565
#define DEFAULT_UART_BUS_RX (&pin_PA07)
6666
#define DEFAULT_UART_BUS_TX (&pin_PA06)
67+
68+
// USB is always used internally so skip the pin objects for it.
69+
#define IGNORE_PIN_PA24 1
70+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/boards/ugame10/mpconfigboard.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,7 @@
5252
{ MP_OBJ_NEW_QSTR(MP_QSTR_audioio), (mp_obj_t)&audioio_module }, \
5353
{ MP_OBJ_NEW_QSTR(MP_QSTR_gamepad),(mp_obj_t)&gamepad_module }, \
5454
{ MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module }
55+
56+
// USB is always used internally so skip the pin objects for it.
57+
#define IGNORE_PIN_PA24 1
58+
#define IGNORE_PIN_PA25 1

ports/atmel-samd/common-hal/microcontroller/__init__.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,10 @@ void common_hal_mcu_delay_us(uint32_t delay) {
4040
mp_hal_delay_us(delay);
4141
}
4242

43-
// Interrupt flags that will be saved and restored during disable/Enable
44-
// interrupt functions below.
45-
46-
// ASF4's interrupt disable doesn't handle duplicate calls
47-
volatile uint32_t interrupt_flags;
4843
volatile uint32_t nesting_count = 0;
4944
void common_hal_mcu_disable_interrupts(void) {
50-
if (nesting_count == 0) {
51-
interrupt_flags = __get_PRIMASK();
52-
__disable_irq();
53-
__DMB();
54-
}
45+
__disable_irq();
46+
__DMB();
5547
nesting_count++;
5648
}
5749

@@ -66,7 +58,7 @@ void common_hal_mcu_enable_interrupts(void) {
6658
return;
6759
}
6860
__DMB();
69-
__set_PRIMASK(interrupt_flags);
61+
__enable_irq();
7062
}
7163

7264
extern uint32_t _ezero;

ports/atmel-samd/common-hal/pulseio/PulseIn.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "atmel_start_pins.h"
3232
#include "hal/include/hal_gpio.h"
3333

34+
#include "background.h"
3435
#include "mpconfigport.h"
3536
#include "py/gc.h"
3637
#include "py/runtime.h"
@@ -60,10 +61,16 @@ void pulsein_interrupt_handler(uint8_t channel) {
6061
uint32_t current_us;
6162
uint64_t current_ms;
6263
current_tick(&current_ms, &current_us);
64+
6365
// current_tick gives us the remaining us until the next tick but we want the number since the
6466
// last ms.
6567
current_us = 1000 - current_us;
6668
pulseio_pulsein_obj_t* self = get_eic_channel_data(channel);
69+
if (!background_tasks_ok() || self->errored_too_fast) {
70+
self->errored_too_fast = true;
71+
common_hal_pulseio_pulsein_pause(self);
72+
return;
73+
}
6774
if (self->first_edge) {
6875
self->first_edge = false;
6976
pulsein_set_config(self, false);
@@ -118,6 +125,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
118125
self->first_edge = true;
119126
self->last_us = 0;
120127
self->last_ms = 0;
128+
self->errored_too_fast = false;
121129

122130
set_eic_channel_data(pin->extint_channel, (void*) self);
123131

@@ -157,6 +165,9 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self,
157165
// Make sure we're paused.
158166
common_hal_pulseio_pulsein_pause(self);
159167

168+
// Reset erroring
169+
self->errored_too_fast = false;
170+
160171
// Send the trigger pulse.
161172
if (trigger_duration > 0) {
162173
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) {
207218
return self->len;
208219
}
209220

221+
bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) {
222+
uint32_t mask = 1 << self->channel;
223+
return (EIC->INTENSET.reg & (mask << EIC_INTENSET_EXTINT_Pos)) == 0;
224+
}
225+
210226
uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self,
211227
int16_t index) {
212228
common_hal_mcu_disable_interrupts();

ports/atmel-samd/common-hal/pulseio/PulseIn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef struct {
4343
volatile bool first_edge;
4444
volatile uint64_t last_ms;
4545
volatile uint16_t last_us;
46+
volatile bool errored_too_fast;
4647
} pulseio_pulsein_obj_t;
4748

4849
void pulsein_reset(void);

ports/atmel-samd/peripherals/samd21/clocks.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ static void init_clock_source_dfll48m_xosc(void) {
130130
SYSCTRL_DFLLCTRL_ENABLE;
131131
while (!SYSCTRL->PCLKSR.bit.DFLLRDY) {}
132132
while (GCLK->STATUS.bit.SYNCBUSY) {}
133+
134+
// Wait for the fine lock on the DFLL.
135+
while (!SYSCTRL->PCLKSR.bit.DFLLLCKC || !SYSCTRL->PCLKSR.bit.DFLLLCKF) {}
133136
}
134137

135138
static void init_clock_source_dfll48m_usb(void) {

ports/atmel-samd/tick.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ void tick_init() {
6060
uint32_t ticks_per_ms = common_hal_mcu_processor_get_frequency() / 1000;
6161
SysTick_Config(ticks_per_ms-1);
6262
NVIC_EnableIRQ(SysTick_IRQn);
63+
// Set all peripheral interrupt priorities to the lowest priority by default.
64+
for (uint16_t i = 0; i < PERIPH_COUNT_IRQn; i++) {
65+
NVIC_SetPriority(i, (1UL << __NVIC_PRIO_BITS) - 1UL);
66+
}
67+
// Bump up the systick interrupt.
68+
NVIC_SetPriority(SysTick_IRQn, 1);
69+
#ifdef SAMD21
70+
NVIC_SetPriority(USB_IRQn, 1);
71+
#endif
72+
73+
#ifdef SAMD51
74+
NVIC_SetPriority(USB_0_IRQn, 1);
75+
NVIC_SetPriority(USB_1_IRQn, 1);
76+
NVIC_SetPriority(USB_2_IRQn, 1);
77+
NVIC_SetPriority(USB_3_IRQn, 1);
78+
#endif
6379
}
6480

6581
void tick_delay(uint32_t us) {

ports/nrf/common-hal/pulseio/PulseIn.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) {
7171
return 0xadaf;
7272
}
7373

74+
bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) {
75+
return true;
76+
}
77+
7478
uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) {
7579
return 0xadaf;
7680
}

0 commit comments

Comments
 (0)
0