Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Channel scan configuration #1190

Merged
merged 39 commits into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
9fe39d5
[PHY] Added channel scan configuration
jgromes Aug 18, 2024
6fdc077
[LR11x0] Added channel scan configuration
jgromes Aug 18, 2024
b0f9ed6
[SX126x] Added channel scan configuration
jgromes Aug 18, 2024
5a04007
[SX128x] Added channel scan configuration
jgromes Aug 18, 2024
f2d005c
Use microsecond timeout
jgromes Aug 18, 2024
02b92fd
[PHY] Added generalized IRQ handling via PHY
jgromes Aug 20, 2024
d75e286
[LR11x0] Added generalized IRQ handling via PHY
jgromes Aug 20, 2024
fcdc1d7
[SX126x] Added generalized IRQ handling via PHY
jgromes Aug 20, 2024
7067c67
[SX127x] Added generalized IRQ handling via PHY
jgromes Aug 20, 2024
8c24a5f
[SX128x] Added generalized IRQ handling via PHY
jgromes Aug 20, 2024
d1803bc
Added missing typedef
jgromes Aug 20, 2024
2545886
[PHY] Fix IRQ method argument type
jgromes Aug 20, 2024
bac6791
[SX128x] Fix non-trivial initializer usage
jgromes Aug 20, 2024
76096ef
[LR11x0] Added missing override specifiers
jgromes Aug 20, 2024
21bf99c
[SX126x] Added missing override specifiers
jgromes Aug 20, 2024
28f404a
[SX127x] Added missing override specifiers
jgromes Aug 20, 2024
77241d2
[SX128x] Added missing override specifiers
jgromes Aug 20, 2024
44c4742
[PHY] Added missing IRQ map initializer
jgromes Aug 20, 2024
4f3c7d4
[CI] Drop APRS builds on AVR
jgromes Aug 21, 2024
b9ffbb1
[CI] Drop Morse builds for AVR
jgromes Aug 25, 2024
644d0ec
[PHY] Rework generic IRQ to allow multiple flags
jgromes Aug 25, 2024
ef5ee1f
[LR11x0] Rework generic IRQ to allow multiple flags
jgromes Aug 25, 2024
cc29905
[SX126x] Rework generic IRQ to allow multiple flags
jgromes Aug 25, 2024
17de575
[SX127x] Rework generic IRQ to allow multiple flags
jgromes Aug 25, 2024
8fe6ba8
[SX128x] Rework generic IRQ to allow multiple flags
jgromes Aug 25, 2024
1a462dc
[LoRaWAN] Use generic IRQ
jgromes Aug 25, 2024
b3edfd8
Add missing typedef
jgromes Aug 25, 2024
29dd65d
[SX127x] Make Rx mode implicit based on timeout
jgromes Aug 28, 2024
0caedc1
[SX127x] Fixed shadowed variable
jgromes Aug 28, 2024
26aae8d
[LR11x0] Fix missing initializers
jgromes Aug 28, 2024
0e694f3
[SX127x] Added default startReceive arguments
jgromes Aug 28, 2024
d81d802
[LR11x0] Pass scan config by const reference
jgromes Aug 28, 2024
fa1760d
[SX126x] Pass scan config by const reference
jgromes Aug 28, 2024
d5987ac
[SX128x] Pass scan config by const reference
jgromes Aug 28, 2024
9d99e38
[PHY] Pass scan config by const reference
jgromes Aug 28, 2024
7d1df89
[SX127x] Add missing IRQ conversion
jgromes Aug 30, 2024
ed30c50
[SX126x] Fixed default CAD scan config IRQ
jgromes Aug 31, 2024
595e780
[LR11x0] Fixed default CAD scan config IRQ
jgromes Aug 31, 2024
6fc4bfa
[LR11x0] Fix comments referencing DIO1
jgromes Sep 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
# platform-dependent settings - extra board options, board index URLs, skip patterns etc.
include:
- id: arduino:avr:uno
run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN|LR11x0_Firmware_Update|Pager)" >> $GITHUB_OUTPUT
run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN|LR11x0_Firmware_Update|Pager|APRS|Morse)" >> $GITHUB_OUTPUT
- id: arduino:avr:mega
run: |
echo "options=':cpu=atmega2560'" >> $GITHUB_OUTPUT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ void loop() {

// check if we got a preamble
if(detectedFlag) {
// LoRa preamble was detected
// LoRa preamble was detected, start reception with timeout of 100 LoRa symbols
Serial.print(F("[SX1278] Preamble detected, starting reception ... "));
state = radio.startReceive(0, RADIOLIB_SX127X_RXSINGLE);
state = radio.startReceive(100);
if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Expand Down
6 changes: 6 additions & 0 deletions src/TypeDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,12 @@
*/
typedef unsigned long RadioLibTime_t;

/*!
\brief Type used for radio-agnostic IRQ flags. IRQ to enable corresponds to the bit index (RadioLibIrq_t).
For example, if bit 0 is set, the module will enable its RADIOLIB_IRQ_TX_DONE (if it is supported).
*/
typedef uint32_t RadioLibIrqFlags_t;

/*!
\}
*/
Expand Down
101 changes: 58 additions & 43 deletions src/modules/LR11x0/LR11x0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@
LR11x0::LR11x0(Module* mod) : PhysicalLayer(RADIOLIB_LR11X0_FREQUENCY_STEP_SIZE, RADIOLIB_LR11X0_MAX_PACKET_LENGTH) {
this->mod = mod;
this->XTAL = false;
this->irqMap[RADIOLIB_IRQ_TX_DONE] = RADIOLIB_LR11X0_IRQ_TX_DONE;
this->irqMap[RADIOLIB_IRQ_RX_DONE] = RADIOLIB_LR11X0_IRQ_RX_DONE;
this->irqMap[RADIOLIB_IRQ_PREAMBLE_DETECTED] = RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED;
this->irqMap[RADIOLIB_IRQ_SYNC_WORD_VALID] = RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID;
this->irqMap[RADIOLIB_IRQ_HEADER_VALID] = RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID;
this->irqMap[RADIOLIB_IRQ_HEADER_ERR] = RADIOLIB_LR11X0_IRQ_HEADER_ERR;
this->irqMap[RADIOLIB_IRQ_CRC_ERR] = RADIOLIB_LR11X0_IRQ_CRC_ERR;
this->irqMap[RADIOLIB_IRQ_CAD_DONE] = RADIOLIB_LR11X0_IRQ_CAD_DONE;
this->irqMap[RADIOLIB_IRQ_CAD_DETECTED] = RADIOLIB_LR11X0_IRQ_CAD_DETECTED;
this->irqMap[RADIOLIB_IRQ_TIMEOUT] = RADIOLIB_LR11X0_IRQ_TIMEOUT;
}

int16_t LR11x0::begin(float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t preambleLength, float tcxoVoltage) {
Expand Down Expand Up @@ -278,12 +288,23 @@ int16_t LR11x0::receiveDirect() {
}

int16_t LR11x0::scanChannel() {
return(this->scanChannel(RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, RADIOLIB_LR11X0_CAD_PARAM_DEFAULT));
ChannelScanConfig_t config = {
.cad = {
.symNum = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT,
.detPeak = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT,
.detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT,
.exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT,
.timeout = 0,
.irqFlags = RADIOLIB_IRQ_CAD_DEFAULT_FLAGS,
.irqMask = RADIOLIB_IRQ_CAD_DEFAULT_MASK,
},
};
return(this->scanChannel(config));
}

int16_t LR11x0::scanChannel(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
int16_t LR11x0::scanChannel(ChannelScanConfig_t config) {
// set mode to CAD
int state = startChannelScan(symbolNum, detPeak, detMin);
int state = startChannelScan(config);
RADIOLIB_ASSERT(state);

// wait for channel activity detected or timeout
Expand Down Expand Up @@ -460,10 +481,9 @@ int16_t LR11x0::startReceive(uint32_t timeout, uint32_t irqFlags, uint32_t irqMa
// set DIO mapping
uint32_t irq = irqFlags;
if(timeout != RADIOLIB_LR11X0_RX_TIMEOUT_INF) {
irq |= RADIOLIB_LR11X0_IRQ_TIMEOUT;
irq |= (1UL << RADIOLIB_IRQ_TIMEOUT);
}

state = setDioIrqParams(irq);
state = setDioIrqParams(getIrqMapped(irq));
jgromes marked this conversation as resolved.
Show resolved Hide resolved
RADIOLIB_ASSERT(state);

// clear interrupt flags
Expand Down Expand Up @@ -541,10 +561,20 @@ int16_t LR11x0::readData(uint8_t* data, size_t len) {
}

int16_t LR11x0::startChannelScan() {
return(this->startChannelScan(RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, RADIOLIB_LR11X0_CAD_PARAM_DEFAULT, RADIOLIB_LR11X0_CAD_PARAM_DEFAULT));
ChannelScanConfig_t config = {
.cad = {
.symNum = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT,
.detPeak = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT,
.detMin = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT,
.exitMode = RADIOLIB_LR11X0_CAD_PARAM_DEFAULT,
.timeout = 0,
.irqFlags = RADIOLIB_IRQ_NOT_SUPPORTED,
},
};
return(this->startChannelScan(config));
}

int16_t LR11x0::startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
int16_t LR11x0::startChannelScan(const ChannelScanConfig_t &config) {
// check active modem
int16_t state = RADIOLIB_ERR_NONE;
uint8_t modem = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
Expand All @@ -562,15 +592,16 @@ int16_t LR11x0::startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t det
this->mod->setRfSwitchState(Module::MODE_RX);

// set DIO pin mapping
state = setDioIrqParams(RADIOLIB_LR11X0_IRQ_CAD_DETECTED | RADIOLIB_LR11X0_IRQ_CAD_DONE);
uint16_t irqFlags = (config.cad.irqFlags == RADIOLIB_IRQ_NOT_SUPPORTED) ? RADIOLIB_LR11X0_IRQ_CAD_DETECTED | RADIOLIB_LR11X0_IRQ_CAD_DONE : config.cad.irqFlags;
state = setDioIrqParams(irqFlags, irqFlags);
RADIOLIB_ASSERT(state);

// clear interrupt flags
state = clearIrq(RADIOLIB_LR11X0_IRQ_ALL);
RADIOLIB_ASSERT(state);

// set mode to CAD
return(startCad(symbolNum, detPeak, detMin));
return(startCad(config.cad.symNum, config.cad.detPeak, config.cad.detMin, config.cad.exitMode, config.cad.timeout));
}

int16_t LR11x0::getChannelScanResult() {
Expand Down Expand Up @@ -1322,39 +1353,16 @@ RadioLibTime_t LR11x0::calculateRxTimeout(RadioLibTime_t timeoutUs) {
return(timeout);
}

int16_t LR11x0::irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) {
irqFlags = RADIOLIB_LR11X0_IRQ_RX_DONE | RADIOLIB_LR11X0_IRQ_TIMEOUT; // flags that can appear in the IRQ register
irqMask = irqFlags; // on LR11x0, these are the same
return(RADIOLIB_ERR_NONE);
uint32_t LR11x0::getIrqFlags() {
return((uint32_t)this->getIrqStatus());
}

int16_t LR11x0::checkIrq(uint8_t irq) {
uint16_t flags = getIrqStatus();
switch(irq) {
case RADIOLIB_IRQ_TX_DONE:
return(flags & RADIOLIB_LR11X0_IRQ_TX_DONE);
case RADIOLIB_IRQ_RX_DONE:
return(flags & RADIOLIB_LR11X0_IRQ_RX_DONE);
case RADIOLIB_IRQ_PREAMBLE_DETECTED:
return(flags & RADIOLIB_LR11X0_IRQ_PREAMBLE_DETECTED);
case RADIOLIB_IRQ_SYNC_WORD_VALID:
return(flags & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID);
case RADIOLIB_IRQ_HEADER_VALID:
return(flags & RADIOLIB_LR11X0_IRQ_SYNC_WORD_HEADER_VALID);
case RADIOLIB_IRQ_HEADER_ERR:
return(flags & RADIOLIB_LR11X0_IRQ_HEADER_ERR);
case RADIOLIB_IRQ_CRC_ERR:
return(flags & RADIOLIB_LR11X0_IRQ_CRC_ERR);
case RADIOLIB_IRQ_CAD_DONE:
return(flags & RADIOLIB_LR11X0_IRQ_CAD_DONE);
case RADIOLIB_IRQ_CAD_DETECTED:
return(flags & RADIOLIB_LR11X0_IRQ_CAD_DETECTED);
case RADIOLIB_IRQ_TIMEOUT:
return(flags & RADIOLIB_LR11X0_IRQ_TIMEOUT);
default:
return(RADIOLIB_ERR_UNSUPPORTED);
}
return(RADIOLIB_ERR_UNSUPPORTED);
int16_t LR11x0::setIrqFlags(uint32_t irq) {
return(this->setDioIrqParams(irq, irq));
}

int16_t LR11x0::clearIrqFlags(uint32_t irq) {
return(this->clearIrq(irq));
}

uint8_t LR11x0::randomByte() {
Expand Down Expand Up @@ -2007,7 +2015,7 @@ int16_t LR11x0::setPacketMode(uint8_t mode, uint8_t len) {
return(state);
}

int16_t LR11x0::startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
int16_t LR11x0::startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8_t exitMode, RadioLibTime_t timeout) {
// check active modem
uint8_t type = RADIOLIB_LR11X0_PACKET_TYPE_NONE;
int16_t state = getPacketType(&type);
Expand All @@ -2034,9 +2042,16 @@ int16_t LR11x0::startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin) {
min = 10;
}

uint8_t mode = exitMode;
if(mode == RADIOLIB_LR11X0_CAD_PARAM_DEFAULT) {
mode = RADIOLIB_LR11X0_CAD_EXIT_MODE_STBY_RC;
}

uint32_t timeout_raw = (float)timeout / 30.52f;

// set CAD parameters
// TODO add configurable exit mode and timeout
state = setCadParams(num, peak, min, RADIOLIB_LR11X0_CAD_EXIT_MODE_STBY_RC, 0);
state = setCadParams(num, peak, min, mode, timeout_raw);
RADIOLIB_ASSERT(state);

// start CAD
Expand Down
36 changes: 19 additions & 17 deletions src/modules/LR11x0/LR11x0.h
Original file line number Diff line number Diff line change
Expand Up @@ -844,12 +844,10 @@ class LR11x0: public PhysicalLayer {

/*!
\brief Performs scan for LoRa transmission in the current channel. Detects both preamble and payload.
\param symbolNum Number of symbols for CAD detection.
\param detPeak Peak value for CAD detection.
\param detMin Minimum value for CAD detection.
\param config CAD configuration structure.
\returns \ref status_codes
*/
int16_t scanChannel(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin);
int16_t scanChannel(ChannelScanConfig_t config) override;

/*!
\brief Sets the module to standby mode (overload for PhysicalLayer compatibility, uses 13 MHz RC oscillator).
Expand Down Expand Up @@ -979,14 +977,12 @@ class LR11x0: public PhysicalLayer {
int16_t startChannelScan() override;

/*!
\brief Interrupt-driven channel activity detection method. IRQ1 will be activated
\brief Interrupt-driven channel activity detection method. DIO1 will be activated
when LoRa preamble is detected, or upon timeout.
\param symbolNum Number of symbols for CAD detection.
\param detPeak Peak value for CAD detection.
\param detMin Minimum value for CAD detection.
\param config CAD configuration structure.
\returns \ref status_codes
*/
int16_t startChannelScan(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin);
int16_t startChannelScan(const ChannelScanConfig_t &config) override;

/*!
\brief Read the channel scan result
Expand Down Expand Up @@ -1221,18 +1217,24 @@ class LR11x0: public PhysicalLayer {
RadioLibTime_t calculateRxTimeout(RadioLibTime_t timeoutUs) override;

/*!
\brief Create the flags that make up RxDone and RxTimeout used for receiving downlinks
\param irqFlags The flags for which IRQs must be triggered
\param irqMask Mask indicating which IRQ triggers a DIO
\brief Read currently active IRQ flags.
\returns IRQ flags.
*/
uint32_t getIrqFlags() override;

/*!
\brief Set interrupt on DIO1 to be sent on a specific IRQ bit (e.g. RxTimeout, CadDone).
\param irq Module-specific IRQ flags.
\returns \ref status_codes
*/
int16_t irqRxDoneRxTimeout(uint32_t &irqFlags, uint32_t &irqMask) override;
int16_t setIrqFlags(uint32_t irq) override;

/*!
\brief Check whether a specific IRQ bit is set (e.g. RxTimeout, CadDone).
\returns Whether requested IRQ is set.
\brief Clear interrupt on a specific IRQ bit (e.g. RxTimeout, CadDone).
\param irq Module-specific IRQ flags.
\returns \ref status_codes
*/
int16_t checkIrq(uint8_t irq) override;
int16_t clearIrqFlags(uint32_t irq) override;

/*!
\brief Get one truly random byte from RSSI noise.
Expand Down Expand Up @@ -1618,7 +1620,7 @@ class LR11x0: public PhysicalLayer {
bool findChip(uint8_t ver);
int16_t config(uint8_t modem);
int16_t setPacketMode(uint8_t mode, uint8_t len);
int16_t startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin);
int16_t startCad(uint8_t symbolNum, uint8_t detPeak, uint8_t detMin, uint8_t exitMode, RadioLibTime_t timeout);
int16_t setHeaderType(uint8_t hdrType, size_t len = 0xFF);

// common methods to avoid some copy-paste
Expand Down
Loading
Loading