[SX127x] Sync with LoRaLib v7.0.0
This commit is contained in:
parent
ac2193ad72
commit
6cd42ca3e1
23 changed files with 416 additions and 140 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 "));
|
||||
|
|
35
keywords.txt
35
keywords.txt
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
62
src/modules/RFM95.cpp
Normal 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
27
src/modules/RFM95.h
Normal 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
62
src/modules/RFM96.cpp
Normal 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
29
src/modules/RFM96.h
Normal 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
39
src/modules/RFM97.cpp
Normal 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
21
src/modules/RFM97.h
Normal 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
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue