Skip to content

Commit d4a11af

Browse files
committed
Optimize ISR handler for performance, not size.
1 parent 1b42e1d commit d4a11af

File tree

1 file changed

+48
-38
lines changed

1 file changed

+48
-38
lines changed

cores/esp8266/core_esp8266_wiring_digital.cpp

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -134,44 +134,6 @@ extern "C" {
134134
static interrupt_handler_t interrupt_handlers[16];
135135
static uint32_t interrupt_reg = 0;
136136

137-
void ICACHE_RAM_ATTR interrupt_handler(void *arg, void *frame)
138-
{
139-
(void) arg;
140-
(void) frame;
141-
uint32_t status = GPIE;
142-
GPIEC = status;//clear them interrupts
143-
uint32_t levels = GPI;
144-
if (status == 0 || interrupt_reg == 0) return;
145-
ETS_GPIO_INTR_DISABLE();
146-
uint32_t i = 0;
147-
uint32_t changedbits = status & interrupt_reg;
148-
while (changedbits >= (1UL << i)) {
149-
while (!(changedbits & (1UL << i)))
150-
{
151-
++i;
152-
}
153-
const interrupt_handler_t& handler = interrupt_handlers[i];
154-
if (handler.mode == CHANGE ||
155-
(handler.mode & 1) == static_cast<bool>(levels & (1UL << i))) {
156-
// to make ISR compatible to Arduino AVR model where interrupts are disabled
157-
// we disable them before we call the client ISR
158-
esp8266::InterruptLock irqLock; // stop other interrupts
159-
handler.userFunc();
160-
}
161-
++i;
162-
}
163-
ETS_GPIO_INTR_ENABLE();
164-
}
165-
166-
void set_interrupt_reg(uint8_t pin, int mode)
167-
{
168-
interrupt_reg |= (1 << pin);
169-
GPC(pin) &= ~(0xF << GPCI);//INT mode disabled
170-
GPIEC = (1 << pin); //Clear Interrupt for this pin
171-
GPC(pin) |= ((mode & 0xF) << GPCI);//INT mode "mode"
172-
ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg);
173-
}
174-
175137
inline void isr_iram_assertion(voidFuncPtrArg userFunc)
176138
{
177139
// #5780
@@ -192,6 +154,17 @@ extern "C" {
192154
handler.mode = mode;
193155
}
194156

157+
void ICACHE_RAM_ATTR interrupt_handler(void *arg, void *frame);
158+
159+
void set_interrupt_reg(uint8_t pin, int mode)
160+
{
161+
interrupt_reg |= (1 << pin);
162+
GPC(pin) &= ~(0xF << GPCI);//INT mode disabled
163+
GPIEC = (1 << pin); //Clear Interrupt for this pin
164+
GPC(pin) |= ((mode & 0xF) << GPCI);//INT mode "mode"
165+
ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg);
166+
}
167+
195168
}
196169

197170
extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg const userFunc, void* const arg, int mode)
@@ -261,3 +234,40 @@ extern void attachInterrupt(uint8_t pin, Delegate<void(), void*> userFunc, int m
261234
ETS_GPIO_INTR_ENABLE();
262235
}
263236
}
237+
238+
// Speed critical bits
239+
#pragma GCC optimize ("O2")
240+
241+
namespace
242+
{
243+
244+
void ICACHE_RAM_ATTR interrupt_handler(void *arg, void *frame)
245+
{
246+
(void) arg;
247+
(void) frame;
248+
uint32_t status = GPIE;
249+
GPIEC = status;//clear them interrupts
250+
uint32_t levels = GPI;
251+
if (status == 0 || interrupt_reg == 0) return;
252+
ETS_GPIO_INTR_DISABLE();
253+
uint32_t i = 0;
254+
uint32_t changedbits = status & interrupt_reg;
255+
while (changedbits >= (1UL << i)) {
256+
while (!(changedbits & (1UL << i)))
257+
{
258+
++i;
259+
}
260+
const interrupt_handler_t& handler = interrupt_handlers[i];
261+
if (handler.mode == CHANGE ||
262+
(handler.mode & 1) == static_cast<bool>(levels & (1UL << i))) {
263+
// to make ISR compatible to Arduino AVR model where interrupts are disabled
264+
// we disable them before we call the client ISR
265+
esp8266::InterruptLock irqLock; // stop other interrupts
266+
handler.userFunc();
267+
}
268+
++i;
269+
}
270+
ETS_GPIO_INTR_ENABLE();
271+
}
272+
273+
}

0 commit comments

Comments
 (0)