Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
4 changes: 3 additions & 1 deletion src/graphics/draw/DebugRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,9 @@ 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 = -1;
if (!RadioLibInterface::instances.empty())
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
4 changes: 2 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -858,11 +858,11 @@ void setup()
#else
// ESP32
#if defined(HW_SPI1_DEVICE)
SPI1.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
SPI1.begin(LORA_SCK, LORA_MISO, LORA_MOSI, -1); // CS handled by RadioLib
LOG_DEBUG("SPI1.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
SPI1.setFrequency(4000000);
#else
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, -1); // CS handled by RadioLib
LOG_DEBUG("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
SPI.setFrequency(4000000);
#endif
Expand Down
35 changes: 25 additions & 10 deletions src/mesh/RadioLibInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,25 @@ void LockingArduinoHal::spiTransfer(uint8_t *out, size_t len, uint8_t *in)

RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy, PhysicalLayer *_iface)
: NotifiedWorkerThread("RadioIf"), module(hal, cs, irq, rst, busy), iface(_iface)
: NotifiedWorkerThread(strcpy(ifaceName, std::string("RadioIf" + std::to_string(cs)).c_str())),
module(hal, cs, irq, rst, busy), iface(_iface)
{
instance = this;
noInterrupts();
instances.push_back(this);
interrupts();
#if defined(ARCH_STM32WL) && defined(USE_SX1262)
module.setCb_digitalWrite(stm32wl_emulate_digitalWrite);
module.setCb_digitalRead(stm32wl_emulate_digitalRead);
#endif
}
RadioLibInterface::~RadioLibInterface()
{
auto it = std::find(instances.begin(), instances.end(), this);
assert(it != instances.end());
noInterrupts();
instances.erase(it);
interrupts();
}

#ifdef ARCH_ESP32
// ESP32 doesn't use that flag
Expand All @@ -55,15 +66,19 @@ RadioLibInterface::RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE c

void INTERRUPT_ATTR RadioLibInterface::isrLevel0Common(PendingISR cause)
{
instance->disableInterrupt();
for (auto instance : instances) {
if (digitalRead(instance->module.getIrq())) {
instance->disableInterrupt();

BaseType_t xHigherPriorityTaskWoken;
instance->notifyFromISR(&xHigherPriorityTaskWoken, cause, true);
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);
/* 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 +93,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;

/** Could we send right now (i.e. either not actively receiving or transmitting)? */
bool RadioLibInterface::canSendImmediately()
Expand Down
11 changes: 5 additions & 6 deletions src/mesh/RadioLibInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@
#include <RadioLib.h>
#include <sys/types.h>

// ESP32 has special rules about ISR code
#ifdef ARDUINO_ARCH_ESP32
#define INTERRUPT_ATTR IRAM_ATTR
#else
#define INTERRUPT_ATTR
#endif

#define RADIOLIB_PIN_TYPE uint32_t

Expand Down Expand Up @@ -60,6 +55,8 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified

MeshPacketQueue txQueue = MeshPacketQueue(MAX_TX_QUEUE);

char ifaceName[16];

protected:
ModemType_t modemType = RADIOLIB_MODEM_LORA;
DataRate_t getDataRate() const { return {.lora = {.spreadingFactor = sf, .bandwidth = bw, .codingRate = cr}}; }
Expand Down Expand Up @@ -100,7 +97,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 All @@ -122,6 +119,8 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
RadioLibInterface(LockingArduinoHal *hal, RADIOLIB_PIN_TYPE cs, RADIOLIB_PIN_TYPE irq, RADIOLIB_PIN_TYPE rst,
RADIOLIB_PIN_TYPE busy, PhysicalLayer *iface = NULL);

~RadioLibInterface();

virtual ErrorCode send(meshtastic_MeshPacket *p) override;

/**
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
13 changes: 7 additions & 6 deletions src/modules/Telemetry/DeviceTelemetry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,13 @@ 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
3 changes: 3 additions & 0 deletions src/platform/portduino/PortduinoGlue.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ bool MAC_from_string(std::string mac_str, uint8_t *dmac);
void readGPIOFromYaml(YAML::Node sourceNode, pinMapping &destPin, int pinDefault = RADIOLIB_NC);
std::string exec(const char *cmd);

#define interrupts()
#define noInterrupts()

extern struct portduino_config_struct {
// Lora
std::map<lora_module_enum, std::string> loraModules = {
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