mirror of
https://github.com/meshtastic/firmware
synced 2026-08-07 20:32:18 -04:00
Update LoRa firmware on Thinknode M7 (#11337)
This commit is contained in:
parent
b026bfbd98
commit
7302db1672
3 changed files with 80 additions and 3 deletions
|
|
@ -4,6 +4,25 @@
|
|||
#include "configuration.h"
|
||||
#include "error.h"
|
||||
#include "mesh/NodeDB.h"
|
||||
|
||||
// A variant may define LR11X0_UPDATE_FIRMWARE_TO to a Semtech transceiver firmware version (e.g. 0x0402) to
|
||||
// bake that image in and update the radio on first boot. Every supported image is 61320 words, so this costs
|
||||
// ~240 kB of flash regardless of the version chosen - only enable it on a variant with the headroom, and
|
||||
// only for as long as it takes to update the affected units.
|
||||
#ifdef LR11X0_UPDATE_FIRMWARE_TO
|
||||
#if LR11X0_UPDATE_FIRMWARE_TO == 0x0402
|
||||
#define RADIOLIB_LR1110_FIRMWARE_0402
|
||||
#elif LR11X0_UPDATE_FIRMWARE_TO == 0x0401
|
||||
#define RADIOLIB_LR1110_FIRMWARE_0401
|
||||
#elif LR11X0_UPDATE_FIRMWARE_TO == 0x0307
|
||||
#define RADIOLIB_LR1110_FIRMWARE_0307
|
||||
#else
|
||||
// Note: RadioLib ships lr1110_transceiver_0308.h but has no selector for it in LR11x0_firmware.h.
|
||||
#error "LR11X0_UPDATE_FIRMWARE_TO must be one of 0x0307, 0x0401, 0x0402"
|
||||
#endif
|
||||
#include <modules/LR11x0/LR11x0_firmware.h>
|
||||
#endif
|
||||
|
||||
#ifdef LR11X0_DIO_AS_RF_SWITCH
|
||||
#include "rfswitch.h"
|
||||
#elif ARCH_PORTDUINO
|
||||
|
|
@ -117,14 +136,59 @@ template <typename T> bool LR11x0Interface<T>::init()
|
|||
|
||||
// \todo Display actual typename of the adapter, not just `LR11x0`
|
||||
LOG_INFO("LR11x0 init result %d", res);
|
||||
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND || res == RADIOLIB_ERR_SPI_CMD_FAILED)
|
||||
return false;
|
||||
if (res == RADIOLIB_ERR_CHIP_NOT_FOUND || res == RADIOLIB_ERR_SPI_CMD_FAILED) {
|
||||
#ifdef LR11X0_UPDATE_FIRMWARE_TO
|
||||
// An interrupted update leaves the radio sitting in bootloader mode, where begin() fails. Retry the
|
||||
// flash from here rather than giving up, otherwise the device could never recover on its own.
|
||||
LOG_WARN("LR11x0 did not start; attempting firmware recovery in case an update was interrupted");
|
||||
if (lora.updateFirmware(lr11xx_firmware_image, LR11XX_FIRMWARE_IMAGE_SIZE, true) == RADIOLIB_ERR_NONE) {
|
||||
LOG_INFO("LR1110 firmware recovery succeeded, re-initializing radio");
|
||||
res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
|
||||
}
|
||||
#endif
|
||||
if (res != RADIOLIB_ERR_NONE)
|
||||
return false;
|
||||
}
|
||||
|
||||
LR11x0VersionInfo_t version;
|
||||
res = lora.getVersionInfo(&version);
|
||||
if (res == RADIOLIB_ERR_NONE)
|
||||
if (res == RADIOLIB_ERR_NONE) {
|
||||
LOG_DEBUG("LR11x0 Device %d, HW %d, FW %d.%d, WiFi %d.%d, GNSS %d.%d", version.device, version.hardware, version.fwMajor,
|
||||
version.fwMinor, version.fwMajorWiFi, version.fwMinorWiFi, version.fwGNSS, version.almanacGNSS);
|
||||
transceiverFw = ((uint16_t)version.fwMajor << 8) | version.fwMinor;
|
||||
transceiverDevice = version.device;
|
||||
}
|
||||
|
||||
#ifdef LR11X0_UPDATE_FIRMWARE_TO
|
||||
// One-shot transceiver firmware update, opt-in per variant. Only runs when the part is an LR1110 running
|
||||
// older firmware than the baked-in image, so once it has succeeded it is a no-op on subsequent boots.
|
||||
if (transceiverDevice == RADIOLIB_LR11X0_DEVICE_LR1110 && transceiverFw != 0 && transceiverFw < LR11X0_UPDATE_FIRMWARE_TO) {
|
||||
LOG_WARN("LR1110 transceiver FW %d.%d is older than %d.%d - updating now. DO NOT POWER OFF: this "
|
||||
"erases and rewrites the radio's own flash.",
|
||||
transceiverFw >> 8, transceiverFw & 0xFF, LR11X0_UPDATE_FIRMWARE_TO >> 8, LR11X0_UPDATE_FIRMWARE_TO & 0xFF);
|
||||
|
||||
int upd = lora.updateFirmware(lr11xx_firmware_image, LR11XX_FIRMWARE_IMAGE_SIZE, true);
|
||||
if (upd != RADIOLIB_ERR_NONE) {
|
||||
// The radio is likely sitting in bootloader mode. It is not bricked - the update is retried on
|
||||
// the next boot because the version check above will still see old (or unreadable) firmware.
|
||||
LOG_ERROR("LR1110 firmware update FAILED %s%d - power-cycle to retry", radioLibErr, upd);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("LR1110 firmware update complete, re-initializing radio");
|
||||
res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
|
||||
if (res != RADIOLIB_ERR_NONE) {
|
||||
LOG_ERROR("LR11x0 re-init after firmware update failed %s%d", radioLibErr, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lora.getVersionInfo(&version) == RADIOLIB_ERR_NONE) {
|
||||
transceiverFw = ((uint16_t)version.fwMajor << 8) | version.fwMinor;
|
||||
transceiverDevice = version.device;
|
||||
LOG_INFO("LR1110 now running transceiver FW %d.%d", version.fwMajor, version.fwMinor);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG_INFO("Frequency set to %f", getFreq());
|
||||
LOG_INFO("Bandwidth set to %f", bw);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@ template <class T> class LR11x0Interface : public RadioLibInterface
|
|||
|
||||
int16_t getCurrentRSSI() override;
|
||||
|
||||
/// Transceiver firmware version as (major << 8 | minor), and which LR11x0 part this is. Captured at
|
||||
/// init() from getVersionInfo(); 0 if the query failed.
|
||||
uint16_t transceiverFw = 0;
|
||||
uint8_t transceiverDevice = 0;
|
||||
|
||||
/**
|
||||
* Glue functions called from ISR land
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -33,6 +33,14 @@
|
|||
#define LR11X0_DIO3_TCXO_VOLTAGE 1.8
|
||||
#define LR11X0_DIO_AS_RF_SWITCH
|
||||
|
||||
// TEMPORARY: units shipped with LR1110 transceiver FW 0x0303 (the original 2020 release), which cannot
|
||||
// reliably demodulate 500 kHz LoRa - Turbo presets fail RX with ~41% byte errors while TX and narrower
|
||||
// bandwidths are fine. 0x0303 also predates GetLoRaRxHeaderInfos, which computePacketTime() calls on every
|
||||
// received packet. Confirmed fixed by updating to 0x0307; targeting 0x0402 additionally picks up the
|
||||
// out-of-band emission fix for consecutive LoRa transmissions (0x0401) and three CVE fixes (0x0402).
|
||||
// Costs ~240 kB of flash. Remove once the affected units are updated.
|
||||
#define LR11X0_UPDATE_FIRMWARE_TO 0x0402
|
||||
|
||||
#define HAS_ETHERNET 1
|
||||
#define USE_CH390D 1
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue