[SX127x] Sync with LoRaLib v7.0.0

This commit is contained in:
jgromes 2018-10-31 17:44:47 +01:00
parent ac2193ad72
commit 6cd42ca3e1
23 changed files with 416 additions and 140 deletions

View file

@ -7,12 +7,7 @@
if the LoRa channel is free, or if you should start
receiving a message.
Other modules from SX127x family can also be used.
SX1272 lora = Kite.ModuleA;
SX1273 lora = Kite.ModuleA;
SX1276 lora = Kite.ModuleA;
SX1277 lora = Kite.ModuleA;
SX1279 lora = Kite.ModuleA;
Other modules from SX127x/RFM9x family can also be used.
*/
// include the library

View file

@ -11,12 +11,7 @@
- sync word
- preamble length
Other modules from SX127x family can also be used.
SX1272 lora = Kite.ModuleA;
SX1273 lora = Kite.ModuleA;
SX1276 lora = Kite.ModuleA;
SX1277 lora = Kite.ModuleA;
SX1279 lora = Kite.ModuleA;
Other modules from SX127x/RFM9x family can also be used.
*/
// include the library
@ -73,13 +68,13 @@ void loop() {
// print the RSSI (Received Signal Strength Indicator)
// of the last received packet
Serial.print("[SX1278] RSSI:\t\t");
Serial.print(lora.lastPacketRSSI);
Serial.print(lora.getRSSI());
Serial.println(" dBm");
// print the SNR (Signal-to-Noise Ratio)
// of the last received packet
Serial.print("[SX1278] SNR:\t\t");
Serial.print(lora.lastPacketSNR);
Serial.print(lora.getSNR());
Serial.println(" dBm");
// print frequency error

View file

@ -12,12 +12,7 @@
- coding rate
- sync word
Other modules from SX127x family can also be used.
SX1272 lora = Kite.ModuleA;
SX1273 lora = Kite.ModuleA;
SX1276 lora = Kite.ModuleA;
SX1277 lora = Kite.ModuleA;
SX1279 lora = Kite.ModuleA;
Other modules from SX127x/RFM9x family can also be used.
*/
// include the library
@ -124,12 +119,12 @@ void loop() {
// print RSSI (Received Signal Strength Indicator)
Serial.print("RSSI:\t\t");
Serial.print(lora.lastPacketRSSI);
Serial.print(lora.getRSSI());
Serial.println(" dBm");
// print SNR (Signal-to-Noise Ratio)
Serial.print("SNR:\t\t");
Serial.print(lora.lastPacketSNR);
Serial.print(lora.getSNR());
Serial.println(" dBm");
// print frequency error

View file

@ -10,6 +10,8 @@
- coding rate
- sync word
- output power during transmission
Other modules from SX127x/RFM9x family can also be used.
*/
// include the library
@ -18,18 +20,8 @@
// SX1278 module is in slot A on the shield
SX1278 loraSX1278 = Kite.ModuleA;
// create another instance of LoRa class using SX1272 module and user-specified pinout
// NSS pin: 6
// DIO0 pin: 4
// DIO1 pin: 5
SX1272 loraSX1272 = new Module(6, 4, 5);
// create third instance of LoRa class using SX1276 module and user-specified pinout
// we ran out of Uno digital pins, so here we use analog ones
// NSS pin: A0
// DIO0 pin: A1
// DIO1 pin: A2
SX1276 loraSX1276 = new Module(A0, A1, A2);
// SX1272 module is in slot B on the shield
SX1272 loraSX1272 = Kite.ModuleB;
void setup() {
Serial.begin(9600);
@ -54,28 +46,7 @@ void setup() {
while (true);
}
// initialize the second LoRa instance with non-default settings
// this LoRa link will have maximum range, but very low data rate
Serial.print(F("[SX1276] Initializing ... "));
// carrier frequency: 434.0 MHz
// bandwidth: 7.8 kHz
// spreading factor: 12
// coding rate: 8
// sync word: 0x13
// output power: 17 dBm
// current limit: 100 mA
// preamble length: 8 symbols
// amplifier gain: 0 (automatic gain control)
state = loraSX1276.begin(434.0, 7.8, 12, 8, 0x13);
if (state == ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while (true);
}
// initialize the third LoRa instance with
// initialize the second LoRa instance with
// non-default settings
// this LoRa link will have high data rate,
// but lower range

View file

@ -7,12 +7,7 @@
- null-terminated char array (C-string)
- arbitrary binary data (byte array)
Other modules from SX127x family can also be used.
SX1272 lora = Kite.ModuleA;
SX1273 lora = Kite.ModuleA;
SX1276 lora = Kite.ModuleA;
SX1277 lora = Kite.ModuleA;
SX1279 lora = Kite.ModuleA;
Other modules from SX127x/RFM9x family can also be used.
*/
// include the library
@ -64,7 +59,7 @@ void loop() {
// print measured data rate
Serial.print("Datarate:\t");
Serial.print(lora.dataRate);
Serial.print(lora.getDataRate());
Serial.println(" bps");
} else if (state == ERR_PACKET_TOO_LONG) {

View file

@ -8,12 +8,7 @@
- null-terminated char array (C-string)
- arbitrary binary data (byte array)
Other modules from SX127x family can also be used.
SX1272 lora = Kite.ModuleA;
SX1273 lora = Kite.ModuleA;
SX1276 lora = Kite.ModuleA;
SX1277 lora = Kite.ModuleA;
SX1279 lora = Kite.ModuleA;
Other modules from SX127x/RFM9x family can also be used.
*/
// include the library
@ -98,6 +93,10 @@ void loop() {
0x78, 0xAB, 0xCD, 0xEF};
int state = lora.transmit(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 "));

View file

@ -14,6 +14,10 @@ ESP8266 KEYWORD1
HC05 KEYWORD1
JDY08 KEYWORD1
RF69 KEYWORD1
RFM95 KEYWORD1
RFM96 KEYWORD1
RFM97 KEYWORD1
RFM98 KEYWORD1
SX1231 KEYWORD1
SX1272 KEYWORD1
SX1273 KEYWORD1
@ -37,34 +41,43 @@ ModuleA KEYWORD2
ModuleB KEYWORD2
Module KEYWORD2
# SX1272/73/76/77/78/79 + RF69
dataRate KEYWORD2
lastPacketRSSI KEYWORD2
# SX127x/RFM9x + RF69
begin KEYWORD2
beginFSK KEYWORD2
transmit KEYWORD2
receive KEYWORD2
scanChannel KEYWORD2
sleep KEYWORD2
standby KEYWORD2
transmitDirect KEYWORD2
receiveDirect KEYWORD2
packetMode KEYWORD2
setDio0Action KEYWORD2
setDio1Action KEYWORD2
startTransmit KEYWORD2
startReceive KEYWORD2
readData KEYWORD2
setBandwidth KEYWORD2
setSpreadingFactor KEYWORD2
setCodingRate KEYWORD2
setFrequency KEYWORD2
setSyncWord KEYWORD2
setOutputPower KEYWORD2
listen KEYWORD2
onReceive KEYWORD2
readData KEYWORD2
transmitDirect KEYWORD2
receiveDirect KEYWORD2
packetMode KEYWORD2
# RF69-specific
setCurrentLimit KEYWORD2
setPreambleLength KEYWORD2
setGain KEYWORD2
getFrequencyError KEYWORD2
getRSSI KEYWORD2
getSNR KEYWORD2
getDataRate KEYWORD2
setBitRate KEYWORD2
setRxBandwidth KEYWORD2
setFrequencyDeviation KEYWORD2
setNodeAddress KEYWORD2
setBroadcastAddress KEYWORD2
disableAddressFiltering KEYWORD2
# RF69-specific
setAESKey KEYWORD2
enableAES KEYWORD2
disableAES KEYWORD2

View file

@ -8,6 +8,10 @@
#include "modules/HC05.h"
#include "modules/JDY08.h"
#include "modules/RF69.h"
#include "modules/RFM95.h"
#include "modules/RFM96.h"
#include "modules/RFM97.h"
#include "modules/RFM98.h"
#include "modules/SX1231.h"
#include "modules/SX1272.h"
#include "modules/SX1273.h"

View file

@ -107,7 +107,7 @@ int16_t Module::SPIgetRegValue(uint8_t reg, uint8_t msb, uint8_t lsb) {
return(maskedValue);
}
int16_t Module::SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb) {
int16_t Module::SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval) {
if((msb > 7) || (lsb > 7) || (lsb > msb)) {
return(ERR_INVALID_BIT_RANGE);
}
@ -117,36 +117,39 @@ int16_t Module::SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb, uint8_t
uint8_t newValue = (currentValue & ~mask) | (value & mask);
SPIwriteRegister(reg, newValue);
// some registers need a bit of time to process the change
// e.g. SX127X_REG_OP_MODE
delay(20);
// check if the write was successful
uint8_t readValue = SPIreadRegister(reg);
if(readValue != newValue) {
DEBUG_PRINTLN();
DEBUG_PRINT_STR("address:\t0x");
DEBUG_PRINTLN_HEX(reg);
DEBUG_PRINT_STR("bits:\t\t");
DEBUG_PRINT(msb);
DEBUG_PRINT(' ');
DEBUG_PRINTLN(lsb);
DEBUG_PRINT_STR("value:\t\t0b");
DEBUG_PRINTLN_BIN(value);
DEBUG_PRINT_STR("current:\t0b");
DEBUG_PRINTLN_BIN(currentValue);
DEBUG_PRINT_STR("mask:\t\t0b");
DEBUG_PRINTLN_BIN(mask);
DEBUG_PRINT_STR("new:\t\t0b");
DEBUG_PRINTLN_BIN(newValue);
DEBUG_PRINT_STR("read:\t\t0b");
DEBUG_PRINTLN_BIN(readValue);
DEBUG_PRINTLN();
return(ERR_SPI_WRITE_FAILED);
// check register value each millisecond until check interval is reached
// some registers need a bit of time to process the change (e.g. SX127X_REG_OP_MODE)
uint32_t start = micros();
uint8_t readValue = 0;
while(micros() - start < (checkInterval * 1000)) {
readValue = SPIreadRegister(reg);
if(readValue == newValue) {
// check passed, we can stop the loop
return(ERR_NONE);
}
}
return(ERR_NONE);
// check failed, print debug info
DEBUG_PRINTLN();
DEBUG_PRINT_STR("address:\t0x");
DEBUG_PRINTLN_HEX(reg);
DEBUG_PRINT_STR("bits:\t\t");
DEBUG_PRINT(msb);
DEBUG_PRINT(' ');
DEBUG_PRINTLN(lsb);
DEBUG_PRINT_STR("value:\t\t0b");
DEBUG_PRINTLN_BIN(value);
DEBUG_PRINT_STR("current:\t0b");
DEBUG_PRINTLN_BIN(currentValue);
DEBUG_PRINT_STR("mask:\t\t0b");
DEBUG_PRINTLN_BIN(mask);
DEBUG_PRINT_STR("new:\t\t0b");
DEBUG_PRINTLN_BIN(newValue);
DEBUG_PRINT_STR("read:\t\t0b");
DEBUG_PRINTLN_BIN(readValue);
DEBUG_PRINTLN();
return(ERR_SPI_WRITE_FAILED);
}
void Module::SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes) {

View file

@ -28,7 +28,7 @@ class Module {
bool ATsendData(uint8_t* data, uint32_t len);
int16_t SPIgetRegValue(uint8_t reg, uint8_t msb = 7, uint8_t lsb = 0);
int16_t SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb = 7, uint8_t lsb = 0);
int16_t SPIsetRegValue(uint8_t reg, uint8_t value, uint8_t msb = 7, uint8_t lsb = 0, uint8_t checkInterval = 2);
void SPIreadRegisterBurst(uint8_t reg, uint8_t numBytes, uint8_t* inBytes);
uint8_t SPIreadRegister(uint8_t reg);

View file

@ -60,7 +60,7 @@
#define ERR_NONE 0
#define ERR_UNKNOWN -1
// SX1278/SX1272/RF69 status codes
// SX127x/RFM9x/RF69 status codes
#define ERR_CHIP_NOT_FOUND -2
#define ERR_EEPROM_NOT_INITIALIZED -3
#define ERR_PACKET_TOO_LONG -4

62
src/modules/RFM95.cpp Normal file
View file

@ -0,0 +1,62 @@
#include "RFM95.h"
RFM95::RFM95(Module* mod) : SX1278(mod) {
}
int16_t RFM95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint8_t currentLimit, uint16_t preambleLength, uint8_t gain) {
// execute common part
int16_t state = SX127x::begin(RFM95_CHIP_VERSION, syncWord, currentLimit, preambleLength);
if(state != ERR_NONE) {
return(state);
}
// configure settings not accessible by API
state = config();
if(state != ERR_NONE) {
return(state);
}
// configure publicly accessible settings
state = setFrequency(freq);
if(state != ERR_NONE) {
return(state);
}
state = setBandwidth(bw);
if(state != ERR_NONE) {
return(state);
}
state = setSpreadingFactor(sf);
if(state != ERR_NONE) {
return(state);
}
state = setCodingRate(cr);
if(state != ERR_NONE) {
return(state);
}
state = setOutputPower(power);
if(state != ERR_NONE) {
return(state);
}
state = setGain(gain);
if(state != ERR_NONE) {
return(state);
}
return(state);
}
int16_t RFM95::setFrequency(float freq) {
// check frequency range
if((freq < 868.0) || (freq > 915.0)) {
return(ERR_INVALID_FREQUENCY);
}
// set frequency
return(SX127x::setFrequencyRaw(freq));
}

27
src/modules/RFM95.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef _KITELIB_RFM95_H
#define _KITELIB_RFM95_H
#include "TypeDef.h"
#include "Module.h"
#include "SX127x.h"
#include "SX1278.h"
// SX127X_REG_VERSION
#define RFM95_CHIP_VERSION 0x11
class RFM95: public SX1278 {
public:
// constructor
RFM95(Module* mod);
// basic methods
int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = SX127X_SYNC_WORD, int8_t power = 17, uint8_t currentLimit = 100, uint16_t preambleLength = 8, uint8_t gain = 0);
// configuration methods
int16_t setFrequency(float freq);
private:
};
#endif

62
src/modules/RFM96.cpp Normal file
View file

@ -0,0 +1,62 @@
#include "RFM96.h"
RFM96::RFM96(Module* mod) : SX1278(mod) {
}
int16_t RFM96::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint8_t currentLimit, uint16_t preambleLength, uint8_t gain) {
// execute common part
int16_t state = SX127x::begin(RFM9X_CHIP_VERSION, syncWord, currentLimit, preambleLength);
if(state != ERR_NONE) {
return(state);
}
// configure settings not accessible by API
state = config();
if(state != ERR_NONE) {
return(state);
}
// configure publicly accessible settings
state = setFrequency(freq);
if(state != ERR_NONE) {
return(state);
}
state = setBandwidth(bw);
if(state != ERR_NONE) {
return(state);
}
state = setSpreadingFactor(sf);
if(state != ERR_NONE) {
return(state);
}
state = setCodingRate(cr);
if(state != ERR_NONE) {
return(state);
}
state = setOutputPower(power);
if(state != ERR_NONE) {
return(state);
}
state = setGain(gain);
if(state != ERR_NONE) {
return(state);
}
return(state);
}
int16_t RFM96::setFrequency(float freq) {
// check frequency range
if((freq < 433.0) || (freq > 470.0)) {
return(ERR_INVALID_FREQUENCY);
}
// set frequency
return(SX127x::setFrequencyRaw(freq));
}

29
src/modules/RFM96.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef _KITELIB_RFM96_H
#define _KITELIB_RFM96_H
#include "TypeDef.h"
#include "Module.h"
#include "SX127x.h"
#include "SX1278.h"
// SX127X_REG_VERSION
#define RFM9X_CHIP_VERSION 0x12 // according to datasheet, this should be 0x11, but all modules seem to have 0x12
class RFM96: public SX1278 {
public:
// constructor
RFM96(Module* mod);
// basic methods
int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = SX127X_SYNC_WORD, int8_t power = 17, uint8_t currentLimit = 100, uint16_t preambleLength = 8, uint8_t gain = 0);
// configuration methods
int16_t setFrequency(float freq);
private:
};
using RFM98 = RFM96;
#endif

39
src/modules/RFM97.cpp Normal file
View file

@ -0,0 +1,39 @@
#include "RFM97.h"
RFM97::RFM97(Module* mod) : RFM95(mod) {
};
int16_t RFM97::setSpreadingFactor(uint8_t sf) {
// check active modem
if(getActiveModem() != SX127X_LORA) {
return(ERR_WRONG_MODEM);
}
uint8_t newSpreadingFactor;
// check allowed spreading factor values
switch(sf) {
case 6:
newSpreadingFactor = SX127X_SF_6;
break;
case 7:
newSpreadingFactor = SX127X_SF_7;
break;
case 8:
newSpreadingFactor = SX127X_SF_8;
break;
case 9:
newSpreadingFactor = SX127X_SF_9;
break;
default:
return(ERR_INVALID_SPREADING_FACTOR);
}
// set spreading factor and if successful, save the new setting
int16_t state = SX1278::setSpreadingFactorRaw(newSpreadingFactor);
if(state == ERR_NONE) {
SX127x::_sf = sf;
}
return(state);
}

21
src/modules/RFM97.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef _KITELIB_RFM97_H
#define _KITELIB_RFM97_H
#include "TypeDef.h"
#include "Module.h"
#include "SX127x.h"
#include "SX1278.h"
#include "RFM95.h"
class RFM97: public RFM95 {
public:
// contructor
RFM97(Module* mod);
// configuration methods
int16_t setSpreadingFactor(uint8_t sf);
private:
};
#endif

View file

@ -91,8 +91,12 @@ int16_t SX1272::setFrequency(float freq) {
return(ERR_INVALID_FREQUENCY);
}
// set frequency
return(SX127x::setFrequencyRaw(freq));
// set frequency and if successful, save the new setting
int16_t state = SX127x::setFrequencyRaw(freq);
if(state == ERR_NONE) {
SX127x::_freq = freq;
}
return(state);
}
int16_t SX1272::setBandwidth(float bw) {
@ -253,6 +257,24 @@ int16_t SX1272::setGain(uint8_t gain) {
return(state);
}
int8_t SX1272::getRSSI() {
// check active modem
if(getActiveModem() != SX127X_LORA) {
return(0);
}
int8_t lastPacketRSSI = -139 + _mod->SPIgetRegValue(SX127X_REG_PKT_RSSI_VALUE);
// spread-spectrum modulation signal can be received below noise floor
// check last packet SNR and if it's less than 0, add it to reported RSSI to get the correct value
float lastPacketSNR = SX127x::getSNR();
if(lastPacketSNR < 0.0) {
lastPacketRSSI += lastPacketSNR;
}
return(lastPacketRSSI);
}
int16_t SX1272::setBandwidthRaw(uint8_t newBandwidth) {
// set mode to standby
int16_t state = SX127x::standby();
@ -300,7 +322,7 @@ int16_t SX1272::config() {
// calculate symbol length and set low datarate optimization, if needed
uint16_t base = 1;
float symbolLength = (float)(base << _sf) / (float)_bw;
if(symbolLength >= 0.016) {
if(symbolLength >= 16.0) {
state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_ON, 0, 0);
} else {
state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0);

View file

@ -99,6 +99,7 @@ class SX1272: public SX127x {
int16_t setCodingRate(uint8_t cr);
int16_t setOutputPower(int8_t power);
int16_t setGain(uint8_t gain);
int8_t getRSSI();
protected:
int16_t setBandwidthRaw(uint8_t newBandwidth);

View file

@ -147,8 +147,12 @@ int16_t SX1278::setFrequency(float freq) {
}
}
// set frequency
return(SX127x::setFrequencyRaw(freq));
// set frequency and if successful, save the new setting
int16_t state = SX127x::setFrequencyRaw(freq);
if(state == ERR_NONE) {
SX127x::_freq = freq;
}
return(state);
}
int16_t SX1278::setBandwidth(float bw) {
@ -323,6 +327,31 @@ int16_t SX1278::setGain(uint8_t gain) {
return(state);
}
int8_t SX1278::getRSSI() {
// check active modem
if(getActiveModem() != SX127X_LORA) {
return(0);
}
int8_t lastPacketRSSI;
// RSSI calculation uses different constant for low-frequency and high-frequency ports
if(_freq < 868.0) {
lastPacketRSSI = -164 + _mod->SPIgetRegValue(SX127X_REG_PKT_RSSI_VALUE);
} else {
lastPacketRSSI = -157 + _mod->SPIgetRegValue(SX127X_REG_PKT_RSSI_VALUE);
}
// spread-spectrum modulation signal can be received below noise floor
// check last packet SNR and if it's less than 0, add it to reported RSSI to get the correct value
float lastPacketSNR = SX127x::getSNR();
if(lastPacketSNR < 0.0) {
lastPacketRSSI += lastPacketSNR;
}
return(lastPacketRSSI);
}
int16_t SX1278::setBandwidthRaw(uint8_t newBandwidth) {
// set mode to standby
int16_t state = SX127x::standby();
@ -370,7 +399,7 @@ int16_t SX1278::config() {
// calculate symbol length and set low datarate optimization, if needed
uint16_t base = 1;
float symbolLength = (float)(base << _sf) / (float)_bw;
if(symbolLength >= 0.016) {
if(symbolLength >= 16.0) {
state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_ON, 0, 0);
} else {
state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 0, 0);

View file

@ -108,6 +108,7 @@ class SX1278: public SX127x {
int16_t setCodingRate(uint8_t cr);
int16_t setOutputPower(int8_t power);
int16_t setGain(uint8_t gain);
int8_t getRSSI();
protected:
int16_t setBandwidthRaw(uint8_t newBandwidth);
@ -118,7 +119,7 @@ class SX1278: public SX127x {
int16_t configFSK();
private:
};
#endif

View file

@ -42,6 +42,9 @@ int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord, uint8_t currentLimi
// set preamble length
state = SX127x::setPreambleLength(preambleLength);
// initalize internal variables
_dataRate = 0.0;
return(state);
}
@ -128,14 +131,14 @@ int16_t SX127x::transmit(uint8_t* data, size_t len, uint8_t addr) {
uint16_t base = 1;
float symbolLength = (float)(base << _sf) / (float)_bw;
float de = 0;
if(symbolLength >= 0.016) {
if(symbolLength >= 16.0) {
de = 1;
}
float ih = (float)_mod->SPIgetRegValue(SX127X_REG_MODEM_CONFIG_1, 0, 0);
float crc = (float)(_mod->SPIgetRegValue(SX127X_REG_MODEM_CONFIG_2, 2, 2) >> 2);
float n_pre = (float)_mod->SPIgetRegValue(SX127X_REG_PREAMBLE_LSB);
float n_pay = 8.0 + max(ceil((8.0 * (float)len - 4.0 * (float)_sf + 28.0 + 16.0 * crc - 20.0 * ih)/(4.0 * (float)_sf - 8.0 * de)) * (float)_cr, 0.0);
uint32_t timeout = ceil(symbolLength * (n_pre + n_pay + 4.25) * 1000.0);
uint32_t timeout = ceil(symbolLength * (n_pre + n_pay + 4.25) * 1.5);
// set DIO mapping
_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_TX_DONE, 7, 6);
@ -170,7 +173,7 @@ int16_t SX127x::transmit(uint8_t* data, size_t len, uint8_t addr) {
uint32_t elapsed = millis() - start;
// update data rate
dataRate = (len*8.0)/((float)elapsed/1000.0);
_dataRate = (len*8.0)/((float)elapsed/1000.0);
// clear interrupt flags
clearIRQFlags();
@ -295,11 +298,6 @@ int16_t SX127x::receive(uint8_t* data, size_t len) {
data[length] = 0;
}
// update RSSI and SNR
lastPacketRSSI = -157 + _mod->SPIgetRegValue(SX127X_REG_PKT_RSSI_VALUE);
int8_t rawSNR = (int8_t)_mod->SPIgetRegValue(SX127X_REG_PKT_SNR_VALUE);
lastPacketSNR = rawSNR / 4.0;
// clear interrupt flags
clearIRQFlags();
@ -634,11 +632,6 @@ int16_t SX127x::readData(uint8_t* data, size_t len) {
data[length] = 0;
}
// update RSSI and SNR
lastPacketRSSI = -157 + _mod->SPIgetRegValue(SX127X_REG_PKT_RSSI_VALUE);
int8_t rawSNR = (int8_t)_mod->SPIgetRegValue(SX127X_REG_PKT_SNR_VALUE);
lastPacketSNR = rawSNR / 4.0;
// clear interrupt flags
clearIRQFlags();
@ -787,6 +780,26 @@ float SX127x::getFrequencyError(bool autoCorrect) {
return(ERR_UNKNOWN);
}
float SX127x::getSNR() {
// check active modem
if(getActiveModem() != SX127X_LORA) {
return(0);
}
// get SNR value
int8_t rawSNR = (int8_t)_mod->SPIgetRegValue(SX127X_REG_PKT_SNR_VALUE);
return(rawSNR / 4.0);
}
float SX127x::getDataRate() {
// check active modem
if(getActiveModem() != SX127X_LORA) {
return(0);
}
return(_dataRate);
}
int16_t SX127x::setBitRate(float br) {
// check active modem
if(getActiveModem() != SX127X_FSK_OOK) {
@ -832,7 +845,7 @@ int16_t SX127x::setFrequencyDeviation(float freqDev) {
return(state);
}
// set frequency deviation from carrier frequency
// set allowed frequency deviation
uint32_t base = 1;
uint32_t FDEV = (freqDev * (base << 19)) / 32000;
state = _mod->SPIsetRegValue(SX127X_REG_FDEV_MSB, (FDEV & 0xFF00) >> 8, 5, 0);
@ -1043,7 +1056,7 @@ int16_t SX127x::config() {
int16_t SX127x::configFSK() {
// set FSK modulation
int16_t state = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_MODULATION_FSK, 6, 5);
int16_t state = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_MODULATION_FSK, 6, 5, 5);
if(state != ERR_NONE) {
return(state);
}
@ -1119,7 +1132,7 @@ bool SX127x::findChip(uint8_t ver) {
}
int16_t SX127x::setMode(uint8_t mode) {
return(_mod->SPIsetRegValue(SX127X_REG_OP_MODE, mode, 2, 0));
return(_mod->SPIsetRegValue(SX127X_REG_OP_MODE, mode, 2, 0, 5));
}
int16_t SX127x::getActiveModem() {
@ -1131,7 +1144,7 @@ int16_t SX127x::setActiveModem(uint8_t modem) {
int16_t state = setMode(SX127X_SLEEP);
// set LoRa mode
state |= _mod->SPIsetRegValue(SX127X_REG_OP_MODE, modem, 7, 7);
state |= _mod->SPIsetRegValue(SX127X_REG_OP_MODE, modem, 7, 7, 5);
// set mode to STANDBY
state |= setMode(SX127X_STANDBY);

View file

@ -522,11 +522,6 @@ class SX127x: public PhysicalLayer {
// constructor
SX127x(Module* mod);
// public member variables
float dataRate;
int8_t lastPacketRSSI;
float lastPacketSNR;
// basic methods
int16_t begin(uint8_t chipVersion, uint8_t syncWord, uint8_t currentLimit, uint16_t preambleLength);
int16_t beginFSK(uint8_t chipVersion, float br, float freqDev, float rxBw, uint8_t currentLimit);
@ -557,6 +552,8 @@ class SX127x: public PhysicalLayer {
int16_t setCurrentLimit(uint8_t currentLimit);
int16_t setPreambleLength(uint16_t preambleLength);
float getFrequencyError(bool autoCorrect = false);
float getSNR();
float getDataRate();
int16_t setBitRate(float br);
int16_t setFrequencyDeviation(float freqDev);
int16_t setRxBandwidth(float rxBw);
@ -572,6 +569,7 @@ class SX127x: public PhysicalLayer {
protected:
Module* _mod;
float _freq;
float _bw;
uint8_t _sf;
uint8_t _cr;
@ -587,6 +585,8 @@ class SX127x: public PhysicalLayer {
int16_t directMode();
private:
float _dataRate;
bool findChip(uint8_t ver);
int16_t setMode(uint8_t mode);
int16_t setActiveModem(uint8_t modem);