[SX128x] Added interface for interrupt-driven CAD (#1085)

pull/1089/head
jgromes 2024-05-05 12:42:03 +01:00
rodzic 86cdefe8a2
commit bcd8a05cd4
3 zmienionych plików z 169 dodań i 33 usunięć

Wyświetl plik

@ -0,0 +1,108 @@
/*
RadioLib SX128x Channel Activity Detection Example
This example uses SX1280 to scan the current LoRa
channel and detect ongoing LoRa transmissions.
Other modules from SX128x family can also be used.
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/
*/
// include the library
#include <RadioLib.h>
// SX1280 has the following connections:
// NSS pin: 10
// DIO1 pin: 2
// NRST pin: 3
// BUSY pin: 9
SX1280 radio = new Module(10, 2, 3, 9);
// or using RadioShield
// https://github.com/jgromes/RadioShield
//SX1280 radio = RadioShield.ModuleA;
void setup() {
Serial.begin(9600);
// initialize SX1280 with default settings
Serial.print(F("[SX1280] 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);
}
// set the function that will be called
// when LoRa packet or timeout is detected
radio.setDio1Action(setFlag);
// start scanning the channel
Serial.print(F("[SX1280] Starting scan for LoRa preamble ... "));
state = radio.startChannelScan();
if (state == RADIOLIB_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;
// 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!
#if defined(ESP8266) || defined(ESP32)
ICACHE_RAM_ATTR
#endif
void setFlag(void) {
// something happened, set the flag
scanFlag = true;
}
void loop() {
// check if the flag is set
if(scanFlag) {
// reset flag
scanFlag = false;
// check CAD result
int state = radio.getChannelScanResult();
if (state == RADIOLIB_LORA_DETECTED) {
// LoRa packet was detected
Serial.println(F("[SX1280] Packet detected!"));
} else if (state == RADIOLIB_CHANNEL_FREE) {
// channel is free
Serial.println(F("[SX1280] Channel is free!"));
} else {
// some other error occurred
Serial.print(F("[SX1280] Failed, code "));
Serial.println(state);
}
// start scanning the channel again
Serial.print(F("[SX1280] Starting scan for LoRa preamble ... "));
state = radio.startChannelScan();
if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
}
}

Wyświetl plik

@ -411,28 +411,8 @@ int16_t SX128x::receiveDirect() {
}
int16_t SX128x::scanChannel() {
// check active modem
if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_LORA) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
// set DIO pin mapping
state = setDioIrqParams(RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE, RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE);
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
// set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_RX);
// set mode to CAD
state = setCad();
int16_t state = startChannelScan();
RADIOLIB_ASSERT(state);
// wait for channel activity detected or timeout
@ -441,18 +421,7 @@ int16_t SX128x::scanChannel() {
}
// check CAD result
uint16_t cadResult = getIrqStatus();
if(cadResult & RADIOLIB_SX128X_IRQ_CAD_DETECTED) {
// detected some LoRa activity
clearIrqStatus();
return(RADIOLIB_LORA_DETECTED);
} else if(cadResult & RADIOLIB_SX128X_IRQ_CAD_DONE) {
// channel is free
clearIrqStatus();
return(RADIOLIB_CHANNEL_FREE);
}
return(RADIOLIB_ERR_UNKNOWN);
return(getChannelScanResult());
}
int16_t SX128x::sleep(bool retainConfig) {
@ -664,6 +633,52 @@ int16_t SX128x::readData(uint8_t* data, size_t len) {
return(state);
}
int16_t SX128x::startChannelScan() {
// check active modem
if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_LORA) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
// set mode to standby
int16_t state = standby();
RADIOLIB_ASSERT(state);
// set DIO pin mapping
state = setDioIrqParams(RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE, RADIOLIB_SX128X_IRQ_CAD_DETECTED | RADIOLIB_SX128X_IRQ_CAD_DONE);
RADIOLIB_ASSERT(state);
// clear interrupt flags
state = clearIrqStatus();
RADIOLIB_ASSERT(state);
// set RF switch (if present)
this->mod->setRfSwitchState(Module::MODE_RX);
// set mode to CAD
return(setCad());
}
int16_t SX128x::getChannelScanResult() {
// check active modem
if(getPacketType() != RADIOLIB_SX128X_PACKET_TYPE_LORA) {
return(RADIOLIB_ERR_WRONG_MODEM);
}
// check CAD result
uint16_t cadResult = getIrqStatus();
int16_t state = RADIOLIB_ERR_UNKNOWN;
if(cadResult & RADIOLIB_SX128X_IRQ_CAD_DETECTED) {
// detected some LoRa activity
state = RADIOLIB_LORA_DETECTED;
} else if(cadResult & RADIOLIB_SX128X_IRQ_CAD_DONE) {
// channel is free
state = RADIOLIB_CHANNEL_FREE;
}
clearIrqStatus();
return(state);
}
int16_t SX128x::setFrequency(float freq) {
RADIOLIB_CHECK_RANGE(freq, 2400.0, 2500.0, RADIOLIB_ERR_INVALID_FREQUENCY);

Wyświetl plik

@ -568,6 +568,19 @@ class SX128x: public PhysicalLayer {
\returns \ref status_codes
*/
int16_t readData(uint8_t* data, size_t len) override;
/*!
\brief Interrupt-driven channel activity detection method. DIO1 will be activated
when LoRa preamble is detected, or upon timeout. Defaults to CAD parameter values recommended by AN1200.48.
\returns \ref status_codes
*/
int16_t startChannelScan() override;
/*!
\brief Read the channel scan result
\returns \ref status_codes
*/
int16_t getChannelScanResult() override;
// configuration methods