8000 esp8266/machine_pin: Move pin_intr_handler to iRAM, de-support hard IRQ. · codemee/micropython@0bd58a5 · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit 0bd58a5

Browse files
committed
esp8266/machine_pin: Move pin_intr_handler to iRAM, de-support hard IRQ.
GPIO interrupts can occur when the flash ROM cache is in use and so the GPIO interrupt handler must be in iRAM. This commit moves the handler to iRAM, and also moves mp_sched_schedule to iRAM which is called by pin_intr_handler. As part of this fix the Pin class can no longer support hard=True in the Pin.irq() method, because the VM and runtime are too big to put in iRAM. Fixes micropython#5714.
1 parent 544c308 commit 0bd58a5

File tree

2 files changed

+6
-19
lines changed

2 files changed

+6
-19
lines changed

ports/esp8266/machine_pin.c

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include "py/gc.h"
3838
#include "py/mphal.h"
3939
#include "extmod/virtpin.h"
40-
#include "ets_alt_task.h"
4140
#include "modmachine.h"
4241

4342
#define GET_TRIGGER(phys_port) \
@@ -87,40 +86,25 @@ STATIC uint8_t pin_mode[16 + 1];
8786
// forward declaration
8887
STATIC const pin_irq_obj_t pin_irq_obj[16];
8988

90-
// whether the irq is hard or soft
91-
STATIC bool pin_irq_is_hard[16];
92-
9389
void pin_init0(void) {
9490
ETS_GPIO_INTR_DISABLE();
9591
ETS_GPIO_INTR_ATTACH(pin_intr_handler_iram, NULL);
9692
// disable all interrupts
9793
memset(&MP_STATE_PORT(pin_irq_handler)[0], 0, 16 * sizeof(mp_obj_t));
98-
memset(pin_irq_is_hard, 0, sizeof(pin_irq_is_hard));
9994
for (int p = 0; p < 16; ++p) {
10095
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << p);
10196
SET_TRIGGER(p, 0);
10297
}
10398
ETS_GPIO_INTR_ENABLE();
10499
}
105100

106-
void pin_intr_handler(uint32_t status) {
101+
void MP_FASTCODE(pin_intr_handler)(uint32_t status) {
107102
status &= 0xffff;
108103
for (int p = 0; status; ++p, status >>= 1) {
109104
if (status & 1) {
110105
mp_obj_t handler = MP_STATE_PORT(pin_irq_handler)[p];
111106
if (handler != MP_OBJ_NULL) {
112-
if (pin_irq_is_hard[p]) {
113-
int orig_ets_loop_iter_disable = ets_loop_iter_disable;
114-
ets_loop_iter_disable = 1;
115-
mp_sched_lock();
116-
gc_lock();
117-
mp_call_function_1_protected(handler, MP_OBJ_FROM_PTR(&pyb_pin_obj[p]));
118-
gc_unlock();
119-
mp_sched_unlock();
120-
ets_loop_iter_disable = orig_ets_loop_iter_disable;
121-
} else {
122-
mp_sched_schedule(handler, MP_OBJ_FROM_PTR(&pyb_pin_obj[p]));
123-
}
107+
mp_sched_schedule(handler, MP_OBJ_FROM_PTR(&pyb_pin_obj[p]));
124108
}
125109
}
126110
}
@@ -390,6 +374,9 @@ STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
390374
if (self->phys_port >= 16) {
391375
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("pin does not have IRQ capabilities"));
392376
}
377+
if (args[ARG_hard].u_bool) {
378+
mp_raise_ValueError(MP_ERROR_TEXT("hard IRQ not supported"));
379+
}
393380

394381
if (n_args > 1 || kw_args->used != 0) {
395382
// configure irq
@@ -401,7 +388,6 @@ STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k
401388
}
402389
ETS_GPIO_INTR_DISABLE();
403390
MP_STATE_PORT(pin_irq_handler)[self->phys_port] = handler;
404-
pin_irq_is_hard[self->phys_port] = args[ARG_hard].u_bool;
405391
SET_TRIGGER(self->phys_port, trigger);
406392
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << self->phys_port);
407393
ETS_GPIO_INTR_ENABLE();

ports/esp8266/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,5 +192,6 @@ extern const struct _mp_obj_module_t mp_module_onewire;
192192

193193
#define MP_FASTCODE(n) __attribute__((section(".iram0.text." #n))) n
194194
#define MICROPY_WRAP_MP_KEYBOARD_INTERRUPT(f) MP_FASTCODE(f)
195+
#define MICROPY_WRAP_MP_SCHED_SCHEDULE(f) MP_FASTCODE(f)
195196

196197
#define _assert(expr) ((expr) ? (void)0 : __assert_func(__FILE__, __LINE__, __func__, #expr))

0 commit comments

Comments
 (0)
0