[LR11x0] Added support for LR-FHSS

pull/1075/head
jgromes 2024-04-21 15:01:57 +02:00
rodzic ce4d9aa150
commit e8a6297c60
6 zmienionych plików z 298 dodań i 92 usunięć

Wyświetl plik

@ -0,0 +1,110 @@
/*
RadioLib LR11x0 LR-FHSS Modem Example
This example shows how to use LR-FHSS modem in LR11x0 chips.
NOTE: The sketch below is just a guide on how to use
LR-FHSS modem, so this code should not be run directly!
Instead, modify the other examples to use LR-FHSS
modem and use the appropriate configuration
methods.
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lr-fhss-modem
For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/
*/
// include the library
#include <RadioLib.h>
// LR1110 has the following connections:
// NSS pin: 10
// IRQ 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.beginLRFHSS();
if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while (true);
}
// if needed, you can switch between any of the modems
//
// radio.begin() start LoRa modem (and disable LR-FHSS)
// radio.beginLRFHSS() start LR-FHSS modem (and disable LoRa)
// the following settings can also
// be modified at run-time
state = radio.setFrequency(433.5);
state = radio.setLrFhssConfig(RADIOLIB_LR11X0_LR_FHSS_BW_1523_4, // bandwidth
RADIOLIB_LR11X0_LR_FHSS_CR_1_2, // coding rate
3, // header count
0x13A); // hopping sequence seed
state = radio.setOutputPower(10.0);
state = radio.setSyncWord(0x12345678);
if (state != RADIOLIB_ERR_NONE) {
Serial.print(F("Unable to set configuration, code "));
Serial.println(state);
while (true);
}
#warning "This sketch is just an API guide! Read the note at line 6."
}
void loop() {
// LR-FHSS modem can use the same transmit/receive methods
// as the LoRa modem, even their interrupt-driven versions
// transmit LR-FHSS packet
int state = radio.transmit("Hello World!");
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8);
*/
if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[LR1110] Packet transmitted successfully!"));
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
Serial.println(F("[LR1110] Packet too long!"));
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
Serial.println(F("[LR1110] Timed out while transmitting!"));
} else {
Serial.println(F("[LR1110] Failed to transmit packet, code "));
Serial.println(state);
}
// receive LR-FHSS packet
String str;
state = radio.receive(str);
/*
byte byteArr[8];
int state = radio.receive(byteArr, 8);
*/
if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[LR1110] Received packet!"));
Serial.print(F("[LR1110] Data:\t"));
Serial.println(str);
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("[LR1110] Timed out while waiting for packet!"));
} else {
Serial.print(F("[LR1110] Failed to receive packet, code "));
Serial.println(state);
}
}

Wyświetl plik

@ -239,6 +239,10 @@ disablePipe KEYWORD2
getStatus KEYWORD2
setAutoAck KEYWORD2
# LR11x0
beginLRFHSS KEYWORD2
setLrFhssConfig KEYWORD2
# RTTY
idle KEYWORD2
byteArr KEYWORD2

Wyświetl plik

@ -31,6 +31,19 @@ int16_t LR1110::beginGFSK(float freq, float br, float freqDev, float rxBw, int8_
return(state);
}
int16_t LR1110::beginLRFHSS(float freq, uint8_t bw, uint8_t cr, int8_t power, float tcxoVoltage) {
// execute common part
int16_t state = LR11x0::beginLRFHSS(bw, cr, tcxoVoltage);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
state = setFrequency(freq);
RADIOLIB_ASSERT(state);
state = setOutputPower(power);
return(state);
}
int16_t LR1110::setFrequency(float freq) {
return(this->setFrequency(freq, true));
}

Wyświetl plik

@ -52,6 +52,19 @@ class LR1110: public LR11x0 {
\returns \ref status_codes
*/
int16_t beginGFSK(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 156.2, int8_t power = 10, uint16_t preambleLength = 16, float tcxoVoltage = 1.6);
/*!
\brief Initialization method for LR-FHSS modem.
\param freq Carrier frequency in MHz. Defaults to 434.0 MHz.
\param bw LR-FHSS bandwidth, one of RADIOLIB_LR11X0_LR_FHSS_BW_* values. Defaults to 722.66 kHz.
\param cr LR-FHSS coding rate, one of RADIOLIB_LR11X0_LR_FHSS_CR_* values. Defaults to 2/3 coding rate.
\param power Output power in dBm. Defaults to 10 dBm.
\param tcxoVoltage TCXO reference voltage to be set. Defaults to 1.6 V.
If you are seeing -706/-707 error codes, it likely means you are using non-0 value for module with XTAL.
To use XTAL, either set this value to 0, or set LR11x0::XTAL to true.
\returns \ref status_codes
*/
int16_t beginLRFHSS(float freq = 434.0, uint8_t bw = RADIOLIB_LR11X0_LR_FHSS_BW_722_66, uint8_t cr = RADIOLIB_LR11X0_LR_FHSS_CR_2_3, int8_t power = 10, float tcxoVoltage = 1.6);
// configuration methods

Wyświetl plik

@ -14,44 +14,8 @@ LR11x0::LR11x0(Module* mod) : PhysicalLayer(RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE,
}
int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t preambleLength, float tcxoVoltage) {
// set module properties
this->mod->init();
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
this->mod->hal->pinMode(this->mod->getGpio(), this->mod->hal->GpioModeInput);
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
this->mod->hal->pinMode(this->mod->getGpio(), this->mod->hal->GpioModeInput);
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_32;
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_16;
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_8;
this->mod->spiConfig.statusPos = 0;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_LR11X0_CMD_READ_REG_MEM;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_LR11X0_CMD_WRITE_REG_MEM;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_LR11X0_CMD_NOP;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_LR11X0_CMD_GET_STATUS;
this->mod->spiConfig.stream = true;
this->mod->spiConfig.parseStatusCb = SPIparseStatus;
this->mod->spiConfig.checkStatusCb = SPIcheckStatus;
// try to find the LR11x0 chip - this will also reset the module at least once
if(!LR11x0::findChip(this->chipType)) {
RADIOLIB_DEBUG_BASIC_PRINTLN("No LR11x0 found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tLR11x0");
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
// set TCXO control, if requested
if(!this->XTAL && tcxoVoltage > 0.0) {
state = setTCXO(tcxoVoltage);
RADIOLIB_ASSERT(state);
}
// configure settings not accessible by API
state = config(RADIOLIB_LR11X0_PACKET_TYPE_LORA);
// set module properties and perform initial setup
int16_t state = this->modSetup(tcxoVoltage, RADIOLIB_LR11X0_PACKET_TYPE_LORA);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
@ -81,42 +45,8 @@ int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16
}
int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, uint16_t preambleLength, float tcxoVoltage) {
// set module properties
this->mod->init();
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
this->mod->hal->pinMode(this->mod->getGpio(), this->mod->hal->GpioModeInput);
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_32;
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_16;
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_8;
this->mod->spiConfig.statusPos = 0;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_LR11X0_CMD_READ_REG_MEM;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_LR11X0_CMD_WRITE_REG_MEM;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_LR11X0_CMD_NOP;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_LR11X0_CMD_GET_STATUS;
this->mod->spiConfig.stream = true;
this->mod->spiConfig.parseStatusCb = SPIparseStatus;
this->mod->spiConfig.checkStatusCb = SPIcheckStatus;
// try to find the LR11x0 chip - this will also reset the module at least once
if(!LR11x0::findChip(this->chipType)) {
RADIOLIB_DEBUG_BASIC_PRINTLN("No LR11x0 found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tLR11x0");
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
// set TCXO control, if requested
if(!this->XTAL && tcxoVoltage > 0.0) {
state = setTCXO(tcxoVoltage);
RADIOLIB_ASSERT(state);
}
// configure settings not accessible by API
state = config(RADIOLIB_LR11X0_PACKET_TYPE_GFSK);
// set module properties and perform initial setup
int16_t state = this->modSetup(tcxoVoltage, RADIOLIB_LR11X0_PACKET_TYPE_GFSK);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
@ -152,6 +82,22 @@ int16_t LR11x0::beginGFSK(float br, float freqDev, float rxBw, uint16_t preamble
return(RADIOLIB_ERR_NONE);
}
int16_t LR11x0::beginLRFHSS(uint8_t bw, uint8_t cr, float tcxoVoltage) {
// set module properties and perform initial setup
int16_t state = this->modSetup(tcxoVoltage, RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS);
RADIOLIB_ASSERT(state);
// configure publicly accessible settings
state = setLrFhssConfig(bw, cr);
RADIOLIB_ASSERT(state);
state = setSyncWord(0x12AD101B);
RADIOLIB_ASSERT(state);
// set fixed configuration
return(setModulationParamsLrFhss(RADIOLIB_LR11X0_LR_FHSS_BIT_RATE_RAW, RADIOLIB_LR11X0_LR_FHSS_SHAPING_GAUSSIAN_BT_1_0));
}
int16_t LR11x0::reset() {
// run the reset sequence
this->mod->hal->pinMode(this->mod->getRst(), this->mod->hal->GpioModeOutput);
@ -185,18 +131,17 @@ int16_t LR11x0::transmit(uint8_t* data, size_t len, uint8_t addr) {
return(RADIOLIB_ERR_PACKET_TOO_LONG);
}
uint32_t timeout = 0;
// get currently active modem
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
state = getPacketType(&modem);
uint32_t timeout = getTimeOnAir(len);
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
// calculate timeout (150% of expected time-on-air)
timeout = (getTimeOnAir(len) * 3) / 2;
timeout = (timeout * 3) / 2;
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
} else if((modem == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) || (modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS)) {
// calculate timeout (500% of expected time-on-air)
timeout = getTimeOnAir(len) * 5;
timeout = timeout * 5;
} else {
return(RADIOLIB_ERR_UNKNOWN);
@ -248,6 +193,13 @@ int16_t LR11x0::receive(uint8_t* data, size_t len) {
}
float brBps = ((float)(RADIOLIB_LR11X0_CRYSTAL_FREQ) * 1000000.0 * 32.0) / (float)this->bitRate;
timeout = (uint32_t)(((maxLen * 8.0) / brBps) * 1000.0 * 5.0);
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
size_t maxLen = len;
if(len == 0) {
maxLen = 0xFF;
}
timeout = (uint32_t)(((maxLen * 8.0) / (RADIOLIB_LR11X0_LR_FHSS_BIT_RATE)) * 1000.0 * 5.0);
} else {
return(RADIOLIB_ERR_UNKNOWN);
@ -417,10 +369,13 @@ int16_t LR11x0::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
RADIOLIB_ASSERT(state);
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, len, this->crcTypeLoRa, this->invertIQEnabled);
} else if(modem == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
state = setPacketParamsGFSK(this->preambleLengthGFSK, this->preambleDetLength, this->syncWordLength, this->addrComp, this->packetType, len, this->crcTypeGFSK, this->whitening);
} else {
} else if(modem != RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
return(RADIOLIB_ERR_UNKNOWN);
}
RADIOLIB_ASSERT(state);
@ -428,9 +383,17 @@ int16_t LR11x0::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
state = setDioIrqParams(RADIOLIB_LR11X0_IRQ_TX_DONE | RADIOLIB_LR11X0_IRQ_TIMEOUT, 0);
RADIOLIB_ASSERT(state);
// write packet to buffer
state = writeBuffer8(data, len);
RADIOLIB_ASSERT(state);
if(modem == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
// in LR-FHSS mode, the packet is built by the device
// TODO add configurable grid step and device offset
state = lrFhssBuildFrame(this->lrFhssHdrCount, this->lrFhssCr, RADIOLIB_LR11X0_LR_FHSS_GRID_STEP_FCC, true, this->lrFhssBw, this->lrFhssHopSeq, 0, data, len);
} else {
// write packet to buffer
state = writeBuffer8(data, len);
RADIOLIB_ASSERT(state);
}
// clear interrupt flags
state = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
@ -471,7 +434,9 @@ int16_t LR11x0::startReceive(uint32_t timeout, uint32_t irqFlags, size_t len) {
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
state = getPacketType(&modem);
RADIOLIB_ASSERT(state);
if((modem != RADIOLIB_LR11X0_PACKET_TYPE_LORA) && (modem != RADIOLIB_LR11X0_PACKET_TYPE_GFSK)) {
if((modem != RADIOLIB_LR11X0_PACKET_TYPE_LORA) &&
(modem != RADIOLIB_LR11X0_PACKET_TYPE_GFSK) &&
(modem != RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS)) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
@ -519,7 +484,9 @@ int16_t LR11x0::readData(uint8_t* data, size_t len) {
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
state = getPacketType(&modem);
RADIOLIB_ASSERT(state);
if((modem != RADIOLIB_LR11X0_PACKET_TYPE_LORA) && (modem != RADIOLIB_LR11X0_PACKET_TYPE_GFSK)) {
if((modem != RADIOLIB_LR11X0_PACKET_TYPE_LORA) &&
(modem != RADIOLIB_LR11X0_PACKET_TYPE_GFSK) &&
(modem != RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS)) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
@ -659,7 +626,7 @@ int16_t LR11x0::setSpreadingFactor(uint8_t sf, bool legacy) {
RADIOLIB_CHECK_RANGE(sf, 5, 12, RADIOLIB_ERR_INVALID_SPREADING_FACTOR);
// enable SF6 legacy mode
// TODO enable SF6 legacy mode
if(legacy && (sf == 6)) {
//this->mod->SPIsetRegValue(RADIOLIB_LR11X0_REG_SF6_SX127X_COMPAT, RADIOLIB_LR11X0_SF6_SX127X, 18, 18);
}
@ -702,8 +669,20 @@ int16_t LR11x0::setCodingRate(uint8_t cr, bool longInterleave) {
return(setModulationParamsLoRa(this->spreadingFactor, this->bandwidth, this->codingRate, this->ldrOptimize));
}
int16_t LR11x0::setSyncWord(uint8_t syncWord) {
return(setLoRaSyncWord(syncWord));
int16_t LR11x0::setSyncWord(uint32_t syncWord) {
// check active modem
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
int16_t state = getPacketType(&type);
RADIOLIB_ASSERT(state);
if(type == RADIOLIB_LR11X0_PACKET_TYPE_LORA) {
return(setLoRaSyncWord(syncWord & 0xFF));
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
return(lrFhssSetSyncWord(syncWord));
}
return(RADIOLIB_ERR_WRONG_MODEM);
}
int16_t LR11x0::setBitRate(float br) {
@ -1271,6 +1250,9 @@ uint32_t LR11x0::getTimeOnAir(size_t len) {
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_GFSK) {
return(((uint32_t)len * 8 * 1000000UL) / this->bitRate);
} else if(type == RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
return(((uint32_t)len * 8 * 1000000UL) / RADIOLIB_LR11X0_LR_FHSS_BIT_RATE);
}
return(0);
@ -1280,6 +1262,65 @@ float LR11x0::getDataRate() const {
return(this->dataRateMeasured);
}
int16_t LR11x0::setLrFhssConfig(uint8_t bw, uint8_t cr, uint8_t hdrCount, uint16_t hopSeed) {
// check active modem
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
int16_t state = getPacketType(&type);
RADIOLIB_ASSERT(state);
if(type != RADIOLIB_LR11X0_PACKET_TYPE_LR_FHSS) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
// check and cache all parameters
RADIOLIB_CHECK_RANGE((int8_t)cr, (int8_t)RADIOLIB_LR11X0_LR_FHSS_CR_5_6, (int8_t)RADIOLIB_LR11X0_LR_FHSS_CR_1_3, RADIOLIB_ERR_INVALID_CODING_RATE);
this->lrFhssCr = cr;
RADIOLIB_CHECK_RANGE((int8_t)bw, (int8_t)RADIOLIB_LR11X0_LR_FHSS_BW_39_06, (int8_t)RADIOLIB_LR11X0_LR_FHSS_BW_1574_2, RADIOLIB_ERR_INVALID_BANDWIDTH);
this->lrFhssBw = bw;
RADIOLIB_CHECK_RANGE(hdrCount, 1, 4, RADIOLIB_ERR_INVALID_BIT_RANGE);
this->lrFhssHdrCount = hdrCount;
RADIOLIB_CHECK_RANGE((int16_t)hopSeed, (int16_t)0x000, (int16_t)0x1FF, RADIOLIB_ERR_INVALID_DATA_SHAPING);
this->lrFhssHopSeq = hopSeed;
return(RADIOLIB_ERR_NONE);
}
int16_t LR11x0::modSetup(float tcxoVoltage, uint8_t modem) {
this->mod->init();
this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput);
this->mod->hal->pinMode(this->mod->getGpio(), this->mod->hal->GpioModeInput);
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_32;
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_16;
this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_8;
this->mod->spiConfig.statusPos = 0;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_LR11X0_CMD_READ_REG_MEM;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_LR11X0_CMD_WRITE_REG_MEM;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_LR11X0_CMD_NOP;
this->mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_LR11X0_CMD_GET_STATUS;
this->mod->spiConfig.stream = true;
this->mod->spiConfig.parseStatusCb = SPIparseStatus;
this->mod->spiConfig.checkStatusCb = SPIcheckStatus;
// try to find the LR11x0 chip - this will also reset the module at least once
if(!LR11x0::findChip(this->chipType)) {
RADIOLIB_DEBUG_BASIC_PRINTLN("No LR11x0 found!");
this->mod->term();
return(RADIOLIB_ERR_CHIP_NOT_FOUND);
}
RADIOLIB_DEBUG_BASIC_PRINTLN("M\tLR11x0");
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
// set TCXO control, if requested
if(!this->XTAL && tcxoVoltage > 0.0) {
state = setTCXO(tcxoVoltage);
RADIOLIB_ASSERT(state);
}
// configure settings not accessible by API
return(config(modem));
}
int16_t LR11x0::SPIparseStatus(uint8_t in) {
if((in & 0b00001110) == RADIOLIB_LR11X0_STAT_1_CMD_PERR) {
return(RADIOLIB_ERR_SPI_CMD_INVALID);

Wyświetl plik

@ -366,7 +366,8 @@
#define RADIOLIB_LR11X0_GFSK_RX_BW_312_0 (0x19UL << 0) // 7 0 312.0 kHz
#define RADIOLIB_LR11X0_GFSK_RX_BW_373_6 (0x11UL << 0) // 7 0 373.6 kHz
#define RADIOLIB_LR11X0_GFSK_RX_BW_467_0 (0x09UL << 0) // 7 0 467.0 kHz
#define RADIOLIB_LR11X0_LR_FHSS_BIT_RATE (0x8001E848UL) // 31 0 LR FHSS bit rate: 488.28215 bps
#define RADIOLIB_LR11X0_LR_FHSS_BIT_RATE (488.28215) // 31 0 LR FHSS bit rate: 488.28215 bps
#define RADIOLIB_LR11X0_LR_FHSS_BIT_RATE_RAW (0x8001E848UL) // 31 0 488.28215 bps in raw
#define RADIOLIB_LR11X0_LR_FHSS_SHAPING_GAUSSIAN_BT_1_0 (0x0BUL << 0) // 7 0 shaping filter: Gaussian, BT = 1.0
#define RADIOLIB_LR11X0_SIGFOX_SHAPING_GAUSSIAN_BT_0_7 (0x16UL << 0) // 7 0 shaping filter: Gaussian, BT = 0.7
@ -582,6 +583,15 @@ class LR11x0: public PhysicalLayer {
*/
int16_t beginGFSK(float br, float freqDev, float rxBw, uint16_t preambleLength, float tcxoVoltage);
/*!
\brief Initialization method for LR-FHSS modem.
\param bw LR-FHSS bandwidth, one of RADIOLIB_LR11X0_LR_FHSS_BW_* values.
\param cr LR-FHSS coding rate, one of RADIOLIB_LR11X0_LR_FHSS_CR_* values.
\param tcxoVoltage TCXO reference voltage to be set.
\returns \ref status_codes
*/
int16_t beginLRFHSS(uint8_t bw, uint8_t cr, float tcxoVoltage);
/*!
\brief Reset method. Will reset the chip to the default state using RST pin.
\returns \ref status_codes
@ -798,11 +808,11 @@ class LR11x0: public PhysicalLayer {
int16_t setCodingRate(uint8_t cr, bool longInterleave = false);
/*!
\brief Sets LoRa sync word.
\param syncWord LoRa sync word to be set.
\brief Sets LoRa or LR-FHSS sync word.
\param syncWord LoRa or LR-FHSS sync word to be set. For LoRa, only 8 least significant bits will be used
\returns \ref status_codes
*/
int16_t setSyncWord(uint8_t syncWord);
int16_t setSyncWord(uint32_t syncWord);
/*!
\brief Sets GFSK bit rate. Allowed values range from 0.6 to 300.0 kbps.
@ -996,6 +1006,16 @@ class LR11x0: public PhysicalLayer {
*/
float getDataRate() const;
/*!
\brief Sets LR-FHSS configuration.
\param bw LR-FHSS bandwidth, one of RADIOLIB_LR11X0_LR_FHSS_BW_* values.
\param cr LR-FHSS coding rate, one of RADIOLIB_LR11X0_LR_FHSS_CR_* values.
\param hdrCount Header packet count, 1 - 4. Defaults to 3.
\param hopSeed 9-bit seed number for PRNG generation of the hopping sequence. Defaults to 0x13A.
\returns \ref status_codes
*/
int16_t setLrFhssConfig(uint8_t bw, uint8_t cr, uint8_t hdrCount = 3, uint16_t hopSeed = 0x13A);
#if !RADIOLIB_GODMODE && !RADIOLIB_LOW_LEVEL
protected:
#endif
@ -1165,8 +1185,13 @@ class LR11x0: public PhysicalLayer {
uint8_t preambleDetLength = 0, rxBandwidth = 0, pulseShape = 0, crcTypeGFSK = 0, syncWordLength = 0, addrComp = 0, whitening = 0, packetType = 0, node = 0;
uint16_t preambleLengthGFSK = 0;
// cached LR-FHSS parameters
uint8_t lrFhssCr = 0, lrFhssBw = 0, lrFhssHdrCount = 0;
uint16_t lrFhssHopSeq = 0;
float dataRateMeasured = 0;
int16_t modSetup(float tcxoVoltage, uint8_t modem);
static int16_t SPIparseStatus(uint8_t in);
static int16_t SPIcheckStatus(Module* mod);
bool findChip(uint8_t ver);