[SX126x] Added interrupt-driven CAD

pull/401/head
jgromes 2021-10-28 15:44:44 +02:00
rodzic ebc4852fc2
commit 3a8360c361
3 zmienionych plików z 186 dodań i 33 usunięć

Wyświetl plik

@ -0,0 +1,123 @@
/*
RadioLib SX126x Channel Activity Detection Example
This example uses SX1262 to scan the current LoRa
channel and detect ongoing LoRa transmissions.
Unlike SX127x CAD, SX126x can detect any part
of LoRa transmission, not just the preamble.
Other modules from SX126x family can also be used.
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/
*/
// include the library
#include <RadioLib.h>
// SX1262 has the following connections:
// NSS pin: 10
// DIO1 pin: 2
// NRST pin: 3
// BUSY pin: 9
SX1262 radio = new Module(10, 2, 3, 9);
// or using RadioShield
// https://github.com/jgromes/RadioShield
//SX1262 radio = RadioShield.ModuleA;
void setup() {
Serial.begin(9600);
// initialize SX1262 with default settings
Serial.print(F("[SX1262] Initializing ... "));
int state = radio.begin();
if (state == ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while (true);
}
// set the function that will be called
// when LoRa packet or timeout is detected
radio.setDio1Action(setFlag);
// start scanning the channel
Serial.print(F("[SX1262] Starting scan for LoRa preamble ... "));
state = radio.startChannelScan();
if (state == ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
}
// flag to indicate that a packet was detected or CAD timed out
volatile bool scanFlag = false;
// disable interrupt when it's not needed
volatile bool enableInterrupt = true;
// this function is called when a complete packet
// is received by the module
// IMPORTANT: this function MUST be 'void' type
// and MUST NOT have any arguments!
void setFlag(void) {
// check if the interrupt is enabled
if(!enableInterrupt) {
return;
}
// something happened, set the flag
scanFlag = true;
}
void loop() {
// check if the flag is set
if(scanFlag) {
// disable the interrupt service routine while
// processing the data
enableInterrupt = false;
// reset flag
scanFlag = false;
// check CAD result
int state = radio.getChannelScanResult();
if (state == LORA_DETECTED) {
// LoRa packet was detected
Serial.println(F("[SX1262] Packet detected!"));
} else if (state == CHANNEL_FREE) {
// channel is free
Serial.println(F("[SX1262] Channel is free!"));
} else {
// some other error occurred
Serial.print(F("[SX1262] Failed, code "));
Serial.println(state);
}
// start scanning the channel again
Serial.print(F("[SX1262] Starting scan for LoRa preamble ... "));
state = radio.startChannelScan();
if (state == ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
// enable interrupt service routine
enableInterrupt = true;
}
}

Wyświetl plik

@ -331,28 +331,8 @@ int16_t SX126x::receiveDirect() {
}
int16_t SX126x::scanChannel() {
// check active modem
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
return(ERR_WRONG_MODEM);
}
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
// set RF switch (if present)
_mod->setRfSwitchState(HIGH, LOW);
// set DIO pin mapping
state = setDioIrqParams(SX126X_IRQ_CAD_DETECTED | SX126X_IRQ_CAD_DONE, SX126X_IRQ_CAD_DETECTED | SX126X_IRQ_CAD_DONE);
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
// set mode to CAD
state = setCad();
int state = startChannelScan();
RADIOLIB_ASSERT(state);
// wait for channel activity detected or timeout
@ -361,18 +341,7 @@ int16_t SX126x::scanChannel() {
}
// check CAD result
uint16_t cadResult = getIrqStatus();
if(cadResult & SX126X_IRQ_CAD_DETECTED) {
// detected some LoRa activity
clearIrqStatus();
return(LORA_DETECTED);
} else if(cadResult & SX126X_IRQ_CAD_DONE) {
// channel is free
clearIrqStatus();
return(CHANNEL_FREE);
}
return(ERR_UNKNOWN);
return(getChannelScanResult());
}
int16_t SX126x::sleep(bool retainConfig) {
@ -608,6 +577,53 @@ int16_t SX126x::readData(uint8_t* data, size_t len) {
return(state);
}
int16_t SX126x::startChannelScan() {
// check active modem
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
return(ERR_WRONG_MODEM);
}
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
// set RF switch (if present)
_mod->setRfSwitchState(HIGH, LOW);
// set DIO pin mapping
state = setDioIrqParams(SX126X_IRQ_CAD_DETECTED | SX126X_IRQ_CAD_DONE, SX126X_IRQ_CAD_DETECTED | SX126X_IRQ_CAD_DONE);
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
// set mode to CAD
state = setCad();
return(state);
}
int16_t SX126x::getChannelScanResult() {
// check active modem
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
return(ERR_WRONG_MODEM);
}
// check CAD result
uint16_t cadResult = getIrqStatus();
if(cadResult & SX126X_IRQ_CAD_DETECTED) {
// detected some LoRa activity
clearIrqStatus();
return(LORA_DETECTED);
} else if(cadResult & SX126X_IRQ_CAD_DONE) {
// channel is free
clearIrqStatus();
return(CHANNEL_FREE);
}
return(ERR_UNKNOWN);
}
int16_t SX126x::setBandwidth(float bw) {
// check active modem
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {

Wyświetl plik

@ -554,6 +554,20 @@ class SX126x: public PhysicalLayer {
*/
int16_t readData(uint8_t* data, size_t len) override;
/*!
\brief Interrupt-driven channel activity detection method. DIO0 will be activated when LoRa preamble is detected, or upon timeout.
\returns \ref status_codes
*/
int16_t startChannelScan();
/*!
\brief Read the channel scan result
\returns \ref status_codes
*/
int16_t getChannelScanResult();
// configuration methods
/*!