Skip to content

FunctionalInterrupt/ScheduledFunctions should be in a library, not in core_esp8266_wiring_digital #6038

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3720f4d
Remove special support for FunctionalInterrupt from core interrupt ha…
dok-net May 2, 2019
e4f6e6c
Add supporting function for interrupt arg memory management, linke wi…
dok-net May 2, 2019
035551d
Bring back FunctionalInterrupt, and ScheduledFunctions, as example code.
dok-net May 2, 2019
bd339ec
Ridiculous port number mistake.
dok-net May 2, 2019
f4acddb
Merge branch 'master' into functional-shouldbe-lib
dok-net May 2, 2019
4f621ea
Apply astyle to example INO.
dok-net May 2, 2019
6002811
Merge branch 'master' into functional-shouldbe-lib
dok-net May 2, 2019
4b045f5
Remove ScheduledFunctions.(h|cpp), per comment https://github.com/esp…
dok-net May 2, 2019
e7013ba
Merge remote-tracking branch 'origin/master' into functional-shouldbe…
dok-net May 2, 2019
9e239ec
Invented void* detachInterruptArg() that returns the argument given i…
dok-net May 3, 2019
f89b22c
Modified example to showcase how general FunctionalInterrupt uses vio…
dok-net May 3, 2019
346d3c3
Direct call or scheduled is either-or.
dok-net May 3, 2019
a844d43
Always apply astyle to examples.
dok-net May 3, 2019
eb6c493
Merge branch 'master' into functional-shouldbe-lib
dok-net May 3, 2019
17e3692
Merge branch 'master' into functional-shouldbe-lib
dok-net May 3, 2019
f5092c6
Merge branch 'master' into functional-shouldbe-lib
dok-net May 4, 2019
e619e4c
Merge branch 'master' into functional-shouldbe-lib
dok-net May 4, 2019
69ac313
Merge branch 'master' into functional-shouldbe-lib
dok-net May 4, 2019
fe56dc6
Merge branch 'master' into functional-shouldbe-lib
dok-net May 4, 2019
db7b1b1
Merge branch 'master' into functional-shouldbe-lib
dok-net May 5, 2019
c8c8bfb
astyle Arduino.h and core_esp8266_wiring_digital.cpp - reduced diff t…
dok-net May 6, 2019
6a33d99
astyle libraries/esp8266/examples/GPIO/FunctionalInterrupt
dok-net May 6, 2019
dd066c9
Merge branch 'master' into functional-shouldbe-lib
dok-net May 9, 2019
6a58725
Merge branch 'master' into functional-shouldbe-lib
dok-net May 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cores/esp8266/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);

void attachInterrupt(uint8_t pin, void (*)(void), int mode);
void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode);
void detachInterrupt(uint8_t pin);

void preinit(void);
Expand Down
71 changes: 0 additions & 71 deletions cores/esp8266/FunctionalInterrupt.cpp

This file was deleted.

85 changes: 29 additions & 56 deletions cores/esp8266/core_esp8266_wiring_digital.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@ extern void __pinMode(uint8_t pin, uint8_t mode) {
GPEC = (1 << pin); //Disable
GPC(pin) = (GPC(pin) & (0xF << GPCI)) | (1 << GPCD); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED)
if(mode == INPUT_PULLUP) {
GPF(pin) |= (1 << GPFPU); // Enable Pullup
GPF(pin) |= (1 << GPFPU); // Enable Pullup
}
} else if(mode == WAKEUP_PULLUP || mode == WAKEUP_PULLDOWN){
GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO
GPEC = (1 << pin); //Disable
if(mode == WAKEUP_PULLUP) {
GPF(pin) |= (1 << GPFPU); // Enable Pullup
GPC(pin) = (1 << GPCD) | (4 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(LOW) | WAKEUP_ENABLE(ENABLED)
GPF(pin) |= (1 << GPFPU); // Enable Pullup
GPC(pin) = (1 << GPCD) | (4 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(LOW) | WAKEUP_ENABLE(ENABLED)
} else {
GPF(pin) |= (1 << GPFPD); // Enable Pulldown
GPC(pin) = (1 << GPCD) | (5 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(HIGH) | WAKEUP_ENABLE(ENABLED)
GPF(pin) |= (1 << GPFPD); // Enable Pulldown
GPC(pin) = (1 << GPCD) | (5 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(HIGH) | WAKEUP_ENABLE(ENABLED)
}
}
} else if(pin == 16){
Expand Down Expand Up @@ -109,27 +109,14 @@ typedef void (*voidFuncPtrArg)(void*);

typedef struct {
uint8_t mode;
void (*fn)(void);
void * arg;
voidFuncPtr fn;
void* arg;
} interrupt_handler_t;

//duplicate from functionalInterrupt.h keep in sync
typedef struct InterruptInfo {
uint8_t pin;
uint8_t value;
uint32_t micro;
} InterruptInfo;

typedef struct {
InterruptInfo* interruptInfo;
void* functionInfo;
} ArgStructure;

static interrupt_handler_t interrupt_handlers[16];
static interrupt_handler_t interrupt_handlers[16] = { {0, 0, 0}, };
static uint32_t interrupt_reg = 0;

void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
(void) arg;
void ICACHE_RAM_ATTR interrupt_handler(void*) {
uint32_t status = GPIE;
GPIEC = status;//clear them interrupts
uint32_t levels = GPI;
Expand All @@ -140,38 +127,28 @@ void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
while(changedbits){
while(!(changedbits & (1 << i))) i++;
changedbits &= ~(1 << i);
interrupt_handler_t *handler = &interrupt_handlers[i];
interrupt_handler_t* handler = &interrupt_handlers[i];
if (handler->fn &&
(handler->mode == CHANGE ||
(handler->mode & 1) == !!(levels & (1 << i)))) {
(handler->mode == CHANGE ||
(handler->mode & 1) == !!(levels & (1 << i)))) {
// to make ISR compatible to Arduino AVR model where interrupts are disabled
// we disable them before we call the client ISR
uint32_t savedPS = xt_rsil(15); // stop other interrupts
ArgStructure* localArg = (ArgStructure*)handler->arg;
if (localArg && localArg->interruptInfo)
{
localArg->interruptInfo->pin = i;
localArg->interruptInfo->value = __digitalRead(i);
localArg->interruptInfo->micro = micros();
}
if (handler->arg)
{
((voidFuncPtrArg)handler->fn)(handler->arg);
((voidFuncPtrArg)handler->fn)(handler->arg);
}
else
{
handler->fn();
handler->fn();
}
xt_wsr_ps(savedPS);
xt_wsr_ps(savedPS);
}
}
ETS_GPIO_INTR_ENABLE();
}

extern void cleanupFunctional(void* arg);

extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFunc, void *arg, int mode) {

extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void* arg, int mode) {
// #5780
// https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map
if ((uint32_t)userFunc >= 0x40200000)
Expand All @@ -183,13 +160,9 @@ extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFu

if(pin < 16) {
ETS_GPIO_INTR_DISABLE();
interrupt_handler_t *handler = &interrupt_handlers[pin];
interrupt_handler_t* handler = &interrupt_handlers[pin];
handler->mode = mode;
handler->fn = userFunc;
if (handler->arg) // Clean when new attach without detach
{
cleanupFunctional(handler->arg);
}
handler->fn = (voidFuncPtr)userFunc;
handler->arg = arg;
interrupt_reg |= (1 << pin);
GPC(pin) &= ~(0xF << GPCI);//INT mode disabled
Expand All @@ -200,30 +173,29 @@ extern void ICACHE_RAM_ATTR __attachInterruptArg(uint8_t pin, voidFuncPtr userFu
}
}

extern void ICACHE_RAM_ATTR __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int mode )
{
__attachInterruptArg (pin, userFunc, 0, mode);
extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int mode ) {
__attachInterruptArg(pin, (voidFuncPtrArg)userFunc, 0, mode);
}

extern void ICACHE_RAM_ATTR __detachInterrupt(uint8_t pin) {
extern void __detachInterrupt(uint8_t pin) {
if(pin < 16) {
ETS_GPIO_INTR_DISABLE();
GPC(pin) &= ~(0xF << GPCI);//INT mode disabled
GPIEC = (1 << pin); //Clear Interrupt for this pin
interrupt_reg &= ~(1 << pin);
interrupt_handler_t *handler = &interrupt_handlers[pin];
interrupt_handler_t* handler = &interrupt_handlers[pin];
handler->mode = 0;
handler->fn = 0;
if (handler->arg)
{
cleanupFunctional(handler->arg);
}
handler->arg = 0;
handler->fn = nullptr;
handler->arg = nullptr;
if (interrupt_reg)
ETS_GPIO_INTR_ENABLE();
}
}

extern interrupt_handler_t* __getInterruptHandler(uint8_t pin) {
return (pin < 16) ? &interrupt_handlers[pin] : nullptr;
}

void initPins() {
//Disable UART interrupts
system_set_os_print(0);
Expand All @@ -243,6 +215,7 @@ extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pi
extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite")));
extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")));
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void* arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));

};
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include <Arduino.h>
#include "FunctionalInterrupts.h"

#if defined(ESP32)
#define BUTTON1 16
#define BUTTON2 17
#elif defined(ARDUINO_ESP8266_WEMOS_D1MINI)
#define BUTTON1 D4
#define BUTTON2 D3
#else
#define BUTTON1 2
#define BUTTON2 0
#endif

class Button {
public:
Button(uint8_t reqPin) : PIN(reqPin) {
pinMode(PIN, INPUT_PULLUP);
attachInterrupt(PIN, std::bind(&Button::isr, this), FALLING);
};
~Button() {
detachFunctionalInterrupt(PIN);
}

#if defined(ESP8266)
void ICACHE_RAM_ATTR isr()
#elif defined(ESP32)
void IRAM_ATTR isr()
#endif
{
numberKeyPresses += 1;
pressed = true;
}

void checkPressed() {
if (pressed) {
Serial.printf("Button on pin %u has been pressed %u times\n", PIN, numberKeyPresses);
pressed = false;
}
}

private:
const uint8_t PIN;
volatile uint32_t numberKeyPresses;
volatile bool pressed;
};

Button button1(BUTTON1);
Button button2(BUTTON2);


void setup() {
Serial.begin(115200);
}

void loop() {
button1.checkPressed();
button2.checkPressed();
}
Loading