diff --git a/variants/tanmatsu/TanmatsuLoraRadio.cpp b/variants/tanmatsu/TanmatsuLoraRadio.cpp index 1179410..c2347f5 100644 --- a/variants/tanmatsu/TanmatsuLoraRadio.cpp +++ b/variants/tanmatsu/TanmatsuLoraRadio.cpp @@ -54,6 +54,18 @@ int TanmatsuLoraRadio::recvRaw(uint8_t* bytes, int sz) { // one-shot is enough. It also gates pushConfig from here on (the remote link blocks under RX load). _rx_polling = true; lora_set_mode(&_h, LORA_PROTOCOL_MODE_RX); + } else if (_cfg_dirty) { + // A runtime setParams()/setTxPower()/setRxBoostedGainMode() (the wadamesh radio + // settings save, from the UI or the companion app) changed the PHY config. Apply it + // HERE, on the RX-poll thread, so the C6 remote link is never touched cross-thread: + // leave RX to STANDBY (so the link isn't under active-RX load and lora_set_config + // can't block), push the new config, then re-arm continuous RX. This is what makes a + // live frequency / SF / BW / CR / power change actually reach the modem (it used to + // need a reboot) AND lets wadamesh's settings override whatever the Tanmatsu OS set. + _cfg_dirty = false; + lora_set_mode(&_h, LORA_PROTOCOL_MODE_STANDBY_RC); + lora_set_config(&_h, &_cfg); + lora_set_mode(&_h, LORA_PROTOCOL_MODE_RX); } lora_protocol_lora_packet_t pkt; // Non-blocking poll of the RX queue (timeout 0). diff --git a/variants/tanmatsu/TanmatsuLoraRadio.h b/variants/tanmatsu/TanmatsuLoraRadio.h index 13c1059..a4a46bf 100644 --- a/variants/tanmatsu/TanmatsuLoraRadio.h +++ b/variants/tanmatsu/TanmatsuLoraRadio.h @@ -56,16 +56,25 @@ public: uint32_t getPacketsSent() const { return _n_sent; } private: - // Push _cfg to the modem — but ONLY while not yet polling RX. The remote link's - // esp_hosted_send_custom_data() blocks indefinitely under continuous-RX load, so a - // live reconfig from the UI thread would freeze the app. Boot bring-up (before the - // RX loop starts) pushes fine; runtime changes update _cfg and apply on next init. - void pushConfig() { if (_started && !_rx_polling) lora_set_config(&_h, &_cfg); } + // Push _cfg to the modem. The remote link's esp_hosted_send_custom_data() can block + // under continuous-RX load, so a live lora_set_config() from the UI/companion thread + // (mid-RX) risked freezing the app — which is why this used to no-op once RX started, + // making a frequency/SF/BW change only take effect on the next reboot ("receives + // nothing on the new frequency", and wadamesh's settings never overrode the Tanmatsu + // OS's). Now: boot bring-up pushes directly; a runtime change marks _cfg dirty and + // recvRaw() applies it on the RX-poll thread, between polls (standby → push → re-arm), + // so wadamesh's settings actually reach the modem and win. + void pushConfig() { + if (!_started) return; + if (_rx_polling) { _cfg_dirty = true; return; } // defer to recvRaw() (RX-poll thread) + lora_set_config(&_h, &_cfg); + } lora_handle_t _h = {0}; lora_protocol_config_params_t _cfg = {0}; bool _started = false; bool _rx_polling = false; // set once recvRaw() starts draining — see pushConfig() + bool _cfg_dirty = false; // runtime config change pending; applied by recvRaw() between polls bool _sending = false; bool _rx_boost = false; float _last_rssi = 0.0f;