[LR11x0] Added firmware update support
This commit is contained in:
parent
8f5440e4b5
commit
5e398bd868
17 changed files with 75034 additions and 38 deletions
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
RadioLib LR11x0 Firmware Update Example
|
||||
|
||||
This example updates the internal LR1110 firmware.
|
||||
Newer versions of the firmware introduce fixes
|
||||
and possibly even new features, so it is recommended
|
||||
to use the latest available firmware version
|
||||
when possible.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// select the firmware image you want to upload
|
||||
// WARNING: Make sure you select the correct firmware
|
||||
// for your device! Uploading incorrect firmware
|
||||
// (e.g. LR1110 firmware to LR1120 device)
|
||||
// may damage your hardware!
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0303
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0304
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0305
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0306
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0307
|
||||
#define RADIOLIB_LR1110_FIRMWARE_0401
|
||||
//#define RADIOLIB_LR1120_FIRMWARE_0101
|
||||
//#define RADIOLIB_LR1120_FIRMWARE_0102
|
||||
//#define RADIOLIB_LR1120_FIRMWARE_0201
|
||||
//#define RADIOLIB_LR1121_FIRMWARE_0102
|
||||
//#define RADIOLIB_LR1121_FIRMWARE_0103
|
||||
|
||||
// enable this macro if you want to store the image in host
|
||||
// MCU RAM instead of Flash.
|
||||
// NOTE: the firmware images are very large, up to 240 kB!
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_IN_RAM
|
||||
|
||||
// include the firmware image
|
||||
#include <modules/LR11x0/LR11x0_firmware.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or using RadioShield
|
||||
// https://github.com/jgromes/RadioShield
|
||||
//LR1110 radio = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// print the firmware versions before the update
|
||||
printVersions();
|
||||
|
||||
// prompt the user
|
||||
Serial.println(F("[LR1110] Send any character to start the update"));
|
||||
while(!Serial.available()) { yield(); }
|
||||
|
||||
// upload update into LR11x0 non-volatile memory
|
||||
Serial.print(F("[LR1110] Updating firmware, this may take several seconds ... "));
|
||||
state = radio.updateFirmware(lr11xx_firmware_image, RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE);
|
||||
/*
|
||||
use the following if you enabled RADIOLIB_LR1110_FIRMWARE_IN_RAM
|
||||
state = radio.updateFirmware(lr11xx_firmware_image, RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE, false);
|
||||
*/
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// print the firmware versions after the update
|
||||
printVersions();
|
||||
|
||||
}
|
||||
|
||||
void printVersions() {
|
||||
LR11x0VersionInfo_t version;
|
||||
Serial.print(F("[LR1110] Reading firmware versions ... "));
|
||||
int16_t state = radio.getVersionInfo(&version);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
Serial.print(F("[LR1110] Device: "));
|
||||
Serial.println(version.device);
|
||||
|
||||
Serial.print(F("[LR1110] Base firmware: "));
|
||||
Serial.print(version.fwMajor);
|
||||
Serial.print('.');
|
||||
Serial.println(version.fwMinor);
|
||||
|
||||
Serial.print(F("[LR1110] WiFi firmware: "));
|
||||
Serial.print(version.fwMajorWiFi);
|
||||
Serial.print('.');
|
||||
Serial.println(version.fwMinorWiFi);
|
||||
|
||||
Serial.print(F("[LR1110] GNSS firmware: "));
|
||||
Serial.print(version.fwGNSS);
|
||||
Serial.print('.');
|
||||
Serial.println(version.almanacGNSS);
|
||||
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
19
keywords.txt
19
keywords.txt
|
@ -91,10 +91,11 @@ AS923 KEYWORD1
|
|||
KR920 KEYWORD1
|
||||
IN865 KEYWORD1
|
||||
|
||||
# LR11x0 scan results
|
||||
# LR11x0 structures
|
||||
LR11x0WifiResult_t KEYWORD1
|
||||
LR11x0WifiResultFull_t KEYWORD1
|
||||
LR11x0WifiResultExtended_t KEYWORD1
|
||||
LR11x0VersionInfo_t KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
|
@ -254,6 +255,8 @@ getWifiScanResult KEYWORD2
|
|||
wifiScan KEYWORD2
|
||||
setWiFiScanAction KEYWORD2
|
||||
clearWiFiScanAction KEYWORD2
|
||||
getVersionInfo KEYWORD2
|
||||
updateFirmware KEYWORD2
|
||||
|
||||
# RTTY
|
||||
idle KEYWORD2
|
||||
|
@ -459,3 +462,17 @@ RADIOLIB_ERR_DATA_RATE_INVALID LITERAL1
|
|||
RADIOLIB_ERR_DWELL_TIME_EXCEEDED LITERAL1
|
||||
RADIOLIB_ERR_CHECKSUM_MISMATCH LITERAL1
|
||||
RADIOLIB_LORAWAN_NO_DOWNLINK LITERAL1
|
||||
|
||||
RADIOLIB_LR1110_FIRMWARE_IN_RAM LITERAL1
|
||||
RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0303 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0304 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0305 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0306 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0307 LITERAL1
|
||||
RADIOLIB_LR1110_FIRMWARE_0401 LITERAL1
|
||||
RADIOLIB_LR1120_FIRMWARE_0101 LITERAL1
|
||||
RADIOLIB_LR1120_FIRMWARE_0102 LITERAL1
|
||||
RADIOLIB_LR1120_FIRMWARE_0201 LITERAL1
|
||||
RADIOLIB_LR1121_FIRMWARE_0102 LITERAL1
|
||||
RADIOLIB_LR1121_FIRMWARE_0103 LITERAL1
|
||||
|
|
|
@ -489,7 +489,7 @@ uint32_t LR11x0::getIrqStatus() {
|
|||
// there is no dedicated "get IRQ" command, the IRQ bits are sent after the status bytes
|
||||
uint8_t buff[6] = { 0 };
|
||||
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_0;
|
||||
mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true);
|
||||
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_8;
|
||||
uint32_t irq = ((uint32_t)(buff[2]) << 24) | ((uint32_t)(buff[3]) << 16) | ((uint32_t)(buff[4]) << 8) | (uint32_t)buff[5];
|
||||
return(irq);
|
||||
|
@ -1546,6 +1546,78 @@ int16_t LR11x0::wifiScan(uint8_t wifiType, uint8_t* count, uint8_t mode, uint16_
|
|||
return(getWifiScanResultsCount(count));
|
||||
}
|
||||
|
||||
int16_t LR11x0::getVersionInfo(LR11x0VersionInfo_t* info) {
|
||||
if(!info) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
|
||||
int16_t state = this->getVersion(&info->hardware, &info->device, &info->fwMajor, &info->fwMinor);
|
||||
RADIOLIB_ASSERT(state);
|
||||
state = this->wifiReadVersion(&info->fwMajorWiFi, &info->fwMinorWiFi);
|
||||
RADIOLIB_ASSERT(state);
|
||||
return(this->gnssReadVersion(&info->fwGNSS, &info->almanacGNSS));
|
||||
}
|
||||
|
||||
int16_t LR11x0::updateFirmware(const uint32_t* image, size_t size, bool nonvolatile) {
|
||||
if(!image) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
|
||||
// put the device to bootloader mode
|
||||
int16_t state = this->reboot(true);
|
||||
RADIOLIB_ASSERT(state);
|
||||
this->mod->hal->delay(500);
|
||||
|
||||
// check we're in bootloader
|
||||
uint8_t device = 0xFF;
|
||||
state = this->getVersion(NULL, &device, NULL, NULL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
if(device != RADIOLIB_LR11X0_DEVICE_BOOT) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Failed to put device to bootloader mode, %02x != %02x", device, RADIOLIB_LR11X0_DEVICE_BOOT);
|
||||
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
|
||||
}
|
||||
|
||||
// erase the image
|
||||
state = this->bootEraseFlash();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// wait for BUSY to go low
|
||||
RadioLibTime_t start = this->mod->hal->millis();
|
||||
while(this->mod->hal->digitalRead(this->mod->getGpio())) {
|
||||
this->mod->hal->yield();
|
||||
if(this->mod->hal->millis() - start >= 3000) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("BUSY pin timeout after erase!");
|
||||
return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
// upload the new image
|
||||
const size_t maxLen = 64;
|
||||
size_t rem = size % maxLen;
|
||||
size_t numWrites = (rem == 0) ? (size / maxLen) : ((size / maxLen) + 1);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Writing image in %lu chunks, last chunk size is %lu words", (unsigned long)numWrites, (unsigned long)rem);
|
||||
for(size_t i = 0; i < numWrites; i ++) {
|
||||
uint32_t offset = i * maxLen;
|
||||
uint32_t len = (i == (numWrites - 1)) ? rem : maxLen;
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Writing chunk %d at offset %08lx (%u words)", (int)i, (unsigned long)offset, (unsigned int)len);
|
||||
this->bootWriteFlashEncrypted(offset*sizeof(uint32_t), (uint32_t*)&image[offset], len, nonvolatile);
|
||||
}
|
||||
|
||||
// kick the device from bootloader
|
||||
state = this->reset();
|
||||
RADIOLIB_ASSERT(state);
|
||||
|
||||
// verify we are no longer in bootloader
|
||||
state = this->getVersion(NULL, &device, NULL, NULL);
|
||||
RADIOLIB_ASSERT(state);
|
||||
if(device == RADIOLIB_LR11X0_DEVICE_BOOT) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Failed to kick device from bootloader mode, %02x == %02x", device, RADIOLIB_LR11X0_DEVICE_BOOT);
|
||||
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) {
|
||||
this->mod->init();
|
||||
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
|
||||
|
@ -1601,7 +1673,7 @@ int16_t LR11x0::SPIcheckStatus(Module* mod) {
|
|||
// it also seems to ignore the actual command, and just sending in bunch of NOPs will work
|
||||
uint8_t buff[6] = { 0 };
|
||||
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_0;
|
||||
int16_t state = mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
int16_t state = mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true);
|
||||
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_8;
|
||||
RADIOLIB_ASSERT(state);
|
||||
return(LR11x0::SPIparseStatus(buff[0]));
|
||||
|
@ -1637,21 +1709,16 @@ bool LR11x0::findChip(uint8_t ver) {
|
|||
reset();
|
||||
|
||||
// read the version
|
||||
uint8_t device = 0xFF;
|
||||
uint8_t major = 0xFF;
|
||||
uint8_t minor = 0xFF;
|
||||
if((this->getVersion(NULL, &device, &major, &minor) == RADIOLIB_ERR_NONE) && (device == ver)) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Found LR11x0: RADIOLIB_LR11X0_CMD_GET_VERSION = 0x%02x", device);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Transceiver FW version: %d.%d", (int)major, (int)minor);
|
||||
#if RADIOLIB_DEBUG_BASIC
|
||||
this->wifiReadVersion(&major, &minor);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("WiFi FW version: %d.%d", (int)major, (int)minor);
|
||||
this->gnssReadVersion(&major, &minor);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("GNSS FW version: %d.%d", (int)major, (int)minor);
|
||||
#endif
|
||||
LR11x0VersionInfo_t info = { 0 };
|
||||
int16_t state = getVersionInfo(&info);
|
||||
if((state == RADIOLIB_ERR_NONE) && (info.device == ver)) {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Found LR11x0: RADIOLIB_LR11X0_CMD_GET_VERSION = 0x%02x", info.device);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Base FW version: %d.%d", (int)info.fwMajor, (int)info.fwMinor);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("WiFi FW version: %d.%d", (int)info.fwMajorWiFi, (int)info.fwMinorWiFi);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("GNSS FW version: %d.%d", (int)info.fwGNSS, (int)info.almanacGNSS);
|
||||
flagFound = true;
|
||||
} else {
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("LR11x0 not found! (%d of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x%02x", i + 1, device);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("LR11x0 not found! (%d of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x%02x", i + 1, info.device);
|
||||
RADIOLIB_DEBUG_BASIC_PRINTLN("Expected: 0x%02x", ver);
|
||||
this->mod->hal->delay(10);
|
||||
i++;
|
||||
|
@ -1781,7 +1848,7 @@ int16_t LR11x0::writeRegMem32(uint32_t addr, uint32_t* data, size_t len) {
|
|||
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
||||
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||
}
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_WRITE_REG_MEM, addr, data, len));
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_WRITE_REG_MEM, addr, data, len, false));
|
||||
}
|
||||
|
||||
int16_t LR11x0::readRegMem32(uint32_t addr, uint32_t* data, size_t len) {
|
||||
|
@ -1874,7 +1941,7 @@ int16_t LR11x0::getStatus(uint8_t* stat1, uint8_t* stat2, uint32_t* irq) {
|
|||
// the status check command doesn't return status in the same place as other read commands
|
||||
// but only as the first byte (as with any other command), hence LR11x0::SPIcommand can't be used
|
||||
// it also seems to ignore the actual command, and just sending in bunch of NOPs will work
|
||||
int16_t state = this->mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
int16_t state = this->mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true);
|
||||
|
||||
// pass the replies
|
||||
if(stat1) { *stat1 = buff[0]; }
|
||||
|
@ -1959,8 +2026,8 @@ int16_t LR11x0::setTcxoMode(uint8_t tune, uint32_t delay) {
|
|||
}
|
||||
|
||||
int16_t LR11x0::reboot(bool stay) {
|
||||
uint8_t buff[1] = { (uint8_t)stay };
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_REBOOT, true, buff, sizeof(buff)));
|
||||
uint8_t buff[1] = { (uint8_t)(stay*3) };
|
||||
return(this->mod->SPIwriteStream(RADIOLIB_LR11X0_CMD_REBOOT, buff, sizeof(buff), true, false));
|
||||
}
|
||||
|
||||
int16_t LR11x0::getVbat(float* vbat) {
|
||||
|
@ -2745,7 +2812,7 @@ int16_t LR11x0::gnssGetContextStatus(uint8_t* fwVersion, uint32_t* almanacCrc, u
|
|||
// read the result - this requires some magic bytes first, that's why LR11x0::SPIcommand cannot be used
|
||||
uint8_t cmd_buff[3] = { 0x00, 0x02, 0x18 };
|
||||
uint8_t buff[9] = { 0 };
|
||||
state = this->mod->SPItransferStream(cmd_buff, sizeof(cmd_buff), false, NULL, buff, sizeof(buff), true, RADIOLIB_MODULE_SPI_TIMEOUT);
|
||||
state = this->mod->SPItransferStream(cmd_buff, sizeof(cmd_buff), false, NULL, buff, sizeof(buff), true);
|
||||
|
||||
// pass the replies
|
||||
if(fwVersion) { *fwVersion = buff[0]; }
|
||||
|
@ -3207,13 +3274,12 @@ int16_t LR11x0::cryptoGetParam(uint8_t id, uint32_t* value) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::cryptoCheckEncryptedFirmwareImage(uint32_t offset, uint32_t* data, size_t len) {
|
||||
int16_t LR11x0::cryptoCheckEncryptedFirmwareImage(uint32_t offset, uint32_t* data, size_t len, bool nonvolatile) {
|
||||
// check maximum size
|
||||
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
||||
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||
}
|
||||
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_CRYPTO_CHECK_ENCRYPTED_FIRMWARE_IMAGE, offset, data, len));
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_CRYPTO_CHECK_ENCRYPTED_FIRMWARE_IMAGE, offset, data, len, nonvolatile));
|
||||
}
|
||||
|
||||
int16_t LR11x0::cryptoCheckEncryptedFirmwareImageResult(bool* result) {
|
||||
|
@ -3227,12 +3293,20 @@ int16_t LR11x0::cryptoCheckEncryptedFirmwareImageResult(bool* result) {
|
|||
}
|
||||
|
||||
int16_t LR11x0::bootEraseFlash(void) {
|
||||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_BOOT_ERASE_FLASH, true, NULL, 0));
|
||||
// erasing flash takes about 2.5 seconds, temporarily tset SPI timeout to 3 seconds
|
||||
RadioLibTime_t timeout = this->mod->spiConfig.timeout;
|
||||
this->mod->spiConfig.timeout = 3000;
|
||||
int16_t state = this->mod->SPIwriteStream(RADIOLIB_LR11X0_CMD_BOOT_ERASE_FLASH, NULL, 0, false, false);
|
||||
this->mod->spiConfig.timeout = timeout;
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t LR11x0::bootWriteFlashEncrypted(uint32_t offset, uint32_t* data, size_t len) {
|
||||
RADIOLIB_CHECK_RANGE(len, 1, 32, RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_BOOT_WRITE_FLASH_ENCRYPTED, offset, data, len));
|
||||
int16_t LR11x0::bootWriteFlashEncrypted(uint32_t offset, uint32_t* data, size_t len, bool nonvolatile) {
|
||||
// check maximum size
|
||||
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
|
||||
return(RADIOLIB_ERR_SPI_CMD_INVALID);
|
||||
}
|
||||
return(this->writeCommon(RADIOLIB_LR11X0_CMD_BOOT_WRITE_FLASH_ENCRYPTED, offset, data, len, nonvolatile));
|
||||
}
|
||||
|
||||
int16_t LR11x0::bootReboot(bool stay) {
|
||||
|
@ -3261,7 +3335,7 @@ int16_t LR11x0::bootGetJoinEui(uint8_t* eui) {
|
|||
return(this->SPIcommand(RADIOLIB_LR11X0_CMD_BOOT_GET_JOIN_EUI, false, eui, RADIOLIB_LR11X0_EUI_LEN));
|
||||
}
|
||||
|
||||
int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len) {
|
||||
int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len, bool nonvolatile) {
|
||||
// build buffers - later we need to ensure endians are correct,
|
||||
// so there is probably no way to do this without copying buffers and iterating
|
||||
size_t buffLen = sizeof(uint32_t) + len*sizeof(uint32_t);
|
||||
|
@ -3279,13 +3353,19 @@ int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* d
|
|||
|
||||
// convert endians
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
dataBuff[4 + i] = (uint8_t)((data[i] >> 24) & 0xFF);
|
||||
dataBuff[5 + i] = (uint8_t)((data[i] >> 16) & 0xFF);
|
||||
dataBuff[6 + i] = (uint8_t)((data[i] >> 8) & 0xFF);
|
||||
dataBuff[7 + i] = (uint8_t)(data[i] & 0xFF);
|
||||
uint32_t bin = 0;
|
||||
if(nonvolatile) {
|
||||
bin = RADIOLIB_NONVOLATILE_READ_DWORD(data + i);
|
||||
} else {
|
||||
bin = data[i];
|
||||
}
|
||||
dataBuff[4 + i*sizeof(uint32_t)] = (uint8_t)((bin >> 24) & 0xFF);
|
||||
dataBuff[5 + i*sizeof(uint32_t)] = (uint8_t)((bin >> 16) & 0xFF);
|
||||
dataBuff[6 + i*sizeof(uint32_t)] = (uint8_t)((bin >> 8) & 0xFF);
|
||||
dataBuff[7 + i*sizeof(uint32_t)] = (uint8_t)(bin & 0xFF);
|
||||
}
|
||||
|
||||
int16_t state = this->SPIcommand(cmd, true, dataBuff, buffLen);
|
||||
int16_t state = this->mod->SPIwriteStream(cmd, dataBuff, buffLen, true, false);
|
||||
#if !RADIOLIB_STATIC_ONLY
|
||||
delete[] dataBuff;
|
||||
#endif
|
||||
|
|
|
@ -661,6 +661,36 @@ struct LR11x0WifiResultExtended_t: public LR11x0WifiResultFull_t {
|
|||
bool fcsCheckOk;
|
||||
};
|
||||
|
||||
/*!
|
||||
\struct LR11x0VersionInfo_t
|
||||
\brief Structure to report information about versions of the LR11x0 hardware and firmware.
|
||||
*/
|
||||
struct LR11x0VersionInfo_t {
|
||||
/*! \brief Hardware revision. */
|
||||
uint8_t hardware;
|
||||
|
||||
/*! \brief Which device this is - one of RADIOLIB_LR11X0_DEVICE_* macros. */
|
||||
uint8_t device;
|
||||
|
||||
/*! \brief Major revision of the base firmware. */
|
||||
uint8_t fwMajor;
|
||||
|
||||
/*! \brief Minor revision of the base firmware. */
|
||||
uint8_t fwMinor;
|
||||
|
||||
/*! \brief Major revision of the WiFi firmware. */
|
||||
uint8_t fwMajorWiFi;
|
||||
|
||||
/*! \brief Minor revision of the WiFi firmware. */
|
||||
uint8_t fwMinorWiFi;
|
||||
|
||||
/*! \brief Revision of the GNSS firmware. */
|
||||
uint8_t fwGNSS;
|
||||
|
||||
/*! \brief Almanac revision of the GNSS firmware. */
|
||||
uint8_t almanacGNSS;
|
||||
};
|
||||
|
||||
/*!
|
||||
\class LR11x0
|
||||
\brief Base class for %LR11x0 series. All derived classes for %LR11x0 (e.g. LR1110 or LR1120) inherit from this base class.
|
||||
|
@ -1289,7 +1319,26 @@ class LR11x0: public PhysicalLayer {
|
|||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t wifiScan(uint8_t wifiType, uint8_t* count, uint8_t mode = RADIOLIB_LR11X0_WIFI_ACQ_MODE_FULL_BEACON, uint16_t chanMask = RADIOLIB_LR11X0_WIFI_ALL_CHANNELS, uint8_t numScans = 16, uint16_t timeout = 100);
|
||||
|
||||
|
||||
/*!
|
||||
\brief Retrieve LR11x0 hardware, device and firmware version information.
|
||||
\param info Pointer to LR11x0VersionInfo_t structure to populate.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t getVersionInfo(LR11x0VersionInfo_t* info);
|
||||
|
||||
/*!
|
||||
\brief Method to upload new firmware image to the device.
|
||||
The device will be automatically erased, a new firmware will be uploaded,
|
||||
written to flash and executed.
|
||||
\param image Pointer to the image to upload.
|
||||
\param size Size of the image in 32-bit words.
|
||||
\param nonvolatile Set to true when the image is saved in non-volatile memory of the host processor,
|
||||
or to false when the patch is in its RAM. Defaults to true.
|
||||
\returns \ref status_codes
|
||||
*/
|
||||
int16_t updateFirmware(const uint32_t* image, size_t size, bool nonvolatile = true);
|
||||
|
||||
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
|
||||
protected:
|
||||
#endif
|
||||
|
@ -1445,11 +1494,11 @@ class LR11x0: public PhysicalLayer {
|
|||
int16_t cryptoRestoreFromFlash(void);
|
||||
int16_t cryptoSetParam(uint8_t id, uint32_t value);
|
||||
int16_t cryptoGetParam(uint8_t id, uint32_t* value);
|
||||
int16_t cryptoCheckEncryptedFirmwareImage(uint32_t offset, uint32_t* data, size_t len);
|
||||
int16_t cryptoCheckEncryptedFirmwareImage(uint32_t offset, uint32_t* data, size_t len, bool nonvolatile);
|
||||
int16_t cryptoCheckEncryptedFirmwareImageResult(bool* result);
|
||||
|
||||
int16_t bootEraseFlash(void);
|
||||
int16_t bootWriteFlashEncrypted(uint32_t offset, uint32_t* data, size_t len);
|
||||
int16_t bootWriteFlashEncrypted(uint32_t offset, uint32_t* data, size_t len, bool nonvolatile);
|
||||
int16_t bootReboot(bool stay);
|
||||
int16_t bootGetPin(uint8_t* pin);
|
||||
int16_t bootGetChipEui(uint8_t* eui);
|
||||
|
@ -1499,7 +1548,7 @@ class LR11x0: public PhysicalLayer {
|
|||
|
||||
// common methods to avoid some copy-paste
|
||||
int16_t bleBeaconCommon(uint16_t cmd, uint8_t chan, uint8_t* payload, size_t len);
|
||||
int16_t writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len);
|
||||
int16_t writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len, bool nonvolatile);
|
||||
int16_t cryptoCommon(uint16_t cmd, uint8_t keyId, uint8_t* dataIn, size_t len, uint8_t* dataOut);
|
||||
};
|
||||
|
||||
|
|
38
src/modules/LR11x0/LR11x0_firmware.h
Normal file
38
src/modules/LR11x0/LR11x0_firmware.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#if !defined(_RADIOLIB_LR11X0_FIRMWARE_H)
|
||||
#define _RADIOLIB_LR11X0_FIRMWARE_H
|
||||
|
||||
#if defined(RADIOLIB_LR1110_FIRMWARE_IN_RAM)
|
||||
#define RADIOLIB_LR1110_FIRMWARE_ATTR
|
||||
#else
|
||||
#define RADIOLIB_LR1110_FIRMWARE_ATTR RADIOLIB_NONVOLATILE
|
||||
#endif
|
||||
|
||||
#define RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE LR11XX_FIRMWARE_IMAGE_SIZE
|
||||
|
||||
#if defined(RADIOLIB_LR1110_FIRMWARE_0303)
|
||||
#include "firmware/lr1110_transceiver_0303.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0304)
|
||||
#include "firmware/lr1110_transceiver_0304.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0305)
|
||||
#include "firmware/lr1110_transceiver_0305.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0306)
|
||||
#include "firmware/lr1110_transceiver_0306.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0307)
|
||||
#include "firmware/lr1110_transceiver_0307.h"
|
||||
#elif defined(RADIOLIB_LR1110_FIRMWARE_0401)
|
||||
#include "firmware/lr1110_transceiver_0401.h"
|
||||
#elif defined(RADIOLIB_LR1120_FIRMWARE_0101)
|
||||
#include "firmware/lr1120_transceiver_0101.h"
|
||||
#elif defined(RADIOLIB_LR1120_FIRMWARE_0102)
|
||||
#include "firmware/lr1120_transceiver_0102.h"
|
||||
#elif defined(RADIOLIB_LR1120_FIRMWARE_0201)
|
||||
#include "firmware/lr1120_transceiver_0201.h"
|
||||
#elif defined(RADIOLIB_LR1121_FIRMWARE_0102)
|
||||
#include "firmware/lr1121_transceiver_0102.h"
|
||||
#elif defined(RADIOLIB_LR1121_FIRMWARE_0103)
|
||||
#include "firmware/lr1121_transceiver_0103.h"
|
||||
#else
|
||||
#error "No LR11x0 firmware image selected!"
|
||||
#endif
|
||||
|
||||
#endif
|
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0303.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0303.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0304.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0304.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0305.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0305.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0306.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0306.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0307.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0307.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0308.h
Normal file
6890
src/modules/LR11x0/firmware/lr1110_transceiver_0308.h
Normal file
File diff suppressed because it is too large
Load diff
7741
src/modules/LR11x0/firmware/lr1110_transceiver_0401.h
Normal file
7741
src/modules/LR11x0/firmware/lr1110_transceiver_0401.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1120_transceiver_0101.h
Normal file
6890
src/modules/LR11x0/firmware/lr1120_transceiver_0101.h
Normal file
File diff suppressed because it is too large
Load diff
6890
src/modules/LR11x0/firmware/lr1120_transceiver_0102.h
Normal file
6890
src/modules/LR11x0/firmware/lr1120_transceiver_0102.h
Normal file
File diff suppressed because it is too large
Load diff
7741
src/modules/LR11x0/firmware/lr1120_transceiver_0201.h
Normal file
7741
src/modules/LR11x0/firmware/lr1120_transceiver_0201.h
Normal file
File diff suppressed because it is too large
Load diff
1921
src/modules/LR11x0/firmware/lr1121_transceiver_0102.h
Normal file
1921
src/modules/LR11x0/firmware/lr1121_transceiver_0102.h
Normal file
File diff suppressed because it is too large
Load diff
2157
src/modules/LR11x0/firmware/lr1121_transceiver_0103.h
Normal file
2157
src/modules/LR11x0/firmware/lr1121_transceiver_0103.h
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue