#include #include "mik32_hal_irq.h" #include "pins_arduino.h" #include "wiring_digital.h" #include "WInterrupts.h" extern void ErrorMsgHandler(const char * msg); typedef void (*voidFuncPtr)(void); // empty irq handler static void nothing(void) { ; } // enable global interrupts void interrupts(void) { HAL_IRQ_EnableInterrupts(); } // disable global interrupts void noInterrupts(void) { HAL_IRQ_DisableInterrupts(); } // we can provide no more than 8 interrupts on gpio at the same time static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS] = { #if EXTERNAL_NUM_INTERRUPTS > 7 nothing, #endif #if EXTERNAL_NUM_INTERRUPTS > 6 nothing, #endif #if EXTERNAL_NUM_INTERRUPTS > 5 nothing, #endif #if EXTERNAL_NUM_INTERRUPTS > 4 nothing, #endif #if EXTERNAL_NUM_INTERRUPTS > 3 nothing, #endif #if EXTERNAL_NUM_INTERRUPTS > 2 nothing, #endif nothing, nothing, }; void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) { // if the interrupt number does not exceed the total number if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { intFunc[interruptNum] = userFunc; // save pointer to irq handler // init pin as input without pullups pinMode(interruptToDigitalPin(interruptNum), INPUT); // interrupt line initialization HAL_GPIO_InterruptMode halMode; if (mode == LOW) halMode = GPIO_INT_MODE_LOW; else if (mode == HIGH) halMode = GPIO_INT_MODE_HIGH; else if (mode == CHANGE) halMode = GPIO_INT_MODE_CHANGE; else if (mode == FALLING) halMode = GPIO_INT_MODE_FALLING; else if (mode == RISING) halMode = GPIO_INT_MODE_RISING; else return; HAL_GPIO_InitInterruptLine(interruptToGpioIntMux(interruptNum), halMode); // turn on the mask in EPIC if ((halMode == GPIO_INT_MODE_LOW) || (halMode == GPIO_INT_MODE_HIGH)) // by level HAL_EPIC_MaskLevelSet(HAL_EPIC_GPIO_IRQ_MASK); else // by edge HAL_EPIC_MaskEdgeSet(HAL_EPIC_GPIO_IRQ_MASK); } else ErrorMsgHandler("attachInterrupt(): incorrect interrupt number\n\r"); } void detachInterrupt(uint8_t interruptNum) { if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { // disable the interrupt in line HAL_GPIO_DeInitInterruptLine(interruptToGpioIntLine(interruptNum)); intFunc[interruptNum] = nothing; // we don't change anything in the EPIC controller, in case there are still configured lines left } } // disable single interrupt void disableInterrupt(uint8_t interruptNum) { if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S; // disable gpio interrupt line GPIO_IRQ->ENABLE_CLEAR = (1 << irq_line_num); } } // enable single interrupt void enableInterrupt(uint8_t interruptNum) { if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { int irq_line_num = interruptToGpioIntLine(interruptNum) >> GPIO_IRQ_LINE_S; // enable gpio interrupt line GPIO_IRQ->ENABLE_SET = (1 << irq_line_num); } } // common gpio interrupt handler void gpio_interrupts_handler(void) { // go through all the interrupts and call the handler for the triggered line for (uint8_t i = 0; i < EXTERNAL_NUM_INTERRUPTS; i++) { if (HAL_GPIO_LineInterruptState(interruptToGpioIntLine(i))) intFunc[i](); } HAL_GPIO_ClearInterrupts(); }