119 lines
5.4 KiB
C++

#pragma once
#include <cstddef>
#include <functional>
#include "esp_attr.h"
#define ISR_TRAMPOLINE_FUNC(slot) \
static void IRAM_ATTR trampoline##slot() { static const int DRAM_ATTR i = slot; auto &f = IsrTrampolines::functions[i]; if (f) f(); }
class IsrTrampolines {
public:
typedef std::size_t SlotNumber;
static constexpr SlotNumber MAX_SLOTS = 32;
using TrampolinePointer = void (*)();
using VoidFunction = std::function<void()>;
static std::array<VoidFunction, MAX_SLOTS> functions;
static void (*const trampolines[MAX_SLOTS])();
static bool registerSlot(VoidFunction f, SlotNumber& slotRegistered) {
for (SlotNumber slot = 0; slot < MAX_SLOTS; ++slot) {
if (!functions[slot]) {
slotRegistered = slot;
functions[slot] = f;
return true;
}
}
return false;
}
static bool unregisterSlot(const SlotNumber slotRegistered) {
if (!functions[slotRegistered]) {
return false;
}
functions[slotRegistered] = nullptr;
return true;
}
static TrampolinePointer getForSlot(const SlotNumber slotRegistered) {
if (slotRegistered < MAX_SLOTS) {
return trampolines[slotRegistered];
}
return nullptr;
}
// Unfortunately, these cannot be templated because the linker cannot correctly handle
// its integer constant indexing the function table (dangerous relocation)
ISR_TRAMPOLINE_FUNC(0);
ISR_TRAMPOLINE_FUNC(1);
ISR_TRAMPOLINE_FUNC(2);
ISR_TRAMPOLINE_FUNC(3);
ISR_TRAMPOLINE_FUNC(4);
ISR_TRAMPOLINE_FUNC(5);
ISR_TRAMPOLINE_FUNC(6);
ISR_TRAMPOLINE_FUNC(7);
ISR_TRAMPOLINE_FUNC(8);
ISR_TRAMPOLINE_FUNC(9);
ISR_TRAMPOLINE_FUNC(10);
ISR_TRAMPOLINE_FUNC(11);
ISR_TRAMPOLINE_FUNC(12);
ISR_TRAMPOLINE_FUNC(13);
ISR_TRAMPOLINE_FUNC(14);
ISR_TRAMPOLINE_FUNC(15);
ISR_TRAMPOLINE_FUNC(16);
ISR_TRAMPOLINE_FUNC(17);
ISR_TRAMPOLINE_FUNC(18);
ISR_TRAMPOLINE_FUNC(19);
ISR_TRAMPOLINE_FUNC(20);
ISR_TRAMPOLINE_FUNC(21);
ISR_TRAMPOLINE_FUNC(22);
ISR_TRAMPOLINE_FUNC(23);
ISR_TRAMPOLINE_FUNC(24);
ISR_TRAMPOLINE_FUNC(25);
ISR_TRAMPOLINE_FUNC(26);
ISR_TRAMPOLINE_FUNC(27);
ISR_TRAMPOLINE_FUNC(28);
ISR_TRAMPOLINE_FUNC(29);
ISR_TRAMPOLINE_FUNC(30);
ISR_TRAMPOLINE_FUNC(31);
/*static void IRAM_ATTR trampoline0() ISR_TRAMPOLINE_FUNC(0)
static void IRAM_ATTR trampoline1() { auto &f = IsrTrampolines::functions[1]; if (f) f(); }
static void IRAM_ATTR trampoline2() { auto &f = IsrTrampolines::functions[2]; if (f) f(); }
static void IRAM_ATTR trampoline3() { auto &f = IsrTrampolines::functions[3]; if (f) f(); }
static void IRAM_ATTR trampoline4() { auto &f = IsrTrampolines::functions[4]; if (f) f(); }
static void IRAM_ATTR trampoline5() { auto &f = IsrTrampolines::functions[5]; if (f) f(); }
static void IRAM_ATTR trampoline6() { auto &f = IsrTrampolines::functions[6]; if (f) f(); }
static void IRAM_ATTR trampoline7() { auto &f = IsrTrampolines::functions[7]; if (f) f(); }
static void IRAM_ATTR trampoline8() { auto &f = IsrTrampolines::functions[8]; if (f) f(); }
static void IRAM_ATTR trampoline9() { auto &f = IsrTrampolines::functions[9]; if (f) f(); }
static void IRAM_ATTR trampoline10() { auto &f = IsrTrampolines::functions[10]; if (f) f(); }
static void IRAM_ATTR trampoline11() { auto &f = IsrTrampolines::functions[11]; if (f) f(); }
static void IRAM_ATTR trampoline12() { auto &f = IsrTrampolines::functions[12]; if (f) f(); }
static void IRAM_ATTR trampoline13() { auto &f = IsrTrampolines::functions[13]; if (f) f(); }
static void IRAM_ATTR trampoline14() { auto &f = IsrTrampolines::functions[14]; if (f) f(); }
static void IRAM_ATTR trampoline15() { auto &f = IsrTrampolines::functions[15]; if (f) f(); }
static void IRAM_ATTR trampoline16() { auto &f = IsrTrampolines::functions[16]; if (f) f(); }
static void IRAM_ATTR trampoline17() { auto &f = IsrTrampolines::functions[17]; if (f) f(); }
static void IRAM_ATTR trampoline18() { auto &f = IsrTrampolines::functions[18]; if (f) f(); }
static void IRAM_ATTR trampoline19() { auto &f = IsrTrampolines::functions[19]; if (f) f(); }
static void IRAM_ATTR trampoline20() { auto &f = IsrTrampolines::functions[20]; if (f) f(); }
static void IRAM_ATTR trampoline21() { auto &f = IsrTrampolines::functions[21]; if (f) f(); }
static void IRAM_ATTR trampoline22() { auto &f = IsrTrampolines::functions[22]; if (f) f(); }
static void IRAM_ATTR trampoline23() { auto &f = IsrTrampolines::functions[23]; if (f) f(); }
static void IRAM_ATTR trampoline24() { auto &f = IsrTrampolines::functions[24]; if (f) f(); }
static void IRAM_ATTR trampoline25() { auto &f = IsrTrampolines::functions[25]; if (f) f(); }
static void IRAM_ATTR trampoline26() { auto &f = IsrTrampolines::functions[26]; if (f) f(); }
static void IRAM_ATTR trampoline27() { auto &f = IsrTrampolines::functions[27]; if (f) f(); }
static void IRAM_ATTR trampoline28() { auto &f = IsrTrampolines::functions[28]; if (f) f(); }
static void IRAM_ATTR trampoline29() { auto &f = IsrTrampolines::functions[29]; if (f) f(); }
static void IRAM_ATTR trampoline30() { auto &f = IsrTrampolines::functions[30]; if (f) f(); }
static void IRAM_ATTR trampoline31() { auto &f = IsrTrampolines::functions[31]; if (f) f(); }
*/
};