Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/graphics/Screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1034,7 +1034,7 @@ void Screen::setFrames(FrameFocus focus)
indicatorIcons.push_back(icon_compass);
}
#endif
if (RadioLibInterface::instance && !hiddenFrames.lora) {
if (!RadioLibInterface::instances.empty() && !hiddenFrames.lora) {
fsi.positions.lora = numframes;
normalFrames[numframes++] = graphics::DebugRenderer::drawLoRaFocused;
indicatorIcons.push_back(icon_radio);
Expand Down
2 changes: 1 addition & 1 deletion src/graphics/draw/DebugRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
// === Fourth Row: Frequency / ChanNum ===
char frequencyslot[35];
char freqStr[16];
float freq = RadioLibInterface::instance->getFreq();
float freq = RadioLibInterface::instances.front()->getFreq();
snprintf(freqStr, sizeof(freqStr), "%.3f", freq);
if (config.lora.channel_num == 0) {
#if defined(M5STACK_UNITC6L)
Expand Down
2 changes: 1 addition & 1 deletion src/input/ButtonThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ int32_t ButtonThread::runOnce()
case BUTTON_EVENT_LONG_PRESSED: {
// Ignore if: TX in progress
// Uncommon T-Echo hardware bug, LoRa TX triggers touch button
if (_touchQuirk && RadioLibInterface::instance && RadioLibInterface::instance->isSending())
if (_touchQuirk && !RadioLibInterface::instances.empty() && RadioLibInterface::instances.front()->isSending())
break;

// Check if this is part of a short-press + long-press combination
Expand Down
28 changes: 17 additions & 11 deletions src/mesh/RadioLibInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE c
RADIOLIB_PIN_TYPE busy, PhysicalLayer *_iface)
: NotifiedWorkerThread("RadioIf"), module(hal, cs, irq, rst, busy), iface(_iface)
{
instance = this;
instances.push_back(this);
#if defined(ARCH_STM32WL) && defined(USE_SX1262)
module.setCb_digitalWrite(stm32wl_emulate_digitalWrite);
module.setCb_digitalRead(stm32wl_emulate_digitalRead);
Expand All @@ -55,15 +55,21 @@ RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE c

void INTERRUPT_ATTR RadioLibInterface::isrLevel0Common(PendingISR cause)
{
instance->disableInterrupt();

BaseType_t xHigherPriorityTaskWoken;
instance->notifyFromISR(&xHigherPriorityTaskWoken, cause, true);

/* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE.
The macro used to do this is dependent on the port and may be called
portEND_SWITCHING_ISR. */
YIELD_FROM_ISR(xHigherPriorityTaskWoken);
for(auto instance : instances)
{
if(digitalRead(instance->module.getIrq()))
{
instance->disableInterrupt();

BaseType_t xHigherPriorityTaskWoken;
instance->notifyFromISR(&xHigherPriorityTaskWoken, cause, true);

/* Force a context switch if xHigherPriorityTaskWoken is now set to pdTRUE.
The macro used to do this is dependent on the port and may be called
portEND_SWITCHING_ISR. */
YIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
}

void INTERRUPT_ATTR RadioLibInterface::isrRxLevel0()
Expand All @@ -78,7 +84,7 @@ void INTERRUPT_ATTR RadioLibInterface::isrTxLevel0()

/** Our ISR code currently needs this to find our active instance
*/
RadioLibInterface *RadioLibInterface::instance;
std::vector<RadioLibInterface*> RadioLibInterface::instances;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this is a static variable you have to explicitly remove instances that have been pushed into this vector when the instance (i.e. an instance of a derived class of RadioLibInterface) is deleted as in main.cpp where several radio chip types are probed.

Copy link
Contributor Author

@Andrik45719 Andrik45719 Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I currently have two radio interfaces running. The variable must be static, as it needs to be accessed from an interrupt.
The problem is that there is not enough IRAM memory on the ESP32, I will solve it.

Copy link
Collaborator

@mverch67 mverch67 Nov 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still, you need to remove instances from the vector in the dtor, otherwise the vector will contain pointers to deleted objects.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I’ve opened a new PR, could you check it?
#8607


/** Could we send right now (i.e. either not actively receiving or transmitting)? */
bool RadioLibInterface::canSendImmediately()
Expand Down
2 changes: 1 addition & 1 deletion src/mesh/RadioLibInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
public:
/** Our ISR code currently needs this to find our active instance
*/
static RadioLibInterface *instance;
static std::vector<RadioLibInterface*> instances;

/**
* Glue functions called from ISR land
Expand Down
6 changes: 4 additions & 2 deletions src/mesh/http/ContentHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -694,8 +694,10 @@ void handleReport(HTTPRequest *req, HTTPResponse *res)

// data->radio
JSONObject jsonObjRadio;
jsonObjRadio["frequency"] = new JSONValue(RadioLibInterface::instance->getFreq());
jsonObjRadio["lora_channel"] = new JSONValue((int)RadioLibInterface::instance->getChannelNum() + 1);
if(!RadioLibInterface::instances.empty()) {
jsonObjRadio["frequency"] = new JSONValue(RadioLibInterface::instances.front()->getFreq());
jsonObjRadio["lora_channel"] = new JSONValue((int)RadioLibInterface::instances.front()->getChannelNum() + 1);
}

// collect data to inner data object
JSONObject jsonObjInner;
Expand Down
12 changes: 6 additions & 6 deletions src/modules/Telemetry/DeviceTelemetry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ meshtastic_Telemetry DeviceTelemetryModule::getLocalStatsTelemetry()
telemetry.variant.local_stats.air_util_tx = airTime->utilizationTXPercent();
telemetry.variant.local_stats.num_online_nodes = numOnlineNodes;
telemetry.variant.local_stats.num_total_nodes = nodeDB->getNumMeshNodes();
if (RadioLibInterface::instance) {
telemetry.variant.local_stats.num_packets_tx = RadioLibInterface::instance->txGood;
telemetry.variant.local_stats.num_packets_rx = RadioLibInterface::instance->rxGood + RadioLibInterface::instance->rxBad;
telemetry.variant.local_stats.num_packets_rx_bad = RadioLibInterface::instance->rxBad;
telemetry.variant.local_stats.num_tx_relay = RadioLibInterface::instance->txRelay;
telemetry.variant.local_stats.num_tx_dropped = RadioLibInterface::instance->txDrop;
if (!RadioLibInterface::instances.empty()) {
telemetry.variant.local_stats.num_packets_tx = RadioLibInterface::instances.front()->txGood;
telemetry.variant.local_stats.num_packets_rx = RadioLibInterface::instances.front()->rxGood + RadioLibInterface::instances.front()->rxBad;
telemetry.variant.local_stats.num_packets_rx_bad = RadioLibInterface::instances.front()->rxBad;
telemetry.variant.local_stats.num_tx_relay = RadioLibInterface::instances.front()->txRelay;
telemetry.variant.local_stats.num_tx_dropped = RadioLibInterface::instances.front()->txDrop;
}
#ifdef ARCH_PORTDUINO
if (SimRadio::instance) {
Expand Down
2 changes: 1 addition & 1 deletion variants/nrf52840/t-echo/nicheGraphics.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ void setupNicheGraphics()
buttons->setHandlerDown(1, [inkhud, backlight]() {
// Discard the button press if radio is active
// Rare hardware fault: LoRa activity triggers touch button
if (!RadioLibInterface::instance || RadioLibInterface::instance->isSending())
if (RadioLibInterface::instances.empty() || RadioLibInterface::instances.front()->isSending())
return;

// Backlight on (while held)
Expand Down
Loading