diff --git a/README.md b/README.md index 007daa7..9c913d9 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Note: this list will probably change with each functionality update.   | `realtek-ambz` | `beken-72xx` --------------------|----------------|------------- Core functions | ✔️ | ✔️ -GPIO/PWM/IRQ | ✔️/✔️/✔️ | ❓/✔️/❌ +GPIO/PWM/IRQ | ✔️/✔️/✔️ | ✔️/✔️/✔️ Analog input (ADC) | ✔️ | ✔️ Serial | ✔️ | ✔️ Serial (extra) | 0, 1, 2 | 1, 2 diff --git a/arduino/beken-72xx/cores/arduino/wiring_irq.c b/arduino/beken-72xx/cores/arduino/wiring_irq.c new file mode 100644 index 0000000..8ccde62 --- /dev/null +++ b/arduino/beken-72xx/cores/arduino/wiring_irq.c @@ -0,0 +1,74 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-07-31. */ + +#include + +static void *irqHandlerList[PINS_COUNT] = {NULL}; +static void *irqHandlerArgs[PINS_COUNT] = {NULL}; + +static void irqHandler(unsigned char gpio) { + int pin = -1; + for (pin_size_t i = 0; i < PINS_COUNT; i++) { + if (pinTable[i].gpio == gpio) { + pin = i; + break; + } + } + if (pin == -1) + return; + if (!irqHandlerList[pin]) + return; + if (irqHandlerArgs[pin] == NULL) { + ((voidFuncPtr)irqHandlerList[pin])(); + } else { + ((voidFuncPtrParam)irqHandlerList[pin])(irqHandlerArgs[pin]); + } +} + +void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode) { + attachInterruptParam(interruptNumber, (voidFuncPtrParam)callback, mode, NULL); +} + +void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void *param) { + PinInfo *pin = pinInfo(interruptNumber); + if (!pin) + return; + if (!pinSupported(pin, PIN_IRQ)) + return; + uint32_t event = 0; + PinMode modeNew = 0; + switch (mode) { + case LOW: + event = GPIO_INT_LEVEL_LOW; + modeNew = INPUT_PULLUP; + break; + case HIGH: + event = GPIO_INT_LEVEL_HIGH; + modeNew = INPUT_PULLDOWN; + break; + case FALLING: + event = GPIO_INT_LEVEL_FALLING; + modeNew = INPUT_PULLUP; + break; + case RISING: + event = GPIO_INT_LEVEL_RISING; + modeNew = INPUT_PULLDOWN; + break; + default: + return; + } + irqHandlerList[interruptNumber] = callback; + irqHandlerArgs[interruptNumber] = param; + gpio_int_enable(pin->gpio, event, irqHandler); + pin->enabled |= PIN_IRQ | PIN_GPIO; + pin->mode = modeNew; +} + +void detachInterrupt(pin_size_t interruptNumber) { + PinInfo *pin = pinInfo(interruptNumber); + if (!pin) + return; + if (!pinSupported(pin, PIN_IRQ)) + return; + gpio_int_disable(pin->gpio); + pin->enabled &= ~PIN_IRQ; +} diff --git a/arduino/realtek-ambz/cores/arduino/WInterrupts.c b/arduino/realtek-ambz/cores/arduino/WInterrupts.c index bbb5f40..90a6cf4 100644 --- a/arduino/realtek-ambz/cores/arduino/WInterrupts.c +++ b/arduino/realtek-ambz/cores/arduino/WInterrupts.c @@ -10,9 +10,9 @@ static void *gpio_irq_handler_args[PINS_COUNT] = {NULL}; extern bool pinInvalid(pin_size_t pinNumber); extern void pinRemoveMode(pin_size_t pinNumber); -void gpioIrqHandler(uint32_t id, gpio_irq_event event) { +static void gpioIrqHandler(uint32_t id, gpio_irq_event event) { if (gpio_irq_handler_list[id] != NULL) { - if (gpio_irq_handler_args[id] != NULL) + if (gpio_irq_handler_args[id] == NULL) ((voidFuncPtr)gpio_irq_handler_list[id])(); else ((voidFuncPtrParam)gpio_irq_handler_list[id])(gpio_irq_handler_args[id]);