Skip to content

Commit 011edf2

Browse files
committed
Clean up interrupt handling for pulseio.PulseIn implementation for #716 ESP8266
1 parent c4cf1c5 commit 011edf2

File tree

4 files changed

+40
-22
lines changed

4 files changed

+40
-22
lines changed

ports/esp8266/common-hal/microcontroller/Pin.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* THE SOFTWARE.
2525
*/
2626

27+
#include "shared-bindings/microcontroller/__init__.h"
2728
#include "common-hal/microcontroller/__init__.h"
2829
#include "common-hal/microcontroller/Pin.h"
2930
#include "shared-bindings/microcontroller/Pin.h"
@@ -35,6 +36,28 @@
3536
bool adc_in_use;
3637
bool gpio16_in_use;
3738

39+
typedef struct {
40+
void (*func)(void *);
41+
void *data;
42+
} pin_intr_handler_t;
43+
44+
static pin_intr_handler_t _pin_intr_handlers[GPIO_PIN_COUNT];
45+
46+
void microcontroller_pin_call_intr_handlers(uint32_t status) {
47+
status &= (1 << GPIO_PIN_COUNT) - 1;
48+
for (int p = 0; status; ++p, status >>= 1) {
49+
if ((status & 1) && _pin_intr_handlers[p].func) {
50+
_pin_intr_handlers[p].func(_pin_intr_handlers[p].data);
51+
}
52+
}
53+
}
54+
55+
void microcontroller_pin_register_intr_handler(uint8_t gpio_number, void (*func)(void *), void *data) {
56+
common_hal_mcu_disable_interrupts();
57+
_pin_intr_handlers[gpio_number] = (pin_intr_handler_t){ func, data };
58+
common_hal_mcu_enable_interrupts();
59+
}
60+
3861
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) {
3962
if (pin == &pin_TOUT) {
4063
return !adc_in_use;
@@ -92,4 +115,4 @@ void reset_pins(void) {
92115

93116
adc_in_use = false;
94117
gpio16_in_use = false;
95-
}
118+
}

ports/esp8266/common-hal/microcontroller/Pin.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,7 @@ void claim_pin(const mcu_pin_obj_t* pin);
4545
void reset_pin(const mcu_pin_obj_t* pin);
4646
void reset_pins(void);
4747

48+
void microcontroller_pin_register_intr_handler(uint8_t gpio_number, void (*func)(void *), void *data);
49+
void microcontroller_pin_call_intr_handlers(uint32_t status);
50+
4851
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H

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

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@
3737
#include "shared-bindings/pulseio/PulseIn.h"
3838
#include "common-hal/microcontroller/__init__.h"
3939

40-
// XXX map gpio pins to pulsein objects: kinda clumsy.
41-
static pulseio_pulsein_obj_t *pulseio_pulsein_objs[GPIO_PIN_COUNT] = {0};
42-
4340
static void pulsein_set_interrupt(pulseio_pulsein_obj_t *self, bool rising, bool falling) {
4441
ETS_GPIO_INTR_DISABLE();
4542
// Set interrupt mode
@@ -55,7 +52,9 @@ static void pulsein_set_interrupt(pulseio_pulsein_obj_t *self, bool rising, bool
5552
ETS_GPIO_INTR_ENABLE();
5653
}
5754

58-
void pulseio_pulsein_interrupt_handler(pulseio_pulsein_obj_t *self, uint32_t time_us) {
55+
void pulseio_pulsein_interrupt_handler(void *data) {
56+
pulseio_pulsein_obj_t *self = data;
57+
uint32_t time_us = system_get_time();
5958
if (self->first_edge) {
6059
self->first_edge = false;
6160
pulsein_set_interrupt(self, true, true);
@@ -72,18 +71,6 @@ void pulseio_pulsein_interrupt_handler(pulseio_pulsein_obj_t *self, uint32_t tim
7271
self->last_us = time_us;
7372
}
7473

75-
// XXX needs a better name, or a better abstraction
76-
// XXX called from intr.c:pin_intr_handler_iram ... inelegantly
77-
void pulsein_interrupt_handler(uint32_t status) {
78-
uint32_t time_us = system_get_time();
79-
for (int i=0; i<GPIO_PIN_COUNT; i++) {
80-
if (status & 1<<i) {
81-
pulseio_pulsein_obj_t *self = pulseio_pulsein_objs[i];
82-
if (self) pulseio_pulsein_interrupt_handler(self, time_us);
83-
}
84-
}
85-
}
86-
8774
void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
8875
const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) {
8976
if (pin->gpio_number == NO_GPIO || pin->gpio_function == SPECIAL_CASE) {
@@ -104,19 +91,22 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
10491
self->len = 0;
10592
self->first_edge = true;
10693
self->last_us = 0;
107-
pulseio_pulsein_objs[self->pin->gpio_number] = self;
94+
95+
microcontroller_pin_register_intr_handler(self->pin->gpio_number,
96+
pulseio_pulsein_interrupt_handler, (void *)self);
10897
pulsein_set_interrupt(self, !idle_state, idle_state);
10998
}
11099

111100
bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) {
112-
return pulseio_pulsein_objs[self->pin->gpio_number] == NULL;
101+
return self->buffer == NULL;
113102
}
114103

115104
void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
116105
pulsein_set_interrupt(self, false, false);
117-
pulseio_pulsein_objs[self->pin->gpio_number] = NULL;
106+
microcontroller_pin_register_intr_handler(self->pin->gpio_number, NULL, NULL);
118107
PIN_FUNC_SELECT(self->pin->peripheral, 0);
119108
m_free(self->buffer);
109+
self->buffer = NULL;
120110
}
121111

122112
void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) {

ports/esp8266/intr.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@
3434
void pin_intr_handler_iram(void *arg) {
3535
uint32_t status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
3636
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, status);
37+
38+
// machine.Pin handlers
3739
pin_intr_handler(status);
3840

39-
// XXX bit of a hack
40-
pulsein_interrupt_handler(status);
41+
// microcontroller.Pin handlers
42+
microcontroller_pin_call_intr_handlers(status);
4143
}

0 commit comments

Comments
 (0)