#pragma once #include #include #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; static std::array 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(); } */ };