[SX126x] Added FSK rx/tx, interrupt methods and CAD
This commit is contained in:
parent
b222883518
commit
f0b9841cf6
14 changed files with 924 additions and 97 deletions
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
RadioLib SX126x Channel Activity Detection Example
|
||||
|
||||
This example scans the current LoRa channel and detects
|
||||
valid LoRa preambles. Preamble is the first part of
|
||||
LoRa transmission, so this can be used to check
|
||||
if the LoRa channel is free, or if you should start
|
||||
receiving a message.
|
||||
|
||||
Other modules from SX126x family can also be used.
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1262 module is in slot A on the shield
|
||||
SX1262 lora = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1262 with default settings
|
||||
Serial.print(F("[SX1262] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x1424 (private network)
|
||||
// output power: 14 dBm
|
||||
// current limit: 60 mA
|
||||
// preamble length: 8 symbols
|
||||
// CRC: enabled
|
||||
int state = lora.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[SX1262] Scanning channel for LoRa transmission ... "));
|
||||
|
||||
// start scanning current channel
|
||||
int state = lora.scanChannel();
|
||||
|
||||
if (state == LORA_DETECTED) {
|
||||
// LoRa preamble was detected
|
||||
Serial.println(F(" detected!"));
|
||||
|
||||
} else if (state == CHANNEL_FREE) {
|
||||
// no preamble was detected, channel is free
|
||||
Serial.println(F(" channel is free!"));
|
||||
|
||||
}
|
||||
|
||||
// wait 100 ms before new scan
|
||||
delay(100);
|
||||
}
|
143
examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino
Normal file
143
examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino
Normal file
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
RadioLib SX126x FSK Modem Example
|
||||
|
||||
This example shows how to use FSK modem in SX126x chips.
|
||||
|
||||
NOTE: The sketch below is just a guide on how to use
|
||||
FSK modem, so this code should not be run directly!
|
||||
Instead, modify the other examples to use FSK
|
||||
modem and use the appropriate configuration
|
||||
methods.
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1262 module is in slot A on the shield
|
||||
SX1262 fsk = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1262 FSK modem with default settings
|
||||
Serial.print(F("[SX1262] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bit rate: 48.0 kbps
|
||||
// frequency deviation: 50.0 kHz
|
||||
// Rx bandwidth: 117.3 kHz
|
||||
// output power: 14 dBm
|
||||
// current limit: 60.0 mA
|
||||
// preamble length: 16 bits
|
||||
// data shaping: Gaussian, BT = 0.5
|
||||
// sync word: 0x2D 0x01
|
||||
// CRC: enabled, CRC16 (CCIT)
|
||||
int state = fsk.beginFSK();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// if needed, you can switch between LoRa and FSK modes
|
||||
//
|
||||
// lora.begin() start LoRa mode (and disable FSK)
|
||||
// lora.beginFSK() start FSK mode (and disable LoRa)
|
||||
|
||||
// the following settings can also
|
||||
// be modified at run-time
|
||||
state = fsk.setFrequency(433.5);
|
||||
state = fsk.setBitRate(100.0);
|
||||
state = fsk.setFrequencyDeviation(10.0);
|
||||
state = fsk.setRxBandwidth(250.0);
|
||||
state = fsk.setOutputPower(10.0);
|
||||
state = fsk.setCurrentLimit(100.0);
|
||||
state = fsk.setDataShaping(1.0);
|
||||
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
state = fsk.setSyncWord(syncWord, 8);
|
||||
if (state != ERR_NONE) {
|
||||
Serial.print(F("Unable to set configuration, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// FSK modem allows advanced CRC configuration
|
||||
// Default is CCIT CRC16 (2 bytes, initial 0x1D0F, polynomial 0x1021, inverted)
|
||||
// Set CRC to IBM CRC (2 bytes, initial 0xFFFF, polynomial 0x8005, non-inverted)
|
||||
state = fsk.setCRC(2, 0xFFFF, 0x8005, false);
|
||||
// set CRC length to 0 to disable CRC
|
||||
|
||||
#warning "This sketch is just an API guide! Read the note at line 6."
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// FSK modem can use the same transmit/receive methods
|
||||
// as the LoRa modem, even their interrupt-driven versions
|
||||
|
||||
// transmit FSK packet
|
||||
int state = fsk.transmit("Hello World!");
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
|
||||
0x78, 0xAB, 0xCD, 0xEF};
|
||||
int state = lora.transmit(byteArr, 8);
|
||||
*/
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("[SX1262] Packet transmitted successfully!"));
|
||||
} else if (state == ERR_PACKET_TOO_LONG) {
|
||||
Serial.println(F("[SX1262] Packet too long!"));
|
||||
} else if (state == ERR_TX_TIMEOUT) {
|
||||
Serial.println(F("[SX1262] Timed out while transmitting!"));
|
||||
} else {
|
||||
Serial.println(F("[SX1262] Failed to transmit packet, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// receive FSK packet
|
||||
String str;
|
||||
state = fsk.receive(str);
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = lora.receive(byteArr, 8);
|
||||
*/
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("[SX1262] Received packet!"));
|
||||
Serial.print(F("[SX1262] Data:\t"));
|
||||
Serial.println(str);
|
||||
} else if (state == ERR_RX_TIMEOUT) {
|
||||
Serial.println(F("[SX1262] Timed out while waiting for packet!"));
|
||||
} else {
|
||||
Serial.println(F("[SX1262] Failed to receive packet, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// FSK modem has built-in address filtering system
|
||||
// it can be enabled by setting node address, broadcast
|
||||
// address, or both
|
||||
//
|
||||
// to transmit packet to a particular address,
|
||||
// use the following methods:
|
||||
//
|
||||
// fsk.transmit("Hello World!", address);
|
||||
// fsk.startTransmit("Hello World!", address);
|
||||
|
||||
// set node address to 0x02
|
||||
state = fsk.setNodeAddress(0x02);
|
||||
// set broadcast address to 0xFF
|
||||
state = fsk.setBroadcastAddress(0xFF);
|
||||
if (state != ERR_NONE) {
|
||||
Serial.println(F("[SX1262] Unable to set address filter, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// address filtering can also be disabled
|
||||
// NOTE: calling this method will also erase previously set
|
||||
// node and broadcast address
|
||||
/*
|
||||
state = fsk.disableAddressFiltering();
|
||||
if (state != ERR_NONE) {
|
||||
Serial.println(F("Unable to remove address filter, code "));
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -33,6 +33,7 @@ void setup() {
|
|||
// output power: 14 dBm
|
||||
// current limit: 60 mA
|
||||
// preamble length: 8 symbols
|
||||
// CRC: enabled
|
||||
int state = lora.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
RadioLib SX126x Receive with Inerrupts Example
|
||||
|
||||
This example listens for LoRa transmissions and tries to
|
||||
receive them. Once a packet is received, an interrupt is
|
||||
triggered. To successfully receive data, the following
|
||||
settings have to be the same on both transmitter
|
||||
and receiver:
|
||||
- carrier frequency
|
||||
- bandwidth
|
||||
- spreading factor
|
||||
- coding rate
|
||||
- sync word
|
||||
|
||||
Other modules from SX126x/RFM9x family can also be used.
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1262 module is in slot A on the shield
|
||||
SX1262 lora = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1262 with default settings
|
||||
Serial.print(F("[SX1262] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x1424 (private network)
|
||||
// output power: 14 dBm
|
||||
// current limit: 60 mA
|
||||
// preamble length: 8 symbols
|
||||
// CRC: enabled
|
||||
int state = lora.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 new packet is received
|
||||
lora.setDio1Action(setFlag);
|
||||
|
||||
// start listening for LoRa packets
|
||||
Serial.print(F("[SX1262] Starting to listen ... "));
|
||||
state = lora.startReceive();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// if needed, 'listen' mode can be disabled by calling
|
||||
// any of the following methods:
|
||||
//
|
||||
// lora.standby()
|
||||
// lora.sleep()
|
||||
// lora.transmit();
|
||||
// lora.receive();
|
||||
// lora.scanChannel();
|
||||
}
|
||||
|
||||
// flag to indicate that a packet was received
|
||||
volatile bool receivedFlag = 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;
|
||||
}
|
||||
|
||||
// we got a packet, set the flag
|
||||
receivedFlag = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(receivedFlag) {
|
||||
// disable the interrupt service routine while
|
||||
// processing the data
|
||||
enableInterrupt = false;
|
||||
|
||||
// reset flag
|
||||
receivedFlag = false;
|
||||
|
||||
// you can read received data as an Arduino String
|
||||
String str;
|
||||
int state = lora.readData(str);
|
||||
|
||||
// you can also read received data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = lora.receive(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("[SX1262] Received packet!"));
|
||||
|
||||
// print data of the packet
|
||||
Serial.print(F("[SX1262] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
Serial.print(F("[SX1262] RSSI:\t\t"));
|
||||
Serial.print(lora.getRSSI());
|
||||
Serial.println(" dBm");
|
||||
|
||||
// print SNR (Signal-to-Noise Ratio)
|
||||
Serial.print(F("[SX1262] SNR:\t\t"));
|
||||
Serial.print(lora.getSNR());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
} else if (state == ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
}
|
||||
|
||||
// we're ready to receive more packets,
|
||||
// enable interrupt service routine
|
||||
enableInterrupt = true;
|
||||
}
|
||||
|
||||
}
|
137
examples/SX126x/SX126x_Settings/SX126x_Settings.ino
Normal file
137
examples/SX126x/SX126x_Settings/SX126x_Settings.ino
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
RadioLib SX126x Settings Example
|
||||
|
||||
This example shows how to change all the properties of LoRa transmission.
|
||||
RadioLib currently supports the following settings:
|
||||
- pins (SPI slave select, digital IO 0, digital IO 1)
|
||||
- carrier frequency
|
||||
- bandwidth
|
||||
- spreading factor
|
||||
- coding rate
|
||||
- sync word
|
||||
- output power during transmission
|
||||
- CRC
|
||||
- preamble length
|
||||
|
||||
Other modules from SX126x family can also be used.
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1268 module is in slot A on the shield
|
||||
SX1268 loraSX1268 = RadioShield.ModuleA;
|
||||
|
||||
// SX1262 module is in slot B on the shield
|
||||
SX1262 loraSX1262 = RadioShield.ModuleB;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1268 with default settings
|
||||
Serial.print(F("[SX1268] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x1424 (private network)
|
||||
// output power: 14 dBm
|
||||
// current limit: 60 mA
|
||||
// preamble length: 8 symbols
|
||||
// CRC: enabled
|
||||
int state = loraSX1268.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// initialize the second LoRa instance with
|
||||
// non-default settings
|
||||
// this LoRa link will have high data rate,
|
||||
// but lower range
|
||||
Serial.print(F("[SX1262] Initializing ... "));
|
||||
// carrier frequency: 915.0 MHz
|
||||
// bandwidth: 500.0 kHz
|
||||
// spreading factor: 6
|
||||
// coding rate: 5
|
||||
// sync word: 0x3444 (public network)
|
||||
// output power: 2 dBm
|
||||
// current limit: 50 mA
|
||||
// preamble length: 20 symbols
|
||||
// CRC: enabled
|
||||
state = loraSX1262.begin(915.0, 500.0, 6, 5, 0x3444, 50, 20);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true);
|
||||
}
|
||||
|
||||
// you can also change the settings at runtime
|
||||
// and check if the configuration was changed successfully
|
||||
|
||||
// set carrier frequency to 433.5 MHz
|
||||
if (loraSX1268.setFrequency(433.5) == ERR_INVALID_FREQUENCY) {
|
||||
Serial.println(F("Selected frequency is invalid for this module!"));
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set bandwidth to 250 kHz
|
||||
if (loraSX1268.setBandwidth(250.0) == ERR_INVALID_BANDWIDTH) {
|
||||
Serial.println(F("Selected bandwidth is invalid for this module!"));
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set spreading factor to 10
|
||||
if (loraSX1268.setSpreadingFactor(10) == ERR_INVALID_SPREADING_FACTOR) {
|
||||
Serial.println(F("Selected spreading factor is invalid for this module!"));
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set coding rate to 6
|
||||
if (loraSX1268.setCodingRate(6) == ERR_INVALID_CODING_RATE) {
|
||||
Serial.println(F("Selected coding rate is invalid for this module!"));
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set LoRa sync word to 0x1234
|
||||
if (loraSX1268.setSyncWord(0x1234) != ERR_NONE) {
|
||||
Serial.println(F("Unable to set sync word!"));
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set output power to 10 dBm (accepted range is -17 - 22 dBm)
|
||||
if (loraSX1268.setOutputPower(10) == ERR_INVALID_OUTPUT_POWER) {
|
||||
Serial.println(F("Selected output power is invalid for this module!"));
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set over current protection limit to 80 mA (accepted range is 45 - 240 mA)
|
||||
// NOTE: set value to 0 to disable overcurrent protection
|
||||
if (loraSX1268.setCurrentLimit(80) == ERR_INVALID_CURRENT_LIMIT) {
|
||||
Serial.println(F("Selected current limit is invalid for this module!"));
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set LoRa preamble length to 15 symbols (accepted range is 0 - 65535)
|
||||
if (loraSX1268.setPreambleLength(15) == ERR_INVALID_PREAMBLE_LENGTH) {
|
||||
Serial.println(F("Selected preamble length is invalid for this module!"));
|
||||
while (true);
|
||||
}
|
||||
|
||||
// disable CRC
|
||||
if (loraSX1268.setCRC(false) == ERR_INVALID_CRC) {
|
||||
Serial.println(F("Selected CRC is invalid for this module!"));
|
||||
while (true);
|
||||
}
|
||||
|
||||
Serial.println(F("All settings succesfully changed!"));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// nothing here
|
||||
}
|
|
@ -29,6 +29,7 @@ void setup() {
|
|||
// output power: 14 dBm
|
||||
// current limit: 60 mA
|
||||
// preamble length: 8 symbols
|
||||
// CRC: enabled
|
||||
int state = lora.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
RadioLib SX126x Transmit with Inerrupts Example
|
||||
|
||||
This example transmits LoRa packets with one second delays
|
||||
between them. Each packet contains up to 256 bytes
|
||||
of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
Other modules from SX126x family can also be used.
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1262 module is in slot A on the shield
|
||||
SX1262 lora = RadioShield.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1262 with default settings
|
||||
Serial.print(F("[SX1262] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x1424 (private network)
|
||||
// output power: 14 dBm
|
||||
// current limit: 60 mA
|
||||
// preamble length: 8 symbols
|
||||
// CRC: enabled
|
||||
int state = lora.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 packet transmission is finished
|
||||
lora.setDio1Action(setFlag);
|
||||
|
||||
// start transmitting the first packet
|
||||
Serial.print(F("[SX1262] Sending first packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
state = lora.startTransmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
|
||||
0x78, 0xAB, 0xCD, 0xEF};
|
||||
state = lora.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state != ERR_NONE) {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
// flag to indicate that a packet was received
|
||||
volatile bool transmittedFlag = false;
|
||||
|
||||
void setFlag(void) {
|
||||
// packet transmission is finished, set the flag
|
||||
transmittedFlag = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the previous transmission finished
|
||||
if(transmittedFlag) {
|
||||
Serial.println(F("packet transmission finished!"));
|
||||
|
||||
// wait one second before next transmission
|
||||
delay(1000);
|
||||
|
||||
// send another packet
|
||||
Serial.print(F("[SX1262] Sending another packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
int state = lora.startTransmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
|
||||
0x78, 0xAB, 0xCD, 0xEF};
|
||||
int state = lora.startTransmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
// NOTE: when using interrupt-driven transmit method,
|
||||
// it is not possible to automatically measure
|
||||
// transmission data rate using getDataRate()
|
||||
|
||||
if (state != ERR_NONE) {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -197,3 +197,6 @@ ERR_INVALID_RTTY_SHIFT LITERAL1
|
|||
ERR_UNSUPPORTED_ENCODING LITERAL1
|
||||
|
||||
ERR_INVALID_NUM_BROAD_ADDRS LITERAL1
|
||||
|
||||
ERR_INVALID_CRC LITERAL1
|
||||
LORA_DETECTED LITERAL1
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
#include "modules/RFM96.h"
|
||||
#include "modules/RFM97.h"
|
||||
#include "modules/SX1231.h"
|
||||
#include "modules/SX1261.h"
|
||||
#include "modules/SX1262.h"
|
||||
#include "modules/SX1268.h"
|
||||
#include "modules/SX1272.h"
|
||||
#include "modules/SX1273.h"
|
||||
#include "modules/SX1276.h"
|
||||
|
|
|
@ -108,4 +108,8 @@
|
|||
// CC1101-specific status codes
|
||||
#define ERR_INVALID_NUM_BROAD_ADDRS -601
|
||||
|
||||
// SX126x-specific status codes
|
||||
#define ERR_INVALID_CRC -701
|
||||
#define LORA_DETECTED -702
|
||||
|
||||
#endif
|
||||
|
|
16
src/modules/SX1261.h
Normal file
16
src/modules/SX1261.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _RADIOLIB_SX1261_H
|
||||
#define _RADIOLIB_SX1261_H
|
||||
|
||||
#include "TypeDef.h"
|
||||
#include "Module.h"
|
||||
#include "SX126x.h"
|
||||
#include "SX1262.h"
|
||||
|
||||
//SX126X_CMD_SET_PA_CONFIG
|
||||
#define SX126X_PA_CONFIG_SX1261 0x01
|
||||
#define SX126X_PA_CONFIG_SX1262 0x00
|
||||
|
||||
// TODO: implement SX1261 class
|
||||
using SX1261 = SX1262;
|
||||
|
||||
#endif
|
16
src/modules/SX1268.h
Normal file
16
src/modules/SX1268.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _RADIOLIB_SX1268_H
|
||||
#define _RADIOLIB_SX1268_H
|
||||
|
||||
#include "TypeDef.h"
|
||||
#include "Module.h"
|
||||
#include "SX126x.h"
|
||||
#include "SX1262.h"
|
||||
|
||||
//SX126X_CMD_SET_PA_CONFIG
|
||||
#define SX126X_PA_CONFIG_SX1261 0x01
|
||||
#define SX126X_PA_CONFIG_SX1262 0x00
|
||||
|
||||
// TODO: implement SX1268 class
|
||||
using SX1268 = SX1262;
|
||||
|
||||
#endif
|
|
@ -65,12 +65,13 @@ int16_t SX126x::beginFSK(float br, float freqDev, float rxBw, uint16_t preambleL
|
|||
pinMode(_mod->getRx(), INPUT);
|
||||
|
||||
// initialize configuration variables (will be overwritten during public settings configuration)
|
||||
_br = 21333;
|
||||
_freqDev = 52429;
|
||||
_br = 21333; // 48.0 kbps
|
||||
_freqDev = 52428; // 50.0 kHz
|
||||
_rxBw = SX126X_GFSK_RX_BW_117_3;
|
||||
_pulseShape = SX126X_GFSK_FILTER_GAUSS_0_5;
|
||||
_crcTypeFSK = SX126X_GFSK_CRC_1_BYTE;
|
||||
_crcTypeFSK = SX126X_GFSK_CRC_2_BYTE_INV; // CCIT CRC configuration
|
||||
_preambleLengthFSK = preambleLength;
|
||||
_addrComp = SX126X_GFSK_ADDRESS_FILT_OFF;
|
||||
|
||||
// get status and errors
|
||||
getStatus();
|
||||
|
@ -110,8 +111,7 @@ int16_t SX126x::beginFSK(float br, float freqDev, float rxBw, uint16_t preambleL
|
|||
|
||||
// set default sync word 0x2D01 - not a beginFSK attribute
|
||||
uint8_t sync[] = {0x2D, 0x01};
|
||||
_syncWordLength = 2;
|
||||
state = setSyncWord(sync, _syncWordLength);
|
||||
state = setSyncWord(sync, 2);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
@ -148,37 +148,22 @@ int16_t SX126x::transmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
float nSymbol = _preambleLength + sfCoeff1 + 8 + ceil(max(8.0 * len + (_crcType * 16.0) - 4.0 * _sf + sfCoeff2 + 20.0, 0.0) / sfDivisor) * (_cr + 4);
|
||||
timeout = (uint32_t)(symbolLength * nSymbol * 1500.0);
|
||||
|
||||
// set packet length
|
||||
setPacketParams(_preambleLength, _crcType, len);
|
||||
|
||||
} else if(modem == SX126X_PACKET_TYPE_GFSK) {
|
||||
|
||||
// calculate timeout (500% of expected time-on-air)
|
||||
float brBps = ((float)(SX126X_CRYSTAL_FREQ) * 1000000.0 * 32.0) / (float)_br;
|
||||
timeout = (uint32_t)(((len * 8.0) / brBps) * 1000000.0 * 5.0);
|
||||
|
||||
} else {
|
||||
return(ERR_UNKNOWN);
|
||||
}
|
||||
|
||||
DEBUG_PRINT(F("Timeout in "))
|
||||
DEBUG_PRINT(F("Timeout in "));
|
||||
DEBUG_PRINT(timeout);
|
||||
DEBUG_PRINTLN(F(" us"))
|
||||
|
||||
// set DIO mapping
|
||||
setDioIrqParams(SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT, SX126X_IRQ_TX_DONE);
|
||||
|
||||
// set buffer pointers
|
||||
setBufferBaseAddress();
|
||||
|
||||
// write packet to buffer
|
||||
writeBuffer(data, len);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIrqStatus();
|
||||
DEBUG_PRINTLN(F(" us"));
|
||||
|
||||
// start transmission
|
||||
uint32_t timeoutValue = (uint32_t)((float)timeout / 15.625);
|
||||
setTx(timeoutValue);
|
||||
|
||||
// wait for BUSY to go low (= PA ramp up done)
|
||||
while(digitalRead(_mod->getRx()));
|
||||
startTransmit(data, len, addr);
|
||||
|
||||
// wait for packet transmission or timeout
|
||||
uint32_t start = micros();
|
||||
|
@ -196,6 +181,9 @@ int16_t SX126x::transmit(uint8_t* data, size_t len, uint8_t addr) {
|
|||
// clear interrupt flags
|
||||
clearIrqStatus();
|
||||
|
||||
// set mode to standby to disable transmitter
|
||||
standby();
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
|
@ -213,27 +201,25 @@ int16_t SX126x::receive(uint8_t* data, size_t len) {
|
|||
timeout = (uint32_t)(symbolLength * 100.0 * 1000.0);
|
||||
|
||||
} else if(modem == SX126X_PACKET_TYPE_GFSK) {
|
||||
// calculate timeout (500 % of expected time-one-air)
|
||||
size_t maxLen = len;
|
||||
if(len == 0) {
|
||||
maxLen = 0xFF;
|
||||
}
|
||||
float brBps = ((float)(SX126X_CRYSTAL_FREQ) * 1000000.0 * 32.0) / (float)_br;
|
||||
timeout = (uint32_t)(((maxLen * 8.0) / brBps) * 1000000.0 * 5.0);
|
||||
|
||||
} else {
|
||||
return(ERR_UNKNOWN);
|
||||
}
|
||||
|
||||
DEBUG_PRINT(F("Timeout in "))
|
||||
DEBUG_PRINT(F("Timeout in "));
|
||||
DEBUG_PRINT(timeout);
|
||||
DEBUG_PRINTLN(F(" us"))
|
||||
|
||||
// set DIO mapping
|
||||
setDioIrqParams(SX126X_IRQ_RX_DONE | SX126X_IRQ_TIMEOUT, SX126X_IRQ_RX_DONE);
|
||||
|
||||
// set buffer pointers
|
||||
setBufferBaseAddress();
|
||||
|
||||
// clear interrupt flags
|
||||
clearIrqStatus();
|
||||
DEBUG_PRINTLN(F(" us"));
|
||||
|
||||
// start reception
|
||||
uint32_t timeoutValue = (uint32_t)((float)timeout / 15.625);
|
||||
setRx(timeoutValue);
|
||||
startReceive(timeoutValue);
|
||||
|
||||
// wait for packet reception or timeout
|
||||
uint32_t start = micros();
|
||||
|
@ -244,6 +230,132 @@ int16_t SX126x::receive(uint8_t* data, size_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
// read the received data
|
||||
return(readData(data, len));
|
||||
}
|
||||
|
||||
int16_t SX126x::transmitDirect(uint32_t frf) {
|
||||
// user requested to start transmitting immediately (required for RTTY)
|
||||
if(frf != 0) {
|
||||
setRfFrequency(frf);
|
||||
}
|
||||
|
||||
// start transmitting
|
||||
uint8_t data[] = {SX126X_CMD_NOP};
|
||||
SPIwriteCommand(SX126X_CMD_SET_TX_CONTINUOUS_WAVE, data, 1);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::receiveDirect() {
|
||||
// SX126x is unable to ouput received data directly
|
||||
return(ERR_UNKNOWN);
|
||||
}
|
||||
|
||||
int16_t SX126x::scanChannel() {
|
||||
// check active modem
|
||||
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
standby();
|
||||
|
||||
// set DIO pin mapping
|
||||
setDioIrqParams(SX126X_IRQ_CAD_DETECTED | SX126X_IRQ_CAD_DONE, SX126X_IRQ_CAD_DONE, SX126X_IRQ_CAD_DETECTED);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIrqStatus();
|
||||
|
||||
// set mode to CAD
|
||||
setCad();
|
||||
|
||||
// wait for channel activity detected or timeout
|
||||
while(!digitalRead(_mod->getInt0())) {
|
||||
if(digitalRead(_mod->getInt1())) {
|
||||
clearIrqStatus();
|
||||
return(LORA_DETECTED);
|
||||
}
|
||||
}
|
||||
|
||||
// clear interrupt flags
|
||||
clearIrqStatus();
|
||||
|
||||
return(CHANNEL_FREE);
|
||||
}
|
||||
|
||||
int16_t SX126x::sleep() {
|
||||
uint8_t data[] = {SX126X_SLEEP_START_COLD | SX126X_SLEEP_RTC_OFF};
|
||||
SPIwriteCommand(SX126X_CMD_SET_SLEEP, data, 1);
|
||||
|
||||
// wait for SX126x to safely enter sleep mode
|
||||
delayMicroseconds(500);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::standby(uint8_t mode) {
|
||||
uint8_t data[] = {mode};
|
||||
SPIwriteCommand(SX126X_CMD_SET_STANDBY, data, 1);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
void SX126x::setDio1Action(void (*func)(void)) {
|
||||
attachInterrupt(digitalPinToInterrupt(_mod->getInt0()), func, RISING);
|
||||
}
|
||||
|
||||
void SX126x::setDio2Action(void (*func)(void)) {
|
||||
attachInterrupt(digitalPinToInterrupt(_mod->getInt1()), func, RISING);
|
||||
}
|
||||
|
||||
int16_t SX126x::startTransmit(uint8_t* data, size_t len, uint8_t addr) {
|
||||
// set packet Length
|
||||
uint8_t modem = getPacketType();
|
||||
if(modem == SX126X_PACKET_TYPE_LORA) {
|
||||
setPacketParams(_preambleLength, _crcType, len);
|
||||
} else if(modem == SX126X_PACKET_TYPE_LORA) {
|
||||
setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp, len);
|
||||
} else {
|
||||
return(ERR_UNKNOWN);
|
||||
}
|
||||
|
||||
// set DIO mapping
|
||||
setDioIrqParams(SX126X_IRQ_TX_DONE | SX126X_IRQ_TIMEOUT, SX126X_IRQ_TX_DONE);
|
||||
|
||||
// set buffer pointers
|
||||
setBufferBaseAddress();
|
||||
|
||||
// write packet to buffer
|
||||
writeBuffer(data, len);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIrqStatus();
|
||||
|
||||
// start transmission
|
||||
setTx(0x000000);
|
||||
|
||||
// wait for BUSY to go low (= PA ramp up done)
|
||||
while(digitalRead(_mod->getRx()));
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::startReceive(uint32_t timeout) {
|
||||
// set DIO mapping
|
||||
setDioIrqParams(SX126X_IRQ_RX_DONE | SX126X_IRQ_TIMEOUT, SX126X_IRQ_RX_DONE);
|
||||
|
||||
// set buffer pointers
|
||||
setBufferBaseAddress();
|
||||
|
||||
// clear interrupt flags
|
||||
clearIrqStatus();
|
||||
|
||||
// set mode to receive
|
||||
setRx(timeout);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::readData(uint8_t* data, size_t len) {
|
||||
// check integrity CRC
|
||||
uint16_t irq = getIrqStatus();
|
||||
if((irq & SX126X_IRQ_CRC_ERR) || (irq & SX126X_IRQ_HEADER_ERR)) {
|
||||
|
@ -274,39 +386,6 @@ int16_t SX126x::receive(uint8_t* data, size_t len) {
|
|||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::transmitDirect(uint32_t frf) {
|
||||
// user requested to start transmitting immediately (required for RTTY)
|
||||
if(frf != 0) {
|
||||
setRfFrequency(frf);
|
||||
}
|
||||
|
||||
// start transmitting
|
||||
uint8_t data[] = {SX126X_CMD_NOP};
|
||||
SPIwriteCommand(SX126X_CMD_SET_TX_CONTINUOUS_WAVE, data, 1);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::receiveDirect() {
|
||||
// SX126x is unable to ouput received data directly
|
||||
return(ERR_UNKNOWN);
|
||||
}
|
||||
|
||||
int16_t SX126x::sleep() {
|
||||
uint8_t data[] = {SX126X_SLEEP_START_COLD | SX126X_SLEEP_RTC_OFF};
|
||||
SPIwriteCommand(SX126X_CMD_SET_SLEEP, data, 1);
|
||||
|
||||
// wait for SX126x to safely enter sleep mode
|
||||
delayMicroseconds(500);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::standby(uint8_t mode) {
|
||||
uint8_t data[] = {mode};
|
||||
SPIwriteCommand(SX126X_CMD_SET_STANDBY, data, 1);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::setBandwidth(float bw) {
|
||||
// check active modem
|
||||
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
|
||||
|
@ -407,7 +486,7 @@ int16_t SX126x::setPreambleLength(uint16_t preambleLength) {
|
|||
return(ERR_NONE);
|
||||
} else if(modem == SX126X_PACKET_TYPE_GFSK) {
|
||||
_preambleLengthFSK = preambleLength;
|
||||
setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength);
|
||||
setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp);
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
|
@ -426,7 +505,8 @@ int16_t SX126x::setFrequencyDeviation(float freqDev) {
|
|||
}
|
||||
|
||||
// calculate raw frequency deviation value
|
||||
_freqDev = (uint32_t)((freqDev * 1000.0) / ((SX126X_CRYSTAL_FREQ * 1000000.0) / (float)((uint32_t)(1) << 25)));
|
||||
//_freqDev = (uint32_t)((freqDev * 1000.0) / ((SX126X_CRYSTAL_FREQ * 1000000.0) / (float)((uint32_t)(1) << 25)));
|
||||
_freqDev = (uint32_t)(((freqDev * 1000.0) * (float)((uint32_t)(1) << 25)) / (SX126X_CRYSTAL_FREQ * 1000000.0));
|
||||
|
||||
// update modulation parameters
|
||||
setModulationParamsFSK(_br, _pulseShape, _rxBw, _freqDev);
|
||||
|
@ -520,15 +600,16 @@ int16_t SX126x::setDataShaping(float sh) {
|
|||
}
|
||||
|
||||
// check allowed values
|
||||
sh *= 10.0;
|
||||
if(abs(sh - 0.0) <= 0.001) {
|
||||
_pulseShape = SX126X_GFSK_FILTER_NONE;
|
||||
} else if(abs(sh - 0.3) <= 0.001) {
|
||||
} else if(abs(sh - 3.0) <= 0.001) {
|
||||
_pulseShape = SX126X_GFSK_FILTER_GAUSS_0_3;
|
||||
} else if(abs(sh - 0.5) <= 0.001) {
|
||||
} else if(abs(sh - 5.0) <= 0.001) {
|
||||
_pulseShape = SX126X_GFSK_FILTER_GAUSS_0_5;
|
||||
} else if(abs(sh - 0.7) <= 0.001) {
|
||||
} else if(abs(sh - 7.0) <= 0.001) {
|
||||
_pulseShape = SX126X_GFSK_FILTER_GAUSS_0_7;
|
||||
} else if(abs(sh - 1.0) <= 0.001) {
|
||||
} else if(abs(sh - 10.0) <= 0.001) {
|
||||
_pulseShape = SX126X_GFSK_FILTER_GAUSS_1;
|
||||
} else {
|
||||
return(ERR_INVALID_DATA_SHAPING);
|
||||
|
@ -555,8 +636,112 @@ int16_t SX126x::setSyncWord(uint8_t* syncWord, uint8_t len) {
|
|||
writeRegister(SX126X_REG_SYNC_WORD_0, syncWord, len);
|
||||
|
||||
// update packet parameters
|
||||
_syncWordLength = len;
|
||||
setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength);
|
||||
_syncWordLength = len * 8;
|
||||
setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::setNodeAddress(uint8_t nodeAddr) {
|
||||
// check active modem
|
||||
if(getPacketType() != SX126X_PACKET_TYPE_GFSK) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// enable address filtering (node only)
|
||||
_addrComp = SX126X_GFSK_ADDRESS_FILT_NODE;
|
||||
setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp);
|
||||
|
||||
// set node address
|
||||
writeRegister(SX126X_REG_NODE_ADDRESS, &nodeAddr, 1);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::setBroadcastAddress(uint8_t broadAddr) {
|
||||
// check active modem
|
||||
if(getPacketType() != SX126X_PACKET_TYPE_GFSK) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// enable address filtering (node and broadcast)
|
||||
_addrComp = SX126X_GFSK_ADDRESS_FILT_NODE_BROADCAST;
|
||||
setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp);
|
||||
|
||||
// set broadcast address
|
||||
writeRegister(SX126X_REG_BROADCAST_ADDRESS, &broadAddr, 1);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::disableAddressFiltering() {
|
||||
// check active modem
|
||||
if(getPacketType() != SX126X_PACKET_TYPE_GFSK) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// disable address filtering
|
||||
_addrComp = SX126X_GFSK_ADDRESS_FILT_OFF;
|
||||
setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::setCRC(bool enableCRC) {
|
||||
// check active modem
|
||||
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// update packet parameters
|
||||
if(enableCRC) {
|
||||
_crcType = SX126X_LORA_CRC_ON;
|
||||
} else {
|
||||
_crcType = SX126X_LORA_CRC_OFF;
|
||||
}
|
||||
setPacketParams(_preambleLength, _crcType);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX126x::setCRC(uint8_t len, uint16_t initial, uint16_t polynomial, bool inverted) {
|
||||
// check active modem
|
||||
if(getPacketType() != SX126X_PACKET_TYPE_GFSK) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// update packet parameters
|
||||
switch(len) {
|
||||
case 0:
|
||||
_crcTypeFSK = SX126X_GFSK_CRC_OFF;
|
||||
break;
|
||||
case 1:
|
||||
if(inverted) {
|
||||
_crcTypeFSK = SX126X_GFSK_CRC_1_BYTE_INV;
|
||||
} else {
|
||||
_crcTypeFSK = SX126X_GFSK_CRC_1_BYTE;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if(inverted) {
|
||||
_crcTypeFSK = SX126X_GFSK_CRC_2_BYTE_INV;
|
||||
} else {
|
||||
_crcTypeFSK = SX126X_GFSK_CRC_2_BYTE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return(ERR_INVALID_CRC);
|
||||
}
|
||||
setPacketParamsFSK(_preambleLengthFSK, _crcTypeFSK, _syncWordLength, _addrComp);
|
||||
|
||||
// write initial CRC value
|
||||
uint8_t data[2] = {(uint8_t)((initial >> 8) & 0xFF), (uint8_t)(initial & 0xFF)};
|
||||
writeRegister(SX126X_REG_CRC_INITIAL_MSB, data, 2);
|
||||
|
||||
// write CRC polynomial value
|
||||
data[0] = (uint8_t)((polynomial >> 8) & 0xFF);
|
||||
data[1] = (uint8_t)(polynomial & 0xFF);
|
||||
writeRegister(SX126X_REG_CRC_POLYNOMIAL_MSB, data, 2);
|
||||
|
||||
return(ERR_NONE);
|
||||
}
|
||||
|
@ -566,11 +751,6 @@ float SX126x::getDataRate() {
|
|||
}
|
||||
|
||||
float SX126x::getRSSI() {
|
||||
// check active modem
|
||||
if(getPacketType() != SX126X_PACKET_TYPE_LORA) {
|
||||
return(ERR_WRONG_MODEM);
|
||||
}
|
||||
|
||||
// get last packet RSSI from packet status
|
||||
uint32_t packetStatus = getPacketStatus();
|
||||
uint8_t rssiPkt = packetStatus & 0xFF;
|
||||
|
@ -630,7 +810,7 @@ void SX126x::readBuffer(uint8_t* data, uint8_t numBytes) {
|
|||
uint8_t* dat = new uint8_t[1 + numBytes];
|
||||
dat[0] = SX126X_CMD_NOP;
|
||||
memcpy(dat + 1, data, numBytes);
|
||||
SPIreadCommand(SX126X_CMD_READ_BUFFER, dat, numBytes);
|
||||
SPIreadCommand(SX126X_CMD_READ_BUFFER, dat, 1 + numBytes);
|
||||
memcpy(data, dat + 1, numBytes);
|
||||
delete[] dat;
|
||||
}
|
||||
|
@ -699,11 +879,11 @@ void SX126x::setPacketParams(uint16_t preambleLength, uint8_t crcType, uint8_t p
|
|||
SPIwriteCommand(SX126X_CMD_SET_PACKET_PARAMS, data, 6);
|
||||
}
|
||||
|
||||
void SX126x::setPacketParamsFSK(uint16_t preambleLength, uint8_t crcType, uint8_t syncWordLength, uint8_t payloadLength, uint8_t packetType, uint8_t addrComp, uint8_t preambleDetectorLength, uint8_t whitening) {
|
||||
void SX126x::setPacketParamsFSK(uint16_t preambleLength, uint8_t crcType, uint8_t syncWordLength, uint8_t addrComp, uint8_t payloadLength, uint8_t packetType, uint8_t preambleDetectorLength, uint8_t whitening) {
|
||||
uint8_t data[9] = {(uint8_t)((preambleLength >> 8) & 0xFF), (uint8_t)(preambleLength & 0xFF),
|
||||
preambleDetectorLength, syncWordLength, addrComp,
|
||||
packetType, payloadLength, crcType, whitening};
|
||||
SPIwriteCommand(SX126X_CMD_SET_MODULATION_PARAMS, data, 9);
|
||||
SPIwriteCommand(SX126X_CMD_SET_PACKET_PARAMS, data, 9);
|
||||
}
|
||||
|
||||
void SX126x::setBufferBaseAddress(uint8_t txBaseAddress, uint8_t rxBaseAddress) {
|
||||
|
@ -768,7 +948,7 @@ int16_t SX126x::config() {
|
|||
// set DIO2 as IRQ
|
||||
uint8_t* data = new uint8_t[1];
|
||||
data[0] = SX126X_DIO2_AS_IRQ;
|
||||
SPIwriteCommand(SX126X_DIO2_AS_RF_SWITCH, data, 1);
|
||||
SPIwriteCommand(SX126X_CMD_SET_DIO2_AS_RF_SWITCH_CTRL, data, 1);
|
||||
|
||||
// set regulator mode
|
||||
data[0] = SX126X_REGULATOR_DC_DC;
|
||||
|
@ -810,7 +990,7 @@ int16_t SX126x::configFSK() {
|
|||
// set DIO2 as IRQ
|
||||
uint8_t* data = new uint8_t[1];
|
||||
data[0] = SX126X_DIO2_AS_IRQ;
|
||||
SPIwriteCommand(SX126X_DIO2_AS_RF_SWITCH, data, 1);
|
||||
SPIwriteCommand(SX126X_CMD_SET_DIO2_AS_RF_SWITCH_CTRL, data, 1);
|
||||
|
||||
// set regulator mode
|
||||
data[0] = SX126X_REGULATOR_DC_DC;
|
||||
|
|
|
@ -318,6 +318,8 @@ class SX126x: public PhysicalLayer {
|
|||
// introduce PhysicalLayer overloads
|
||||
using PhysicalLayer::transmit;
|
||||
using PhysicalLayer::receive;
|
||||
using PhysicalLayer::startTransmit;
|
||||
using PhysicalLayer::readData;
|
||||
|
||||
// constructor
|
||||
SX126x(Module* mod);
|
||||
|
@ -329,9 +331,17 @@ class SX126x: public PhysicalLayer {
|
|||
int16_t receive(uint8_t* data, size_t len);
|
||||
int16_t transmitDirect(uint32_t frf = 0);
|
||||
int16_t receiveDirect();
|
||||
int16_t scanChannel();
|
||||
int16_t sleep();
|
||||
int16_t standby(uint8_t mode = SX126X_STANDBY_RC);
|
||||
|
||||
// interrupt methods
|
||||
void setDio1Action(void (*func)(void));
|
||||
void setDio2Action(void (*func)(void));
|
||||
int16_t startTransmit(uint8_t* data, size_t len, uint8_t addr = 0);
|
||||
int16_t startReceive(uint32_t timeout = 0xFFFFFF);
|
||||
int16_t readData(uint8_t* data, size_t len);
|
||||
|
||||
// configuration methods
|
||||
int16_t setBandwidth(float bw);
|
||||
int16_t setSpreadingFactor(uint8_t sf);
|
||||
|
@ -344,6 +354,11 @@ class SX126x: public PhysicalLayer {
|
|||
int16_t setRxBandwidth(float rxBw);
|
||||
int16_t setDataShaping(float sh);
|
||||
int16_t setSyncWord(uint8_t* syncWord, uint8_t len);
|
||||
int16_t setNodeAddress(uint8_t nodeAddr);
|
||||
int16_t setBroadcastAddress(uint8_t broadAddr);
|
||||
int16_t disableAddressFiltering();
|
||||
int16_t setCRC(bool enableCRC);
|
||||
int16_t setCRC(uint8_t len, uint16_t initial = 0x1D0F, uint16_t polynomial = 0x1021, bool inverted = true);
|
||||
float getDataRate();
|
||||
float getRSSI();
|
||||
float getSNR();
|
||||
|
@ -359,14 +374,14 @@ class SX126x: public PhysicalLayer {
|
|||
void readBuffer(uint8_t* data, uint8_t numBytes);
|
||||
void setDioIrqParams(uint16_t irqMask, uint16_t dio1Mask, uint16_t dio2Mask = SX126X_IRQ_NONE, uint16_t dio3Mask = SX126X_IRQ_NONE);
|
||||
uint16_t getIrqStatus();
|
||||
void clearIrqStatus(uint16_t clearIrqParams = 0xFFFF);
|
||||
void clearIrqStatus(uint16_t clearIrqParams = SX126X_IRQ_ALL);
|
||||
void setRfFrequency(uint32_t frf);
|
||||
uint8_t getPacketType();
|
||||
void setTxParams(uint8_t power, uint8_t rampTime = SX126X_PA_RAMP_200U);
|
||||
void setModulationParams(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro = 0xFF);
|
||||
void setModulationParamsFSK(uint32_t br, uint8_t pulseShape, uint8_t rxBw, uint32_t freqDev);
|
||||
void setPacketParams(uint16_t preambleLength, uint8_t crcType, uint8_t payloadLength = 0xFF, uint8_t headerType = SX126X_LORA_HEADER_EXPLICIT, uint8_t invertIQ = SX126X_LORA_IQ_STANDARD);
|
||||
void setPacketParamsFSK(uint16_t preambleLength, uint8_t crcType, uint8_t syncWordLength, uint8_t payloadLength = 0xFF, uint8_t packetType = SX126X_GFSK_PACKET_VARIABLE, uint8_t addrComp = SX126X_GFSK_ADDRESS_FILT_OFF, uint8_t preambleDetectorLength = SX126X_GFSK_PREAMBLE_DETECT_8, uint8_t whitening = SX126X_GFSK_WHITENING_ON);
|
||||
void setPacketParamsFSK(uint16_t preambleLength, uint8_t crcType, uint8_t syncWordLength, uint8_t addrComp, uint8_t payloadLength = 0xFF, uint8_t packetType = SX126X_GFSK_PACKET_VARIABLE, uint8_t preambleDetectorLength = SX126X_GFSK_PREAMBLE_DETECT_16, uint8_t whitening = SX126X_GFSK_WHITENING_ON);
|
||||
void setBufferBaseAddress(uint8_t txBaseAddress = 0x00, uint8_t rxBaseAddress = 0x00);
|
||||
uint8_t getStatus();
|
||||
uint32_t getPacketStatus();
|
||||
|
@ -383,7 +398,7 @@ class SX126x: public PhysicalLayer {
|
|||
float _bwKhz;
|
||||
|
||||
uint32_t _br, _freqDev;
|
||||
uint8_t _rxBw, _pulseShape, _crcTypeFSK, _syncWordLength;
|
||||
uint8_t _rxBw, _pulseShape, _crcTypeFSK, _syncWordLength, _addrComp;
|
||||
uint16_t _preambleLengthFSK;
|
||||
|
||||
float _dataRate;
|
||||
|
|
Loading…
Add table
Reference in a new issue