Skip to content

Commit 3cd9bd9

Browse files
committed
Refactor FunctionalInterrupt, undo removal of attachInterrupt() for functional arguments.
1 parent d0279f2 commit 3cd9bd9

File tree

3 files changed

+67
-80
lines changed

3 files changed

+67
-80
lines changed

Diff for: libraries/FunctionalInterrupt/examples/Functional/Functional.ino

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#include <FunctionalInterrupt.h>
22
#include <Arduino.h>
33

4+
#ifndef IRAM_ATTR
5+
#define IRAM_ATTR ICACHE_RAM_ATTR
6+
#endif
7+
48
#if defined(ESP32)
59
#define BUTTON1 16
610
#define BUTTON2 17
@@ -35,22 +39,12 @@ class Button {
3539
detachFunctionalInterrupt(PIN);
3640
}
3741

38-
#if defined(ESP8266)
39-
void ICACHE_RAM_ATTR isr()
40-
#elif defined(ESP32)
41-
void IRAM_ATTR isr()
42-
#endif
43-
{
42+
void IRAM_ATTR isr() {
4443
numberKeyPresses += 1;
4544
pressed = true;
4645
}
4746

48-
#if defined(ESP8266)
49-
static void ICACHE_RAM_ATTR isr_static(Button* const self)
50-
#elif defined(ESP32)
51-
static void IRAM_ATTR isr_static(Button* const self)
52-
#endif
53-
{
47+
static void IRAM_ATTR isr_static(Button* const self) {
5448
self->isr();
5549
}
5650

+53-45
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,73 @@
1-
#include <FunctionalInterrupt.h>
1+
#include "FunctionalInterrupt.h"
22
#include <Schedule.h>
3-
#include "Arduino.h"
3+
#include <Arduino.h>
44

5-
// Duplicate typedefs from core_esp8266_wiring_digital_c
6-
typedef void (*voidFuncPtr)(void);
7-
typedef void (*voidFuncPtrArg)(void*);
5+
namespace {
86

9-
// Helper functions for Functional interrupt routines
10-
extern "C" void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtr userFunc, void*fp, int mode, bool functional);
7+
struct ArgStructure
8+
{
9+
std::function<void()> function = nullptr;
10+
};
1111

12+
void ICACHE_RAM_ATTR interruptFunctional(void* arg)
13+
{
14+
ArgStructure* localArg = static_cast<ArgStructure*>(arg);
15+
localArg->function();
16+
}
1217

13-
void ICACHE_RAM_ATTR interruptFunctional(void* arg)
14-
{
15-
ArgStructure* localArg = (ArgStructure*)arg;
16-
if (localArg->functionInfo->reqScheduledFunction)
17-
{
18-
schedule_function(std::bind(localArg->functionInfo->reqScheduledFunction,InterruptInfo(*(localArg->interruptInfo))));
19-
}
20-
if (localArg->functionInfo->reqFunction)
21-
{
22-
localArg->functionInfo->reqFunction();
23-
}
24-
}
18+
void cleanupFunctional(void* arg)
19+
{
20+
ArgStructure* localArg = static_cast<ArgStructure*>(arg);
21+
delete localArg;
22+
}
2523

26-
extern "C"
27-
{
28-
void cleanupFunctional(void* arg)
29-
{
30-
ArgStructure* localArg = (ArgStructure*)arg;
31-
delete (FunctionInfo*)localArg->functionInfo;
32-
delete (InterruptInfo*)localArg->interruptInfo;
33-
delete localArg;
34-
}
3524
}
3625

3726
void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode)
3827
{
39-
// use the local interrupt routine which takes the ArgStructure as argument
40-
41-
InterruptInfo* ii = nullptr;
28+
void* localArg = detachInterruptArg(pin);
29+
if (localArg)
30+
{
31+
cleanupFunctional(localArg);
32+
}
4233

43-
FunctionInfo* fi = new FunctionInfo;
44-
fi->reqFunction = intRoutine;
34+
if (intRoutine)
35+
{
36+
ArgStructure* arg = new ArgStructure;
37+
arg->function = std::move(intRoutine);
4538

46-
ArgStructure* as = new ArgStructure;
47-
as->interruptInfo = ii;
48-
as->functionInfo = fi;
49-
50-
__attachInterruptFunctionalArg(pin, (voidFuncPtr)interruptFunctional, as, mode, true);
39+
attachInterruptArg(pin, interruptFunctional, arg, mode);
40+
}
5141
}
5242

5343
void attachScheduledInterrupt(uint8_t pin, std::function<void(InterruptInfo)> scheduledIntRoutine, int mode)
5444
{
55-
InterruptInfo* ii = new InterruptInfo;
45+
void* localArg = detachInterruptArg(pin);
46+
if (localArg)
47+
{
48+
cleanupFunctional(localArg);
49+
}
5650

57-
FunctionInfo* fi = new FunctionInfo;
58-
fi->reqScheduledFunction = scheduledIntRoutine;
51+
if (scheduledIntRoutine)
52+
{
53+
ArgStructure* arg = new ArgStructure;
54+
arg->function = [scheduledIntRoutine = std::move(scheduledIntRoutine), pin]()
55+
{
56+
InterruptInfo interruptInfo(pin);
57+
interruptInfo.value = digitalRead(pin);
58+
interruptInfo.micro = micros();
59+
schedule_function([scheduledIntRoutine, interruptInfo]() { scheduledIntRoutine(std::move(interruptInfo)); });
60+
};
5961

60-
ArgStructure* as = new ArgStructure;
61-
as->interruptInfo = ii;
62-
as->functionInfo = fi;
62+
attachInterruptArg(pin, interruptFunctional, arg, mode);
63+
}
64+
}
6365

64-
__attachInterruptFunctionalArg(pin, (voidFuncPtr)interruptFunctional, as, mode, true);
66+
void detachFunctionalInterrupt(uint8_t pin)
67+
{
68+
void* localArg = detachInterruptArg(pin);
69+
if (localArg)
70+
{
71+
cleanupFunctional(localArg);
72+
}
6573
}
+8-23
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,20 @@
11
#ifndef FUNCTIONALINTERRUPT_H
22
#define FUNCTIONALINTERRUPT_H
33

4-
#include <stddef.h>
5-
#include <stdint.h>
64
#include <functional>
75

8-
extern "C" {
9-
#include "c_types.h"
10-
#include "ets_sys.h"
11-
}
12-
136
// Structures for communication
147

15-
struct InterruptInfo {
16-
uint8_t pin = 0;
17-
uint8_t value = 0;
18-
uint32_t micro = 0;
19-
};
20-
21-
struct FunctionInfo {
22-
std::function<void(void)> reqFunction = nullptr;
23-
std::function<void(InterruptInfo)> reqScheduledFunction = nullptr;
24-
};
25-
26-
struct ArgStructure {
27-
InterruptInfo* interruptInfo = nullptr;
28-
FunctionInfo* functionInfo = nullptr;
8+
struct InterruptInfo
9+
{
10+
InterruptInfo(uint8_t _pin) : pin(_pin) {}
11+
const uint8_t pin;
12+
uint8_t value = 0;
13+
uint32_t micro = 0;
2914
};
3015

3116
void attachInterrupt(uint8_t pin, std::function<void(void)> intRoutine, int mode);
3217
void attachScheduledInterrupt(uint8_t pin, std::function<void(InterruptInfo)> scheduledIntRoutine, int mode);
18+
void detachFunctionalInterrupt(uint8_t pin);
3319

34-
35-
#endif //INTERRUPTS_H
20+
#endif //FUNCTIONALINTERRUPT_H

0 commit comments

Comments
 (0)