Sx1262: Fixed DIO1 ISR registration by bypassing RadioLib

This commit is contained in:
Dominic Höglinger 2025-09-14 11:31:02 +02:00
parent 1ab7c4ce9a
commit 9f05bcf066
4 changed files with 26 additions and 168 deletions

View File

@ -1,38 +0,0 @@
#include "IsrTrampoline.h"
std::array<IsrTrampolines::VoidFunction, IsrTrampolines::MAX_SLOTS> IsrTrampolines::functions{};
void (*const IsrTrampolines::trampolines[IsrTrampolines::MAX_SLOTS])() = {
&IsrTrampolines::trampoline0,
&IsrTrampolines::trampoline1,
&IsrTrampolines::trampoline2,
&IsrTrampolines::trampoline3,
&IsrTrampolines::trampoline4,
&IsrTrampolines::trampoline5,
&IsrTrampolines::trampoline6,
&IsrTrampolines::trampoline7,
&IsrTrampolines::trampoline8,
&IsrTrampolines::trampoline9,
&IsrTrampolines::trampoline10,
&IsrTrampolines::trampoline11,
&IsrTrampolines::trampoline12,
&IsrTrampolines::trampoline13,
&IsrTrampolines::trampoline14,
&IsrTrampolines::trampoline15,
&IsrTrampolines::trampoline16,
&IsrTrampolines::trampoline17,
&IsrTrampolines::trampoline18,
&IsrTrampolines::trampoline19,
&IsrTrampolines::trampoline20,
&IsrTrampolines::trampoline21,
&IsrTrampolines::trampoline22,
&IsrTrampolines::trampoline23,
&IsrTrampolines::trampoline24,
&IsrTrampolines::trampoline25,
&IsrTrampolines::trampoline26,
&IsrTrampolines::trampoline27,
&IsrTrampolines::trampoline28,
&IsrTrampolines::trampoline29,
&IsrTrampolines::trampoline30,
&IsrTrampolines::trampoline31
};

View File

@ -1,118 +0,0 @@
#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(); }
*/
};

View File

@ -1,8 +1,13 @@
#include "Sx1262.h"
#include <cstring>
#include "hal/gpio_hal.h"
constexpr const char* TAG = "LoraDevice";
constexpr const char* TAG = "Sx1262";
void IRAM_ATTR dio1handler(void* context) {
((Sx1262*)context)->setRxEvent();
}
bool Sx1262::configure(const Parameter parameter, const float value) {
using enum Parameter;
@ -42,8 +47,19 @@ bool Sx1262::configure(const Parameter parameter, const float value) {
return false;
}
void Sx1262::onReceive() {
getEventFlag().set(RADIO_RECEIVED_BIT);
void Sx1262::registerDio1Isr() {
// We cannot use the RadioLib API to register this action,
// as it does not have the capability to pass an instance pointer via context.
// A trampoline has been tried, but is not linkable to be in IRAM_ATTR (dangerous relocation).
gpio_install_isr_service((int)ESP_INTR_FLAG_IRAM);
gpio_set_intr_type(configuration.irqPin, GPIO_INTR_POSEDGE);
gpio_isr_handler_add(configuration.irqPin, dio1handler, this);
}
void Sx1262::unregisterDio1Isr() {
gpio_isr_handler_remove(configuration.irqPin);
gpio_wakeup_disable(configuration.irqPin);
gpio_set_intr_type(configuration.irqPin, GPIO_INTR_DISABLE);
}
int32_t Sx1262::threadMain(const Modulation modulation) {

View File

@ -5,7 +5,6 @@
#include <RadioLib.h>
#include "RadiolibTactilityHal.h"
#include "IsrTrampoline.h"
#include <utility>
@ -30,7 +29,7 @@ private:
RadiolibTactilityHal hal;
Module radioModule;
SX1262 radio;
IsrTrampolines::SlotNumber isrTrampolineSlot;
IsrTrampolines<Sx1262>::SlotNumber isrTrampolineSlot;
int8_t power = 0;
float frequency = 0.0;
float bandwidth = 0.0;
@ -42,8 +41,8 @@ private:
float frequencyDeviation = 0.0;
int32_t threadMain();
void onReceive();
void registerDio1Isr();
void unregisterDio1Isr();
public:
@ -54,14 +53,11 @@ public:
, hal(configuration.spiHostDevice, configuration.csPin)
, radioModule(&hal, configuration.csPin, configuration.irqPin, configuration.resetPin, configuration.busyPin)
, radio(&radioModule) {
IsrTrampolines::registerSlot([this]() {
this->onReceive();
}, isrTrampolineSlot);
radio.setDio1Action(IsrTrampolines::getForSlot(isrTrampolineSlot));
registerDio1Isr();
}
~Sx1262() override {
IsrTrampolines::unregisterSlot(isrTrampolineSlot);
unregisterDio1Isr();
}
std::string getName() const override { return name; }
@ -74,6 +70,8 @@ public:
return (modulation == Modulation::Fsk) || (modulation == Modulation::LoRa);
}
void IRAM_ATTR setRxEvent() { getEventFlag().set(RADIO_RECEIVED_BIT); }
protected:
int32_t threadMain(const Modulation modulation) override;