summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Leech <andrew@alelec.net>2022-04-30 12:45:43 +1000
committerDamien George <damien@micropython.org>2022-06-03 14:29:11 +1000
commit05f927b624474d3f89639ed8a93e98da9f49ba11 (patch)
tree6b4cda9cc3efce6d4e1ffedc8c8c1dd79a1508a1
parent9bd6169b7293d4b996ecbb1a53b6079a508d826a (diff)
rp2/machine_pin: Add mp_hal_pin_interrupt C interface.
So C can can easily configure a pin interrupt and callback. Signed-off-by: Andrew Leech <andrew@alelec.net>
-rw-r--r--ports/rp2/machine_pin.c70
-rw-r--r--ports/rp2/mphalport.h10
2 files changed, 51 insertions, 29 deletions
diff --git a/ports/rp2/machine_pin.c b/ports/rp2/machine_pin.c
index aa3cad6ef..ca8de6ce2 100644
--- a/ports/rp2/machine_pin.c
+++ b/ports/rp2/machine_pin.c
@@ -313,50 +313,62 @@ STATIC mp_obj_t machine_pin_toggle(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_pin_toggle_obj, machine_pin_toggle);
-// pin.irq(handler=None, trigger=IRQ_FALLING|IRQ_RISING, hard=False)
-STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_handler, ARG_trigger, ARG_hard };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_handler, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
- { MP_QSTR_trigger, MP_ARG_INT, {.u_int = GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE} },
- { MP_QSTR_hard, MP_ARG_BOOL, {.u_bool = false} },
- };
- machine_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
+STATIC machine_pin_irq_obj_t *machine_pin_get_irq(mp_hal_pin_obj_t pin) {
// Get the IRQ object.
- machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_obj[self->id]);
+ machine_pin_irq_obj_t *irq = MP_STATE_PORT(machine_pin_irq_obj[pin]);
// Allocate the IRQ object if it doesn't already exist.
if (irq == NULL) {
irq = m_new_obj(machine_pin_irq_obj_t);
irq->base.base.type = &mp_irq_type;
irq->base.methods = (mp_irq_methods_t *)&machine_pin_irq_methods;
- irq->base.parent = MP_OBJ_FROM_PTR(self);
+ irq->base.parent = MP_OBJ_FROM_PTR(&machine_pin_obj[pin]);
irq->base.handler = mp_const_none;
irq->base.ishard = false;
- MP_STATE_PORT(machine_pin_irq_obj[self->id]) = irq;
+ MP_STATE_PORT(machine_pin_irq_obj[pin]) = irq;
}
+ return irq;
+}
- if (n_args > 1 || kw_args->used != 0) {
- // Configure IRQ.
+void mp_hal_pin_interrupt(mp_hal_pin_obj_t pin, mp_obj_t handler, mp_uint_t trigger, bool hard) {
+ machine_pin_irq_obj_t *irq = machine_pin_get_irq(pin);
- // Disable all IRQs while data is updated.
- gpio_set_irq_enabled(self->id, GPIO_IRQ_ALL, false);
+ // Disable all IRQs while data is updated.
+ gpio_set_irq_enabled(pin, GPIO_IRQ_ALL, false);
- // Update IRQ data.
- irq->base.handler = args[ARG_handler].u_obj;
- irq->base.ishard = args[ARG_hard].u_bool;
- irq->flags = 0;
- irq->trigger = args[ARG_trigger].u_int;
-
- // Enable IRQ if a handler is given.
- if (args[ARG_handler].u_obj != mp_const_none) {
- gpio_set_irq_enabled(self->id, args[ARG_trigger].u_int, true);
- }
+ // Update IRQ data.
+ irq->base.handler = handler;
+ irq->base.ishard = hard;
+ irq->flags = 0;
+ irq->trigger = trigger;
+
+ // Enable IRQ if a handler is given.
+ if (handler != mp_const_none && trigger != MP_HAL_PIN_TRIGGER_NONE) {
+ gpio_set_irq_enabled(pin, trigger, true);
}
+}
+// pin.irq(handler=None, trigger=IRQ_FALLING|IRQ_RISING, hard=False)
+STATIC mp_obj_t machine_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_handler, ARG_trigger, ARG_hard };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_handler, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} },
+ { MP_QSTR_trigger, MP_ARG_INT, {.u_int = MP_HAL_PIN_TRIGGER_FALL | MP_HAL_PIN_TRIGGER_RISE} },
+ { MP_QSTR_hard, MP_ARG_BOOL, {.u_bool = false} },
+ };
+ machine_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ machine_pin_irq_obj_t *irq = machine_pin_get_irq(self->id);
+
+ if (n_args > 1 || kw_args->used != 0) {
+ // Update IRQ data.
+ mp_obj_t handler = args[ARG_handler].u_obj;
+ mp_uint_t trigger = args[ARG_trigger].u_int;
+ bool hard = args[ARG_hard].u_bool;
+ mp_hal_pin_interrupt(self->id, handler, trigger, hard);
+ }
return MP_OBJ_FROM_PTR(irq);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_pin_irq_obj, 1, machine_pin_irq);
diff --git a/ports/rp2/mphalport.h b/ports/rp2/mphalport.h
index 458d9a9a1..0aebf7d74 100644
--- a/ports/rp2/mphalport.h
+++ b/ports/rp2/mphalport.h
@@ -126,4 +126,14 @@ static inline void mp_hal_pin_high(mp_hal_pin_obj_t pin) {
gpio_set_mask(1 << pin);
}
+enum mp_hal_pin_interrupt_trigger {
+ MP_HAL_PIN_TRIGGER_NONE,
+ MP_HAL_PIN_TRIGGER_LOW = GPIO_IRQ_LEVEL_LOW,
+ MP_HAL_PIN_TRIGGER_HIGH = GPIO_IRQ_LEVEL_HIGH,
+ MP_HAL_PIN_TRIGGER_FALL = GPIO_IRQ_EDGE_FALL,
+ MP_HAL_PIN_TRIGGER_RISE = GPIO_IRQ_EDGE_RISE,
+};
+
+void mp_hal_pin_interrupt(mp_hal_pin_obj_t pin, mp_obj_t handler, mp_uint_t trigger, bool hard);
+
#endif // MICROPY_INCLUDED_RP2_MPHALPORT_H