[LRxxxx] Create base class for common LR11xx and LR20xx commands

lr2021
jgromes 2025-10-13 20:36:34 +01:00
rodzic f203c77c16
commit d696fed842
9 zmienionych plików z 111 dodań i 117 usunięć

Wyświetl plik

@ -5,7 +5,7 @@
#if !RADIOLIB_EXCLUDE_LR11X0
LR11x0::LR11x0(Module* mod) : PhysicalLayer() {
LR11x0::LR11x0(Module* mod) : PhysicalLayer(), LRxxxx(mod) {
this->freqStep = RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_LR11X0_MAX_PACKET_LENGTH;
this->mod = mod;
@ -1227,7 +1227,8 @@ size_t LR11x0::getPacketLength(bool update, uint8_t* offset) {
}
uint8_t len = 0;
(void)getRxBufferStatus(&len, offset);
int state = getRxBufferStatus(&len, offset);
RADIOLIB_DEBUG_BASIC_PRINT("getRxBufferStatus state = %d\n", state);
return((size_t)len);
}
@ -1785,28 +1786,6 @@ int16_t LR11x0::SPIcheckStatus(Module* mod) {
return(LR11x0::SPIparseStatus(buff[0]));
}
int16_t LR11x0::SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, const uint8_t* out, size_t outLen) {
int16_t state = RADIOLIB_ERR_UNKNOWN;
if(!write) {
// the SPI interface of LR11x0 requires two separate transactions for reading
// send the 16-bit command
state = this->mod->SPIwriteStream(cmd, out, outLen, true, false);
RADIOLIB_ASSERT(state);
// read the result without command
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_0;
state = this->mod->SPIreadStream(RADIOLIB_LR11X0_CMD_NOP, data, len, true, false);
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_16;
} else {
// write is just a single transaction
state = this->mod->SPIwriteStream(cmd, data, len, true, true);
}
return(state);
}
bool LR11x0::findChip(uint8_t ver) {
uint8_t i = 0;
bool flagFound = false;

Wyświetl plik

@ -8,6 +8,7 @@
#include "../../Module.h"
#include "../../protocols/PhysicalLayer/PhysicalLayer.h"
#include "../LR11x0/LR_common.h"
// LR11X0 physical layer properties
#define RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE 1.0
@ -886,7 +887,7 @@ struct LR11x0GnssAlmanacStatus_t {
\brief Base class for %LR11x0 series. All derived classes for %LR11x0 (e.g. LR1110 or LR1120) inherit from this base class.
This class should not be instantiated directly from user code, only from its derived classes.
*/
class LR11x0: public PhysicalLayer {
class LR11x0: public PhysicalLayer, public LRxxxx {
public:
// introduce PhysicalLayer overloads
using PhysicalLayer::transmit;
@ -1834,8 +1835,6 @@ class LR11x0: public PhysicalLayer {
int16_t bootGetChipEui(uint8_t* eui);
int16_t bootGetJoinEui(uint8_t* eui);
int16_t SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, const uint8_t* out = NULL, size_t outLen = 0);
#if !RADIOLIB_GODMODE
protected:
#endif

Wyświetl plik

@ -56,7 +56,7 @@ int16_t LR11x0::writeRegMem32(uint32_t addr, const 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(LR_writeCommon(this->mod, RADIOLIB_LR11X0_CMD_WRITE_REG_MEM, addr, data, len, false));
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) {
@ -830,7 +830,7 @@ int16_t LR11x0::bootWriteFlashEncrypted(uint32_t offset, const uint32_t* data, s
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
}
return(LR_writeCommon(this->mod, RADIOLIB_LR11X0_CMD_BOOT_WRITE_FLASH_ENCRYPTED, offset, data, len, nonvolatile));
return(this->writeCommon(RADIOLIB_LR11X0_CMD_BOOT_WRITE_FLASH_ENCRYPTED, offset, data, len, nonvolatile));
}
int16_t LR11x0::bootReboot(bool stay) {

Wyświetl plik

@ -178,7 +178,7 @@ int16_t LR11x0::cryptoCheckEncryptedFirmwareImage(uint32_t offset, const uint32_
if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
}
return(LR_writeCommon(this->mod, RADIOLIB_LR11X0_CMD_CRYPTO_CHECK_ENCRYPTED_FIRMWARE_IMAGE, offset, data, len, nonvolatile));
return(this->writeCommon(RADIOLIB_LR11X0_CMD_CRYPTO_CHECK_ENCRYPTED_FIRMWARE_IMAGE, offset, data, len, nonvolatile));
}
int16_t LR11x0::cryptoCheckEncryptedFirmwareImageResult(bool* result) {

Wyświetl plik

@ -1,6 +1,64 @@
#include "LR_common.h"
int16_t LR_writeCommon(Module* mod, uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len, bool nonvolatile) {
LRxxxx::LRxxxx(Module* mod) {
this->mod = mod;
}
int16_t LRxxxx::writeRegMem32(uint16_t cmd, uint32_t addr, const uint32_t* data, size_t len) {
// check maximum size
if(len > (RADIOLIB_LRXXXX_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
}
return(this->writeCommon(cmd, addr, data, len, false));
}
int16_t LRxxxx::writeRegMemMask32(uint16_t cmd, uint32_t addr, uint32_t mask, uint32_t data) {
uint8_t buff[12] = {
(uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
(uint8_t)((mask >> 24) & 0xFF), (uint8_t)((mask >> 16) & 0xFF), (uint8_t)((mask >> 8) & 0xFF), (uint8_t)(mask & 0xFF),
(uint8_t)((data >> 24) & 0xFF), (uint8_t)((data >> 16) & 0xFF), (uint8_t)((data >> 8) & 0xFF), (uint8_t)(data & 0xFF),
};
return(this->SPIcommand(cmd, true, buff, sizeof(buff)));
}
int16_t LRxxxx::readRegMem32(uint16_t cmd, uint32_t addr, uint32_t* data, size_t len) {
// check maximum size
if(len >= (RADIOLIB_LRXXXX_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
}
// the request contains the address and length
uint8_t reqBuff[5] = {
(uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF),
(uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
(uint8_t)len,
};
// build buffers - later we need to ensure endians are correct,
// so there is probably no way to do this without copying buffers and iterating
#if RADIOLIB_STATIC_ONLY
uint8_t rplBuff[RADIOLIB_LR2021_SPI_MAX_READ_WRITE_LEN];
#else
uint8_t* rplBuff = new uint8_t[len*sizeof(uint32_t)];
#endif
int16_t state = this->SPIcommand(cmd, false, rplBuff, len*sizeof(uint32_t), reqBuff, sizeof(reqBuff));
// convert endians
if(data && (state == RADIOLIB_ERR_NONE)) {
for(size_t i = 0; i < len; i++) {
data[i] = ((uint32_t)rplBuff[2 + i*sizeof(uint32_t)] << 24) | ((uint32_t)rplBuff[3 + i*sizeof(uint32_t)] << 16) | ((uint32_t)rplBuff[4 + i*sizeof(uint32_t)] << 8) | (uint32_t)rplBuff[5 + i*sizeof(uint32_t)];
}
}
#if !RADIOLIB_STATIC_ONLY
delete[] rplBuff;
#endif
return(state);
}
int16_t LRxxxx::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);
@ -31,9 +89,31 @@ int16_t LR_writeCommon(Module* mod, uint16_t cmd, uint32_t addrOffset, const uin
dataBuff[7 + i*sizeof(uint32_t)] = (uint8_t)(bin & 0xFF);
}
int16_t state = mod->SPIwriteStream(cmd, dataBuff, buffLen, true, false);
int16_t state = this->mod->SPIwriteStream(cmd, dataBuff, buffLen, true, false);
#if !RADIOLIB_STATIC_ONLY
delete[] dataBuff;
#endif
return(state);
}
int16_t LRxxxx::SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, const uint8_t* out, size_t outLen) {
int16_t state = RADIOLIB_ERR_UNKNOWN;
if(!write) {
// the SPI interface of LR11x0 requires two separate transactions for reading
// send the 16-bit command
state = this->mod->SPIwriteStream(cmd, out, outLen, true, false);
RADIOLIB_ASSERT(state);
// read the result without command
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_0;
state = this->mod->SPIreadStream(RADIOLIB_LRXXXX_CMD_NOP, data, len, true, false);
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_16;
} else {
// write is just a single transaction
state = this->mod->SPIwriteStream(cmd, data, len, true, true);
}
return(state);
}

Wyświetl plik

@ -3,6 +3,23 @@
#include "../../Module.h"
int16_t LR_writeCommon(Module* mod, uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len, bool nonvolatile);
#define RADIOLIB_LRXXXX_CMD_NOP (0x0000)
#define RADIOLIB_LRXXXX_SPI_MAX_READ_WRITE_LEN (256)
class LRxxxx {
public:
LRxxxx(Module* mod);
protected:
int16_t writeRegMem32(uint16_t cmd, uint32_t addr, const uint32_t* data, size_t len);
int16_t writeRegMemMask32(uint16_t cmd, uint32_t addr, uint32_t mask, uint32_t data);
int16_t readRegMem32(uint16_t cmd, uint32_t addr, 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 SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, const uint8_t* out = NULL, size_t outLen = 0);
private:
Module* mod;
};
#endif

Wyświetl plik

@ -5,7 +5,7 @@
#if !RADIOLIB_EXCLUDE_LR2021
LR2021::LR2021(Module* mod) : PhysicalLayer() {
LR2021::LR2021(Module* mod) : PhysicalLayer(), LRxxxx(mod) {
this->freqStep = RADIOLIB_LR2021_FREQUENCY_STEP_SIZE;
this->maxPacketLength = RADIOLIB_LR2021_MAX_PACKET_LENGTH;
this->mod = mod;
@ -69,26 +69,4 @@ int16_t LR2021::SPIcheckStatus(Module* mod) {
return(LR2021::SPIparseStatus(buff[0]));
}
int16_t LR2021::SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, const uint8_t* out, size_t outLen) {
int16_t state = RADIOLIB_ERR_UNKNOWN;
if(!write) {
// the SPI interface of LR2021 requires two separate transactions for reading
// send the 16-bit command
state = this->mod->SPIwriteStream(cmd, out, outLen, true, false);
RADIOLIB_ASSERT(state);
// read the result without command
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_0;
state = this->mod->SPIreadStream(RADIOLIB_LR2021_CMD_NOP, data, len, true, false);
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_16;
} else {
// write is just a single transaction
state = this->mod->SPIwriteStream(cmd, data, len, true, true);
}
return(state);
}
#endif

Wyświetl plik

@ -8,6 +8,7 @@
#include "../../Module.h"
#include "../../protocols/PhysicalLayer/PhysicalLayer.h"
#include "../LR11x0/LR_common.h"
// LR2021 physical layer properties
#define RADIOLIB_LR2021_FREQUENCY_STEP_SIZE 1.0
@ -187,9 +188,6 @@
#define RADIOLIB_LR2021_IRQ_RNG_EXCH_VALID (0x01UL << 30) // 31 0 master receive valid ranging response
#define RADIOLIB_LR2021_IRQ_RNG_TIMEOUT (0x01UL << 31) // 31 0 ranging timeout
// RADIOLIB_LR2021_CMD_WRITE_REG_MEM
#define RADIOLIB_LR2021_SPI_MAX_READ_WRITE_LEN (256) // 7 0 maximum length of read/write SPI payload in bytes
// RADIOLIB_LR2021_CMD_SET_SLEEP
#define RADIOLIB_LR2021_SLEEP_32K_CLK_DISABLED (0x00UL << 0) // 0 0 32 kHz clock: disabled
#define RADIOLIB_LR2021_SLEEP_32K_CLK_ENABLED (0x01UL << 0) // 0 0 enabled
@ -201,7 +199,7 @@
\class LR2021
\brief
*/
class LR2021: public PhysicalLayer {
class LR2021: public PhysicalLayer, public LRxxxx {
public:
// introduce PhysicalLayer overloads
using PhysicalLayer::transmit;
@ -227,7 +225,6 @@ class LR2021: public PhysicalLayer {
#if !RADIOLIB_GODMODE
protected:
#endif
int16_t SPIcommand(uint16_t cmd, bool write, uint8_t* data, size_t len, const uint8_t* out = NULL, size_t outLen = 0);
#if !RADIOLIB_GODMODE
private:

Wyświetl plik

@ -15,60 +15,4 @@ int16_t LR2021::writeRadioTxFifo(uint8_t* data, size_t len) {
return(this->SPIcommand(RADIOLIB_LR2021_CMD_WRITE_TX_FIFO, true, data, len, NULL, 0));
}
// TODO reuse LR11x0 method
int16_t LR2021::writeRegMem32(uint32_t addr, const uint32_t* data, size_t len) {
// check maximum size
if(len > (RADIOLIB_LR2021_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
}
return(LR_writeCommon(this->mod, RADIOLIB_LR2021_CMD_WRITE_REG_MEM_32, addr, data, len, false));
}
// TODO reuse LR11x0 method
int16_t LR2021::writeRegMemMask32(uint32_t addr, uint32_t mask, uint32_t data) {
uint8_t buff[12] = {
(uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
(uint8_t)((mask >> 24) & 0xFF), (uint8_t)((mask >> 16) & 0xFF), (uint8_t)((mask >> 8) & 0xFF), (uint8_t)(mask & 0xFF),
(uint8_t)((data >> 24) & 0xFF), (uint8_t)((data >> 16) & 0xFF), (uint8_t)((data >> 8) & 0xFF), (uint8_t)(data & 0xFF),
};
return(this->SPIcommand(RADIOLIB_LR2021_CMD_WRITE_REG_MEM_MASK_32, true, buff, sizeof(buff)));
}
// TODO reuse LR11x0 method
int16_t LR2021::readRegMem32(uint32_t addr, uint32_t* data, size_t len) {
// check maximum size
if(len >= (RADIOLIB_LR2021_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);
}
// the request contains the address and length
uint8_t reqBuff[5] = {
(uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF),
(uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
(uint8_t)len,
};
// build buffers - later we need to ensure endians are correct,
// so there is probably no way to do this without copying buffers and iterating
#if RADIOLIB_STATIC_ONLY
uint8_t rplBuff[RADIOLIB_LR2021_SPI_MAX_READ_WRITE_LEN];
#else
uint8_t* rplBuff = new uint8_t[len*sizeof(uint32_t)];
#endif
int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_READ_REG_MEM_32, false, rplBuff, len*sizeof(uint32_t), reqBuff, sizeof(reqBuff));
// convert endians
if(data && (state == RADIOLIB_ERR_NONE)) {
for(size_t i = 0; i < len; i++) {
data[i] = ((uint32_t)rplBuff[2 + i*sizeof(uint32_t)] << 24) | ((uint32_t)rplBuff[3 + i*sizeof(uint32_t)] << 16) | ((uint32_t)rplBuff[4 + i*sizeof(uint32_t)] << 8) | (uint32_t)rplBuff[5 + i*sizeof(uint32_t)];
}
}
#if !RADIOLIB_STATIC_ONLY
delete[] rplBuff;
#endif
return(state);
}
#endif