From 4c926aa4c39bb68575cada3f8f78f2a177df0b78 Mon Sep 17 00:00:00 2001 From: Thaars Date: Tue, 9 Mar 2021 09:24:44 +0100 Subject: [PATCH 1/2] Update WInterrupts.c --- cores/nRF5/WInterrupts.c | 85 ++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/cores/nRF5/WInterrupts.c b/cores/nRF5/WInterrupts.c index 3ea3f1a9..634b4b63 100644 --- a/cores/nRF5/WInterrupts.c +++ b/cores/nRF5/WInterrupts.c @@ -32,6 +32,7 @@ static voidFuncPtr callbacksInt[NUMBER_OF_GPIO_TE]; static int8_t channelMap[NUMBER_OF_GPIO_TE]; +static voidFuncPtr callbackLowAccuracyInt; static int enabled = 0; /* Configure I/O interrupt sources */ @@ -39,6 +40,7 @@ static void __initialize() { memset(callbacksInt, 0, sizeof(callbacksInt)); memset(channelMap, -1, sizeof(channelMap)); + callbackLowAccuracyInt = NULL; NVIC_DisableIRQ(GPIOTE_IRQn); NVIC_ClearPendingIRQ(GPIOTE_IRQn); @@ -125,23 +127,84 @@ void detachInterrupt(uint32_t pin) } } +/* + * \brief Specifies a named Interrupt Service Routine (ISR) to call when an interrupt occurs. + * Replaces any previous function that was attached to the interrupt. + * Only one callback can be assigned to the low accuracy interrupt AKA PORT event. + */ +void attachInterruptLowAccuracy(uint32_t pin, voidFuncPtr callback, uint32_t mode) +{ + if (!enabled) { + __initialize(); + enabled = 1; + } + + if (pin >= PINS_COUNT) { + return; + } + + pin = g_ADigitalPinMap[pin]; + + uint32_t polarity; + + switch (mode) { + case FALLING: + NRF_GPIO->PIN_CNF[pin] |= ((uint32_t)GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos); + break; + + case RISING: + NRF_GPIO->PIN_CNF[pin] |= ((uint32_t)GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos); + break; + + default: + return; + } + + callbackLowAccuracyInt = callback; + NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk; +} + +/* + * \brief Turns off the given low accuracy interrupt. + */ +void detachInterruptLowAccuracy(uint32_t pin) +{ + if (pin >= PINS_COUNT) { + return; + } + + pin = g_ADigitalPinMap[pin]; + + callbackLowAccuracyInt = NULL; + + NRF_GPIO->PIN_CNF[pin] &= ~((uint32_t)GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + NRF_GPIOTE->INTENCLR = GPIOTE_INTENCLR_PORT_Msk; +} + void GPIOTE_IRQHandler() { - uint32_t event = offsetof(NRF_GPIOTE_Type, EVENTS_IN[0]); + if(NRF_GPIOTE->EVENTS_PORT == 1 && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_PORT_Msk)) { + if(callbackLowAccuracyInt) { + callbackLowAccuracyInt(); + } + NRF_GPIOTE->EVENTS_PORT = 0; + } else { + uint32_t event = offsetof(NRF_GPIOTE_Type, EVENTS_IN[0]); - for (int ch = 0; ch < NUMBER_OF_GPIO_TE; ch++) { - if ((*(uint32_t *)((uint32_t)NRF_GPIOTE + event) == 0x1UL) && (NRF_GPIOTE->INTENSET & (1 << ch))) { - if (channelMap[ch] != -1 && callbacksInt[ch]) { - callbacksInt[ch](); - } + for (int ch = 0; ch < NUMBER_OF_GPIO_TE; ch++) { + if ((*(uint32_t *)((uint32_t)NRF_GPIOTE + event) == 0x1UL) && (NRF_GPIOTE->INTENSET & (1 << ch))) { + if (channelMap[ch] != -1 && callbacksInt[ch]) { + callbacksInt[ch](); + } - *(uint32_t *)((uint32_t)NRF_GPIOTE + event) = 0; + *(uint32_t *)((uint32_t)NRF_GPIOTE + event) = 0; #if __CORTEX_M == 0x04 - volatile uint32_t dummy = *((volatile uint32_t *)((uint32_t)NRF_GPIOTE + event)); - (void)dummy; + volatile uint32_t dummy = *((volatile uint32_t *)((uint32_t)NRF_GPIOTE + event)); + (void)dummy; #endif - } + } - event = (uint32_t)((uint32_t)event + 4); + event = (uint32_t)((uint32_t)event + 4); + } } } From a2bbcab95617e6d5d6e24a7002b27b66b88f1dd7 Mon Sep 17 00:00:00 2001 From: Thaars Date: Tue, 9 Mar 2021 09:26:49 +0100 Subject: [PATCH 2/2] Update WInterrupts.h --- cores/nRF5/WInterrupts.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cores/nRF5/WInterrupts.h b/cores/nRF5/WInterrupts.h index 5d2b24a0..273dc3a9 100644 --- a/cores/nRF5/WInterrupts.h +++ b/cores/nRF5/WInterrupts.h @@ -47,6 +47,18 @@ void attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode); */ void detachInterrupt(uint32_t pin); +/* + * \brief Specifies a named Interrupt Service Routine (ISR) to call when an interrupt occurs. + * Replaces any previous function that was attached to the interrupt. + * Only one callback can be assigned to the low accuracy interrupt AKA PORT event. + */ +void attachInterruptLowAccuracy(uint32_t pin, voidFuncPtr callback, uint32_t mode); + +/* + * \brief Turns off the given low accuracy interrupt. + */ +void detachInterruptLowAccuracy(uint32_t pin); + #ifdef __cplusplus } #endif