kopia lustrzana https://github.com/jgromes/RadioLib
SX127x - Sync with LoRaLib v5.0.2
rodzic
0ca15ac41f
commit
e3021b5a37
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
KiteLib SX127x Channel Activity Detection Example
|
||||
|
||||
This example scans the current LoRa channel using SX1278 LoRa radio module
|
||||
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.
|
||||
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 SX127x family can also be used.
|
||||
SX1272 lora = Kite.ModuleA;
|
||||
|
@ -25,12 +26,15 @@ void setup() {
|
|||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// current limit: 100 mA
|
||||
// preamble length: 8 symbols
|
||||
// amplifier gain: 0 (automatic gain control)
|
||||
int state = lora.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
- spreading factor
|
||||
- coding rate
|
||||
- sync word
|
||||
- preamble length
|
||||
|
||||
Other modules from SX127x family can also be used.
|
||||
SX1272 lora = Kite.ModuleA;
|
||||
|
@ -29,12 +30,15 @@ void setup() {
|
|||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// current limit: 100 mA
|
||||
// preamble length: 8 symbols
|
||||
// amplifier gain: 0 (automatic gain control)
|
||||
int state = lora.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
@ -66,21 +70,24 @@ void loop() {
|
|||
Serial.print("[SX1278] Data:\t\t");
|
||||
Serial.println(str);
|
||||
|
||||
//print the measured data rate
|
||||
Serial.print("[SX1278] Datarate:\t");
|
||||
Serial.print(lora.dataRate);
|
||||
Serial.println(" bps");
|
||||
|
||||
//print the RSSI (Received Signal Strength Indicator) of the last received packet
|
||||
// print the RSSI (Received Signal Strength Indicator)
|
||||
// of the last received packet
|
||||
Serial.print("[SX1278] RSSI:\t\t");
|
||||
Serial.print(lora.lastPacketRSSI);
|
||||
Serial.println(" dBm");
|
||||
|
||||
//print the SNR (Signal-to-Noise Ratio) of the last received packet
|
||||
// print the SNR (Signal-to-Noise Ratio)
|
||||
// of the last received packet
|
||||
Serial.print("[SX1278] SNR:\t\t");
|
||||
Serial.print(lora.lastPacketSNR);
|
||||
Serial.println(" dBm");
|
||||
|
||||
// print frequency error
|
||||
// of the last received packet
|
||||
Serial.print("Frequency error:\t");
|
||||
Serial.print(lora.getFrequencyError());
|
||||
Serial.println(" Hz");
|
||||
|
||||
} else if (state == ERR_RX_TIMEOUT) {
|
||||
// timeout occurred while waiting for a packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
|
|
@ -31,12 +31,15 @@ void setup() {
|
|||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// current limit: 100 mA
|
||||
// preamble length: 8 symbols
|
||||
// amplifier gain: 0 (automatic gain control)
|
||||
int state = lora.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
@ -128,6 +131,11 @@ void loop() {
|
|||
Serial.print("SNR:\t\t");
|
||||
Serial.print(lora.lastPacketSNR);
|
||||
Serial.println(" dBm");
|
||||
|
||||
// print frequency error
|
||||
Serial.print("Frequency error:\t");
|
||||
Serial.print(lora.getFrequencyError());
|
||||
Serial.println(" Hz");
|
||||
|
||||
} else if (state == ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
|
|
|
@ -36,12 +36,15 @@ void setup() {
|
|||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// current limit: 100 mA
|
||||
// preamble length: 8 symbols
|
||||
// amplifier gain: 0 (automatic gain control)
|
||||
int state = loraSX1278.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
@ -54,12 +57,15 @@ void setup() {
|
|||
// 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
|
||||
// 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!"));
|
||||
|
@ -69,19 +75,24 @@ void setup() {
|
|||
while (true);
|
||||
}
|
||||
|
||||
// initialize the third LoRa instance with non-default settings
|
||||
// this LoRa link will have high data rate, but lower range
|
||||
// NOTE: when using spreading factor 6, the total packet length has to be known in advance!
|
||||
// it can be set using the length variable of your Packet instance
|
||||
// Packet::length = x;
|
||||
// where x is the total packet length including both addresses
|
||||
// initialize the third LoRa instance with
|
||||
// non-default settings
|
||||
// this LoRa link will have high data rate,
|
||||
// but lower range
|
||||
// NOTE: when using spreading factor 6, the total packet
|
||||
// length has to be known in advance!
|
||||
// you have to pass the number of expected bytes
|
||||
// to the receive() method
|
||||
Serial.print(F("[SX1272] Initializing ... "));
|
||||
// carrier frequency: 915.0 MHz
|
||||
// bandwidth: 500.0 kHz
|
||||
// spreading factor: 6
|
||||
// coding rate: 5
|
||||
// sync word: 0x14
|
||||
// output power: 2 dBm
|
||||
// carrier frequency: 915.0 MHz
|
||||
// bandwidth: 500.0 kHz
|
||||
// spreading factor: 6
|
||||
// coding rate: 5
|
||||
// sync word: 0x14
|
||||
// output power: 2 dBm
|
||||
// current limit: 50 mA
|
||||
// preamble length: 20 symbols
|
||||
// amplifier gain: 1 (maximum gain)
|
||||
state = loraSX1272.begin(915.0, 500.0, 6, 5, 0x14, 2);
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
@ -128,12 +139,35 @@ void setup() {
|
|||
while (true);
|
||||
}
|
||||
|
||||
// set output power to 10 dBm (accepted range is 2 - 17 dBm)
|
||||
// set output power to 10 dBm (accepted range is -3 - 17 dBm)
|
||||
// NOTE: 20 dBm value allows high power operation, but transmission
|
||||
// duty cycle MUST NOT exceed 1%
|
||||
if (loraSX1278.setOutputPower(10) == ERR_INVALID_OUTPUT_POWER) {
|
||||
Serial.println("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 (loraSX1278.setCurrentLimit(80) == ERR_INVALID_CURRENT_LIMIT) {
|
||||
Serial.println("Selected current limit is invalid for this module!");
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set LoRa preamble length to 15 symbols (accepted range is 6 - 65535)
|
||||
if (loraSX1278.setPreambleLength(15) == ERR_INVALID_PREAMBLE_LENGTH) {
|
||||
Serial.println("Selected preamble length is invalid for this module!");
|
||||
while (true);
|
||||
}
|
||||
|
||||
// set amplifier gain to 1 (accepted range is 1 - 6, where 1 is maximum gain)
|
||||
// NOTE: set value to 0 to enable autmatic gain control
|
||||
// leave at 0 unless you know what you're doing
|
||||
if (loraSX1278.setGain(1) == ERR_INVALID_GAIN) {
|
||||
Serial.println("Selected gain is invalid for this module!");
|
||||
while (true);
|
||||
}
|
||||
|
||||
Serial.println("All settings succesfully changed!");
|
||||
}
|
||||
|
||||
|
|
|
@ -26,12 +26,15 @@ void setup() {
|
|||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// current limit: 100 mA
|
||||
// preamble length: 8 symbols
|
||||
// amplifier gain: 0 (automatic gain control)
|
||||
int state = lora.begin();
|
||||
if (state == ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
@ -45,7 +48,8 @@ void setup() {
|
|||
void loop() {
|
||||
Serial.print(F("[SX1278] Transmitting packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to 256 characters long
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
int state = lora.transmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
|
@ -58,6 +62,11 @@ void loop() {
|
|||
// the packet was successfully transmitted
|
||||
Serial.println(" success!");
|
||||
|
||||
// print measured data rate
|
||||
Serial.print("Datarate:\t");
|
||||
Serial.print(lora.dataRate);
|
||||
Serial.println(" bps");
|
||||
|
||||
} else if (state == ERR_PACKET_TOO_LONG) {
|
||||
// the supplied packet was longer than 256 bytes
|
||||
Serial.println(" too long!");
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
KiteLib 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 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;
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <KiteLib.h>
|
||||
|
||||
// SX1278 module is in slot A on the shield
|
||||
SX1278 lora = Kite.ModuleA;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bandwidth: 125.0 kHz
|
||||
// spreading factor: 9
|
||||
// coding rate: 7
|
||||
// sync word: 0x12
|
||||
// output power: 17 dBm
|
||||
// current limit: 100 mA
|
||||
// preamble length: 8 symbols
|
||||
// amplifier gain: 0 (automatic gain control)
|
||||
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.setDio0Action(setFlag);
|
||||
|
||||
// start transmitting the first packet
|
||||
Serial.print(F("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("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.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state != ERR_NONE) {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -118,6 +118,10 @@ ERR_INVALID_FREQUENCY LITERAL1
|
|||
ERR_INVALID_OUTPUT_POWER LITERAL1
|
||||
PREAMBLE_DETECTED LITERAL1
|
||||
CHANNEL_FREE LITERAL1
|
||||
ERR_SPI_WRITE_FAILED LITERAL1
|
||||
ERR_INVALID_CURRENT_LIMIT LITERAL1
|
||||
ERR_INVALID_PREAMBLE_LENGTH LITERAL1
|
||||
ERR_INVALID_GAIN LITERAL1
|
||||
|
||||
ERR_INVALID_BIT_RATE LITERAL1
|
||||
ERR_INVALID_FREQUENCY_DEVIATION LITERAL1
|
||||
|
|
|
@ -76,6 +76,9 @@
|
|||
#define PREAMBLE_DETECTED -14
|
||||
#define CHANNEL_FREE -15
|
||||
#define ERR_SPI_WRITE_FAILED -16
|
||||
#define ERR_INVALID_CURRENT_LIMIT -17
|
||||
#define ERR_INVALID_PREAMBLE_LENGTH -18
|
||||
#define ERR_INVALID_GAIN -19
|
||||
|
||||
// RF69-specific status codes
|
||||
#define ERR_INVALID_BIT_RATE -101
|
||||
|
|
|
@ -4,9 +4,9 @@ SX1272::SX1272(Module* mod) : SX127x(mod) {
|
|||
|
||||
}
|
||||
|
||||
int16_t SX1272::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power) {
|
||||
int16_t SX1272::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(SX1272_CHIP_VERSION, syncWord);
|
||||
int16_t state = SX127x::begin(SX1272_CHIP_VERSION, syncWord, currentLimit, preambleLength);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
@ -17,6 +17,13 @@ int16_t SX1272::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
|
|||
return(state);
|
||||
}
|
||||
|
||||
// mitigation of receiver spurious response
|
||||
// see SX1272/73 Errata, section 2.2 for details
|
||||
state = _mod->SPIsetRegValue(0x31, 0b10000000, 7, 7);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// configure publicly accessible settings
|
||||
state = setFrequency(freq);
|
||||
if(state != ERR_NONE) {
|
||||
|
@ -43,7 +50,12 @@ int16_t SX1272::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
|
|||
return(state);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
state = setGain(gain);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1272::setFrequency(float freq) {
|
||||
|
@ -60,11 +72,11 @@ int16_t SX1272::setBandwidth(float bw) {
|
|||
uint8_t newBandwidth;
|
||||
|
||||
// check alowed bandwidth values
|
||||
if(bw == 125.0) {
|
||||
if(abs(bw - 125.0) <= 0.001) {
|
||||
newBandwidth = SX1272_BW_125_00_KHZ;
|
||||
} else if(bw == 250.0) {
|
||||
} else if(abs(bw - 250.0) <= 0.001) {
|
||||
newBandwidth = SX1272_BW_250_00_KHZ;
|
||||
} else if(bw == 500.0) {
|
||||
} else if(abs(bw - 500.0) <= 0.001) {
|
||||
newBandwidth = SX1272_BW_500_00_KHZ;
|
||||
} else {
|
||||
return(ERR_INVALID_BANDWIDTH);
|
||||
|
@ -75,7 +87,6 @@ int16_t SX1272::setBandwidth(float bw) {
|
|||
if(state == ERR_NONE) {
|
||||
SX127x::_bw = bw;
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
@ -114,7 +125,6 @@ int16_t SX1272::setSpreadingFactor(uint8_t sf) {
|
|||
if(state == ERR_NONE) {
|
||||
SX127x::_sf = sf;
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
@ -144,7 +154,6 @@ int16_t SX1272::setCodingRate(uint8_t cr) {
|
|||
if(state == ERR_NONE) {
|
||||
SX127x::_cr = cr;
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
@ -155,43 +164,62 @@ int16_t SX1272::setOutputPower(int8_t power) {
|
|||
}
|
||||
|
||||
// set mode to standby
|
||||
SX127x::standby();
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
int16_t state;
|
||||
// set output power
|
||||
if(power < 2) {
|
||||
// power is less than 2 dBm, enable PA0 on RFIO
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_RFO, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_RFO, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, (power + 1), 3, 0);
|
||||
state |= _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_OFF, 2, 0);
|
||||
} else if((power >= 2) && (power <= 17)) {
|
||||
// power is 2 - 17 dBm, enable PA1 + PA2 on PA_BOOST
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, (power - 2), 3, 0);
|
||||
state |= _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_OFF, 2, 0);
|
||||
} else if(power == 20) {
|
||||
// power is 20 dBm, enable PA1 + PA2 on PA_BOOST and enable high power control
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, (power - 5), 3, 0);
|
||||
state |= _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0);
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1272::setGain(uint8_t gain) {
|
||||
// check allowed range
|
||||
if(gain > 6) {
|
||||
return(ERR_INVALID_GAIN);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// set gain
|
||||
if(gain == 0) {
|
||||
// gain set to 0, enable AGC loop
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1272_AGC_AUTO_ON, 2, 2);
|
||||
} else {
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1272_AGC_AUTO_OFF, 2, 2);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_LNA, (gain << 5) | SX127X_LNA_BOOST_ON);
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1272::setBandwidthRaw(uint8_t newBandwidth) {
|
||||
// set mode to standby
|
||||
SX127x::standby();
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// write register
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newBandwidth, 7, 6));
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newBandwidth, 7, 6);
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1272::setSpreadingFactorRaw(uint8_t newSpreadingFactor) {
|
||||
// set mode to standby
|
||||
SX127x::standby();
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// write registers
|
||||
int16_t state = 0;
|
||||
if(newSpreadingFactor == SX127X_SF_6) {
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_HEADER_IMPL_MODE | SX1272_RX_CRC_MODE_OFF, 2, 1);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX127X_SF_6 | SX127X_TX_MODE_SINGLE, 7, 3);
|
||||
|
@ -203,16 +231,16 @@ int16_t SX1272::setSpreadingFactorRaw(uint8_t newSpreadingFactor) {
|
|||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_7_12, 2, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_7_12);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1272::setCodingRateRaw(uint8_t newCodingRate) {
|
||||
// set mode to standby
|
||||
SX127x::standby();
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// write register
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newCodingRate, 5, 3));
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newCodingRate, 5, 3);
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1272::config() {
|
||||
|
@ -222,12 +250,6 @@ int16_t SX1272::config() {
|
|||
return(state);
|
||||
}
|
||||
|
||||
// enable LNA gain setting by register
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1272_AGC_AUTO_OFF, 2, 2);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// calculate symbol length and set low datarate optimization, if needed
|
||||
uint16_t base = 1;
|
||||
float symbolLength = (float)(base << _sf) / (float)_bw;
|
||||
|
@ -236,6 +258,5 @@ int16_t SX1272::config() {
|
|||
} else {
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ class SX1272: public SX127x {
|
|||
SX1272(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);
|
||||
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);
|
||||
|
@ -60,14 +60,17 @@ class SX1272: public SX127x {
|
|||
int16_t setSpreadingFactor(uint8_t sf);
|
||||
int16_t setCodingRate(uint8_t cr);
|
||||
int16_t setOutputPower(int8_t power);
|
||||
int16_t setGain(uint8_t gain);
|
||||
|
||||
protected:
|
||||
int16_t setBandwidthRaw(uint8_t newBandwidth);
|
||||
int16_t setSpreadingFactorRaw(uint8_t newSpreadingFactor);
|
||||
int16_t setCodingRateRaw(uint8_t newCodingRate);
|
||||
|
||||
int16_t config();
|
||||
|
||||
private:
|
||||
int16_t config();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,60 @@ SX1273::SX1273(Module* mod) : SX1272(mod) {
|
|||
|
||||
}
|
||||
|
||||
int16_t SX1273::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(SX1272_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);
|
||||
}
|
||||
|
||||
// mitigation of receiver spurious response
|
||||
// see SX1272/73 Errata, section 2.2 for details
|
||||
state = _mod->SPIsetRegValue(0x31, 0b10000000, 7, 7);
|
||||
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 SX1273::setSpreadingFactor(uint8_t sf) {
|
||||
uint8_t newSpreadingFactor;
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ class SX1273: public SX1272 {
|
|||
// constructor
|
||||
SX1273(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 setSpreadingFactor(uint8_t sf);
|
||||
};
|
||||
|
|
|
@ -4,6 +4,53 @@ SX1276::SX1276(Module* mod) : SX1278(mod) {
|
|||
|
||||
}
|
||||
|
||||
int16_t SX1276::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(SX1278_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 SX1276::setFrequency(float freq) {
|
||||
// check frequency range
|
||||
if((freq < 137.0) || (freq > 1020.0)) {
|
||||
|
@ -12,7 +59,7 @@ int16_t SX1276::setFrequency(float freq) {
|
|||
|
||||
// sensitivity optimization for 500kHz bandwidth
|
||||
// see SX1276/77/78 Errata, section 2.1 for details
|
||||
if(_bw == 500.0) {
|
||||
if(abs(_bw - 500.0) <= 0.001) {
|
||||
if((freq >= 862.0) && (freq <= 1020.0)) {
|
||||
_mod->SPIwriteRegister(0x36, 0x02);
|
||||
_mod->SPIwriteRegister(0x3a, 0x64);
|
||||
|
@ -24,49 +71,49 @@ int16_t SX1276::setFrequency(float freq) {
|
|||
|
||||
// mitigation of receiver spurious response
|
||||
// see SX1276/77/78 Errata, section 2.3 for details
|
||||
if(_bw == 7.8) {
|
||||
if(abs(_bw - 7.8) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x48);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 7.8;
|
||||
} else if(_bw == 10.4) {
|
||||
} else if(abs(_bw - 10.4) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 10.4;
|
||||
} else if(_bw == 15.6) {
|
||||
} else if(abs(_bw - 15.6) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 15.6;
|
||||
} else if(_bw == 20.8) {
|
||||
} else if(abs(_bw - 20.8) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 20.8;
|
||||
} else if(_bw == 31.25) {
|
||||
} else if(abs(_bw - 31.25) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 31.25;
|
||||
} else if(_bw == 41.7) {
|
||||
} else if(abs(_bw - 41.7) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 41.7;
|
||||
} else if(_bw == 62.5) {
|
||||
} else if(abs(_bw - 62.5) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x40);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
} else if(_bw == 125.0) {
|
||||
} else if(abs(_bw - 125.0) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x40);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
} else if(_bw == 250.0) {
|
||||
} else if(abs(_bw - 250.0) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x40);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
} else if(_bw == 500.0) {
|
||||
} else if(abs(_bw - 500.0) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b1000000, 7, 7);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ class SX1276: public SX1278 {
|
|||
// constructor
|
||||
SX1276(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);
|
||||
};
|
||||
|
|
|
@ -4,6 +4,53 @@ SX1277::SX1277(Module* mod) : SX1278(mod) {
|
|||
|
||||
}
|
||||
|
||||
int16_t SX1277::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(SX1278_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 SX1277::setFrequency(float freq) {
|
||||
// check frequency range
|
||||
if((freq < 137.0) || (freq > 1020.0)) {
|
||||
|
@ -12,7 +59,7 @@ int16_t SX1277::setFrequency(float freq) {
|
|||
|
||||
// sensitivity optimization for 500kHz bandwidth
|
||||
// see SX1276/77/78 Errata, section 2.1 for details
|
||||
if(_bw == 500.0) {
|
||||
if(abs(_bw - 500.0) <= 0.001) {
|
||||
if((freq >= 862.0) && (freq <= 1020.0)) {
|
||||
_mod->SPIwriteRegister(0x36, 0x02);
|
||||
_mod->SPIwriteRegister(0x3a, 0x64);
|
||||
|
@ -24,49 +71,49 @@ int16_t SX1277::setFrequency(float freq) {
|
|||
|
||||
// mitigation of receiver spurious response
|
||||
// see SX1276/77/78 Errata, section 2.3 for details
|
||||
if(_bw == 7.8) {
|
||||
if(abs(_bw - 7.8) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x48);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 7.8;
|
||||
} else if(_bw == 10.4) {
|
||||
} else if(abs(_bw - 10.4) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 10.4;
|
||||
} else if(_bw == 15.6) {
|
||||
} else if(abs(_bw - 15.6) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 15.6;
|
||||
} else if(_bw == 20.8) {
|
||||
} else if(abs(_bw - 20.8) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 20.8;
|
||||
} else if(_bw == 31.25) {
|
||||
} else if(abs(_bw - 31.25) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 31.25;
|
||||
} else if(_bw == 41.7) {
|
||||
} else if(abs(_bw - 41.7) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 41.7;
|
||||
} else if(_bw == 62.5) {
|
||||
} else if(abs(_bw - 62.5) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x40);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
} else if(_bw == 125.0) {
|
||||
} else if(abs(_bw - 125.0) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x40);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
} else if(_bw == 250.0) {
|
||||
} else if(abs(_bw - 250.0) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x40);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
} else if(_bw == 500.0) {
|
||||
} else if(abs(_bw - 500.0) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b1000000, 7, 7);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,9 @@ class SX1277: public SX1278 {
|
|||
// constructor
|
||||
SX1277(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);
|
||||
int16_t setSpreadingFactor(uint8_t sf);
|
||||
|
|
|
@ -4,9 +4,9 @@ SX1278::SX1278(Module* mod) : SX127x(mod) {
|
|||
|
||||
}
|
||||
|
||||
int16_t SX1278::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power) {
|
||||
int16_t SX1278::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(SX1278_CHIP_VERSION, syncWord);
|
||||
int16_t state = SX127x::begin(SX1278_CHIP_VERSION, syncWord, currentLimit, preambleLength);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
@ -43,7 +43,12 @@ int16_t SX1278::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync
|
|||
return(state);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
state = setGain(gain);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::setFrequency(float freq) {
|
||||
|
@ -54,7 +59,7 @@ int16_t SX1278::setFrequency(float freq) {
|
|||
|
||||
// sensitivity optimization for 500kHz bandwidth
|
||||
// see SX1276/77/78 Errata, section 2.1 for details
|
||||
if(_bw == 500.0) {
|
||||
if(abs(_bw - 500.0) <= 0.001) {
|
||||
if((freq >= 862.0) && (freq <= 1020.0)) {
|
||||
_mod->SPIwriteRegister(0x36, 0x02);
|
||||
_mod->SPIwriteRegister(0x3a, 0x64);
|
||||
|
@ -66,49 +71,49 @@ int16_t SX1278::setFrequency(float freq) {
|
|||
|
||||
// mitigation of receiver spurious response
|
||||
// see SX1276/77/78 Errata, section 2.3 for details
|
||||
if(_bw == 7.8) {
|
||||
if(abs(_bw - 7.8) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x48);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 7.8;
|
||||
} else if(_bw == 10.4) {
|
||||
} else if(abs(_bw - 10.4) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 10.4;
|
||||
} else if(_bw == 15.6) {
|
||||
} else if(abs(_bw - 15.6) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 15.6;
|
||||
} else if(_bw == 20.8) {
|
||||
} else if(abs(_bw - 20.8) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 20.8;
|
||||
} else if(_bw == 31.25) {
|
||||
} else if(abs(_bw - 31.25) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 31.25;
|
||||
} else if(_bw == 41.7) {
|
||||
} else if(abs(_bw - 41.7) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x44);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
freq += 41.7;
|
||||
} else if(_bw == 62.5) {
|
||||
} else if(abs(_bw - 62.5) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x40);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
} else if(_bw == 125.0) {
|
||||
} else if(abs(_bw - 125.0) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x40);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
} else if(_bw == 250.0) {
|
||||
} else if(abs(_bw - 250.0) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b0000000, 7, 7);
|
||||
_mod->SPIsetRegValue(0x2F, 0x40);
|
||||
_mod->SPIsetRegValue(0x30, 0x00);
|
||||
} else if(_bw == 500.0) {
|
||||
} else if(abs(_bw - 500.0) <= 0.001) {
|
||||
_mod->SPIsetRegValue(0x31, 0b1000000, 7, 7);
|
||||
}
|
||||
|
||||
|
@ -120,25 +125,25 @@ int16_t SX1278::setBandwidth(float bw) {
|
|||
uint8_t newBandwidth;
|
||||
|
||||
// check alowed bandwidth values
|
||||
if(bw == 7.8) {
|
||||
if(abs(bw - 7.8) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_7_80_KHZ;
|
||||
} else if(bw == 10.4) {
|
||||
} else if(abs(bw - 10.4) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_10_40_KHZ;
|
||||
} else if(bw == 15.6) {
|
||||
} else if(abs(bw - 15.6) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_15_60_KHZ;
|
||||
} else if(bw == 20.8) {
|
||||
} else if(abs(bw - 20.8) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_20_80_KHZ;
|
||||
} else if(bw == 31.25) {
|
||||
} else if(abs(bw - 32.5) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_31_25_KHZ;
|
||||
} else if(bw == 41.7) {
|
||||
} else if(abs(bw - 41.7) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_41_70_KHZ;
|
||||
} else if(bw == 62.5) {
|
||||
} else if(abs(bw - 62.5) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_62_50_KHZ;
|
||||
} else if(bw == 125.0) {
|
||||
} else if(abs(bw - 125.0) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_125_00_KHZ;
|
||||
} else if(bw == 250.0) {
|
||||
} else if(abs(bw - 250.0) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_250_00_KHZ;
|
||||
} else if(bw == 500.0) {
|
||||
} else if(abs(bw - 500.0) <= 0.001) {
|
||||
newBandwidth = SX1278_BW_500_00_KHZ;
|
||||
} else {
|
||||
return(ERR_INVALID_BANDWIDTH);
|
||||
|
@ -149,7 +154,6 @@ int16_t SX1278::setBandwidth(float bw) {
|
|||
if(state == ERR_NONE) {
|
||||
SX127x::_bw = bw;
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
@ -188,7 +192,6 @@ int16_t SX1278::setSpreadingFactor(uint8_t sf) {
|
|||
if(state == ERR_NONE) {
|
||||
SX127x::_sf = sf;
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
@ -218,53 +221,72 @@ int16_t SX1278::setCodingRate(uint8_t cr) {
|
|||
if(state == ERR_NONE) {
|
||||
SX127x::_cr = cr;
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::setOutputPower(int8_t power) {
|
||||
// check allowed power range
|
||||
if(!(((power >= -3) && (power <= 17)) || (power == 20))) {
|
||||
return(ERR_INVALID_OUTPUT_POWER);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
SX127x::standby();
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
int16_t state;
|
||||
// set output power
|
||||
if(power < 2) {
|
||||
// power is less than 2 dBm, enable PA on RFO
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_RFO, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_RFO, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_LOW_POWER | (power + 3), 6, 0);
|
||||
state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_OFF, 2, 0);
|
||||
} else if((power >= 2) && (power <= 17)) {
|
||||
// power is 2 - 17 dBm, enable PA1 + PA2 on PA_BOOST
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_MAX_POWER | (power - 2), 6, 0);
|
||||
state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_OFF, 2, 0);
|
||||
} else if(power == 20) {
|
||||
// power is 20 dBm, enable PA1 + PA2 on PA_BOOST and enable high power mode
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST, 7, 7);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_MAX_POWER | (power - 5), 6, 0);
|
||||
state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0);
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::setGain(uint8_t gain) {
|
||||
// check allowed range
|
||||
if(gain > 6) {
|
||||
return(ERR_INVALID_GAIN);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// set gain
|
||||
if(gain == 0) {
|
||||
// gain set to 0, enable AGC loop
|
||||
state |= _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_AGC_AUTO_ON, 2, 2);
|
||||
} else {
|
||||
state |= _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_AGC_AUTO_OFF, 2, 2);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_LNA, (gain << 5) | SX127X_LNA_BOOST_ON);
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::setBandwidthRaw(uint8_t newBandwidth) {
|
||||
// set mode to standby
|
||||
SX127x::standby();
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// write register
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newBandwidth, 7, 4));
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newBandwidth, 7, 4);
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::setSpreadingFactorRaw(uint8_t newSpreadingFactor) {
|
||||
// set mode to standby
|
||||
SX127x::standby();
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// write registers
|
||||
int16_t state = 0;
|
||||
if(newSpreadingFactor == SX127X_SF_6) {
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1278_HEADER_IMPL_MODE, 0, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX127X_SF_6 | SX127X_TX_MODE_SINGLE | SX1278_RX_CRC_MODE_OFF, 7, 2);
|
||||
|
@ -276,16 +298,16 @@ int16_t SX1278::setSpreadingFactorRaw(uint8_t newSpreadingFactor) {
|
|||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_7_12, 2, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_7_12);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::setCodingRateRaw(uint8_t newCodingRate) {
|
||||
// set mode to standby
|
||||
SX127x::standby();
|
||||
int16_t state = SX127x::standby();
|
||||
|
||||
// write register
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newCodingRate, 3, 1));
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newCodingRate, 3, 1);
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX1278::config() {
|
||||
|
@ -295,12 +317,6 @@ int16_t SX1278::config() {
|
|||
return(state);
|
||||
}
|
||||
|
||||
// enable LNA gain setting by register
|
||||
state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_AGC_AUTO_OFF, 2, 2);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// calculate symbol length and set low datarate optimization, if needed
|
||||
uint16_t base = 1;
|
||||
float symbolLength = (float)(base << _sf) / (float)_bw;
|
||||
|
@ -309,6 +325,5 @@ int16_t SX1278::config() {
|
|||
} else {
|
||||
state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 0, 0);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ class SX1278: public SX127x {
|
|||
SX1278(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);
|
||||
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);
|
||||
|
@ -78,14 +78,17 @@ class SX1278: public SX127x {
|
|||
int16_t setSpreadingFactor(uint8_t sf);
|
||||
int16_t setCodingRate(uint8_t cr);
|
||||
int16_t setOutputPower(int8_t power);
|
||||
int16_t setGain(uint8_t gain);
|
||||
|
||||
protected:
|
||||
int16_t setBandwidthRaw(uint8_t newBandwidth);
|
||||
int16_t setSpreadingFactorRaw(uint8_t newSpreadingFactor);
|
||||
int16_t setCodingRateRaw(uint8_t newCodingRate);
|
||||
|
||||
private:
|
||||
int16_t config();
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,53 @@ SX1279::SX1279(Module* mod) : SX1278(mod) {
|
|||
|
||||
}
|
||||
|
||||
int16_t SX1279::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(SX1278_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 SX1279::setFrequency(float freq) {
|
||||
// check frequency range
|
||||
if((freq < 137.0) || (freq > 960.0)) {
|
||||
|
|
|
@ -9,6 +9,9 @@ class SX1279: public SX1278 {
|
|||
// constructor
|
||||
SX1279(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);
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@ SX127x::SX127x(Module* mod) {
|
|||
_mod = mod;
|
||||
}
|
||||
|
||||
int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord) {
|
||||
int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord, uint8_t currentLimit, uint16_t preambleLength) {
|
||||
// set module properties
|
||||
_mod->init(USE_SPI, INT_BOTH);
|
||||
|
||||
|
@ -12,7 +12,7 @@ int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord) {
|
|||
uint8_t i = 0;
|
||||
bool flagFound = false;
|
||||
while((i < 10) && !flagFound) {
|
||||
int16_t version = _mod->SPIreadRegister(SX127X_REG_VERSION);
|
||||
uint8_t version = _mod->SPIreadRegister(SX127X_REG_VERSION);
|
||||
if(version == chipVersion) {
|
||||
flagFound = true;
|
||||
} else {
|
||||
|
@ -21,8 +21,8 @@ int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord) {
|
|||
Serial.print(i + 1);
|
||||
Serial.print(F(" of 10 tries) SX127X_REG_VERSION == "));
|
||||
|
||||
char buffHex[7];
|
||||
sprintf(buffHex, "0x%04X", version);
|
||||
char buffHex[5];
|
||||
sprintf(buffHex, "0x%02X", version);
|
||||
Serial.print(buffHex);
|
||||
Serial.print(F(", expected 0x00"));
|
||||
Serial.print(chipVersion, HEX);
|
||||
|
@ -46,7 +46,19 @@ int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord) {
|
|||
return(state);
|
||||
}
|
||||
|
||||
return(ERR_NONE);
|
||||
// set over current protection
|
||||
state = SX127x::setCurrentLimit(currentLimit);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// set preamble length
|
||||
state = SX127x::setPreambleLength(preambleLength);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX127x::transmit(String& str) {
|
||||
|
@ -77,7 +89,7 @@ int16_t SX127x::transmit(uint8_t* data, size_t len) {
|
|||
uint32_t timeout = ceil(symbolLength * (n_pre + n_pay + 4.25) * 1000.0);
|
||||
|
||||
// set mode to standby
|
||||
setMode(SX127X_STANDBY);
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
||||
// set DIO mapping
|
||||
_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_TX_DONE, 7, 6);
|
||||
|
@ -86,17 +98,20 @@ int16_t SX127x::transmit(uint8_t* data, size_t len) {
|
|||
clearIRQFlags();
|
||||
|
||||
// set packet length
|
||||
_mod->SPIsetRegValue(SX127X_REG_PAYLOAD_LENGTH, len);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PAYLOAD_LENGTH, len);
|
||||
|
||||
// set FIFO pointers
|
||||
_mod->SPIsetRegValue(SX127X_REG_FIFO_TX_BASE_ADDR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
_mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_TX_BASE_ADDR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
|
||||
// write packet to FIFO
|
||||
_mod->SPIwriteRegisterBurst(SX127X_REG_FIFO, data, len);
|
||||
|
||||
// start transmission
|
||||
setMode(SX127X_TX);
|
||||
state |= setMode(SX127X_TX);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// wait for packet transmission or timeout
|
||||
uint32_t start = millis();
|
||||
|
@ -133,20 +148,23 @@ int16_t SX127x::receive(String& str, size_t len) {
|
|||
|
||||
int16_t SX127x::receive(uint8_t* data, size_t len) {
|
||||
// set mode to standby
|
||||
setMode(SX127X_STANDBY);
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
||||
// set DIO pin mapping
|
||||
_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_RX_DONE | SX127X_DIO1_RX_TIMEOUT, 7, 4);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_RX_DONE | SX127X_DIO1_RX_TIMEOUT, 7, 4);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// set FIFO pointers
|
||||
_mod->SPIsetRegValue(SX127X_REG_FIFO_RX_BASE_ADDR, SX127X_FIFO_RX_BASE_ADDR_MAX);
|
||||
_mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_RX_BASE_ADDR_MAX);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_RX_BASE_ADDR, SX127X_FIFO_RX_BASE_ADDR_MAX);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_RX_BASE_ADDR_MAX);
|
||||
|
||||
// set mode to receive
|
||||
setMode(SX127X_RXSINGLE);
|
||||
state |= setMode(SX127X_RXSINGLE);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// wait for packet reception or timeout
|
||||
uint32_t start = millis();
|
||||
|
@ -170,10 +188,10 @@ int16_t SX127x::receive(uint8_t* data, size_t len) {
|
|||
|
||||
// read packet data
|
||||
if(len == 0) {
|
||||
// argument len equal to zero indicates String call, which means dynamically allocated data array
|
||||
// argument 'len' equal to zero indicates String call, which means dynamically allocated data array
|
||||
// dispose of the original and create a new one
|
||||
delete[] data;
|
||||
data = new uint8_t[length];
|
||||
data = new uint8_t[length + 1];
|
||||
}
|
||||
_mod->SPIreadRegisterBurst(SX127X_REG_FIFO, length, data);
|
||||
|
||||
|
@ -195,14 +213,19 @@ int16_t SX127x::receive(uint8_t* data, size_t len) {
|
|||
|
||||
int16_t SX127x::scanChannel() {
|
||||
// set mode to standby
|
||||
setMode(SX127X_STANDBY);
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
||||
// set DIO pin mapping
|
||||
_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_CAD_DONE | SX127X_DIO1_CAD_DETECTED, 7, 4);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_CAD_DONE | SX127X_DIO1_CAD_DETECTED, 7, 4);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// set mode to CAD
|
||||
setMode(SX127X_CAD);
|
||||
state |= setMode(SX127X_CAD);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// wait for channel activity detected or timeout
|
||||
while(!digitalRead(_mod->int0())) {
|
||||
|
@ -228,21 +251,18 @@ int16_t SX127x::standby() {
|
|||
return(setMode(SX127X_STANDBY));
|
||||
}
|
||||
|
||||
int16_t SX127x::listen() {
|
||||
int16_t SX127x::startReceive() {
|
||||
// set mode to standby
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
||||
// set DIO pin mapping
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_RX_DONE | SX127X_DIO1_RX_TIMEOUT, 7, 4);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// set FIFO pointers
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_FIFO_RX_BASE_ADDR, SX127X_FIFO_RX_BASE_ADDR_MAX);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_RX_BASE_ADDR, SX127X_FIFO_RX_BASE_ADDR_MAX);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_RX_BASE_ADDR_MAX);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
|
@ -252,34 +272,54 @@ int16_t SX127x::listen() {
|
|||
return(setMode(SX127X_RXCONTINUOUS));
|
||||
}
|
||||
|
||||
int16_t SX127x::setSyncWord(uint8_t syncWord) {
|
||||
// set mode to standby
|
||||
setMode(SX127X_STANDBY);
|
||||
|
||||
// write register
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_SYNC_WORD, syncWord));
|
||||
}
|
||||
|
||||
int16_t SX127x::setFrequencyRaw(float newFreq) {
|
||||
// set mode to standby
|
||||
setMode(SX127X_STANDBY);
|
||||
|
||||
// calculate register values
|
||||
uint32_t base = 1;
|
||||
uint32_t FRF = (newFreq * (base << 19)) / 32.0;
|
||||
|
||||
// write registers
|
||||
int16_t state = _mod->SPIsetRegValue(SX127X_REG_FRF_MSB, (FRF & 0xFF0000) >> 16);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FRF_MID, (FRF & 0x00FF00) >> 8);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FRF_LSB, FRF & 0x0000FF);
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
void SX127x::onReceive(void (*func)(void)) {
|
||||
void SX127x::setDio0Action(void (*func)(void)) {
|
||||
attachInterrupt(digitalPinToInterrupt(_mod->int0()), func, RISING);
|
||||
}
|
||||
|
||||
void SX127x::setDio1Action(void (*func)(void)) {
|
||||
attachInterrupt(digitalPinToInterrupt(_mod->int1()), func, RISING);
|
||||
}
|
||||
|
||||
int16_t SX127x::startTransmit(String& str) {
|
||||
return(SX127x::startTransmit(str.c_str()));
|
||||
}
|
||||
|
||||
int16_t SX127x::startTransmit(const char* str) {
|
||||
return(SX127x::startTransmit((uint8_t*)str, strlen(str)));
|
||||
}
|
||||
|
||||
int16_t SX127x::startTransmit(uint8_t* data, size_t len) {
|
||||
// check packet length
|
||||
if(len >= 256) {
|
||||
return(ERR_PACKET_TOO_LONG);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
||||
// set DIO mapping
|
||||
_mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_TX_DONE, 7, 6);
|
||||
|
||||
// clear interrupt flags
|
||||
clearIRQFlags();
|
||||
|
||||
// set packet length
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PAYLOAD_LENGTH, len);
|
||||
|
||||
// set FIFO pointers
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_TX_BASE_ADDR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_TX_BASE_ADDR_MAX);
|
||||
|
||||
// write packet to FIFO
|
||||
_mod->SPIwriteRegisterBurst(SX127X_REG_FIFO, data, len);
|
||||
|
||||
// start transmission
|
||||
state |= setMode(SX127X_TX);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
}
|
||||
|
||||
int16_t SX127x::readData(String& str, size_t len) {
|
||||
// create temporary array to store received data
|
||||
char* data = new char[len];
|
||||
|
@ -311,7 +351,7 @@ int16_t SX127x::readData(uint8_t* data, size_t len) {
|
|||
// argument len equal to zero indicates String call, which means dynamically allocated data array
|
||||
// dispose of the original and create a new one
|
||||
delete[] data;
|
||||
data = new uint8_t[length];
|
||||
data = new uint8_t[length + 1];
|
||||
}
|
||||
_mod->SPIreadRegisterBurst(SX127X_REG_FIFO, length, data);
|
||||
|
||||
|
@ -331,47 +371,101 @@ int16_t SX127x::readData(uint8_t* data, size_t len) {
|
|||
return(ERR_NONE);
|
||||
}
|
||||
|
||||
int16_t SX127x::setSyncWord(uint8_t syncWord) {
|
||||
// set mode to standby
|
||||
setMode(SX127X_STANDBY);
|
||||
|
||||
// write register
|
||||
return(_mod->SPIsetRegValue(SX127X_REG_SYNC_WORD, syncWord));
|
||||
}
|
||||
|
||||
int16_t SX127x::setCurrentLimit(uint8_t currentLimit) {
|
||||
// check allowed range
|
||||
if(!(((currentLimit >= 45) && (currentLimit <= 240)) || (currentLimit == 0))) {
|
||||
return(ERR_INVALID_CURRENT_LIMIT);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
||||
// set OCP limit
|
||||
uint8_t raw;
|
||||
if(currentLimit == 0) {
|
||||
// limit set to 0, disable OCP
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_OCP, SX127X_OCP_OFF, 5, 5);
|
||||
} else if(currentLimit <= 120) {
|
||||
raw = (currentLimit - 45) / 5;
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_OCP, SX127X_OCP_ON | raw, 5, 0);
|
||||
} else if(currentLimit <= 240) {
|
||||
raw = (currentLimit + 30) / 10;
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_OCP, SX127X_OCP_ON | raw, 5, 0);
|
||||
}
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX127x::setPreambleLength(uint16_t preambleLength) {
|
||||
// check allowed range
|
||||
if(preambleLength < 6) {
|
||||
return(ERR_INVALID_PREAMBLE_LENGTH);
|
||||
}
|
||||
|
||||
// set mode to standby
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
||||
// set preamble length
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PREAMBLE_MSB, (preambleLength & 0xFF00) >> 8);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PREAMBLE_LSB, preambleLength & 0x00FF);
|
||||
return(state);
|
||||
}
|
||||
|
||||
float SX127x::getFrequencyError() {
|
||||
// get raw frequency error
|
||||
uint32_t raw = _mod->SPIgetRegValue(SX127X_REG_FEI_MSB, 3, 0) << 16;
|
||||
raw |= _mod->SPIgetRegValue(SX127X_REG_FEI_MID) << 8;
|
||||
raw |= _mod->SPIgetRegValue(SX127X_REG_FEI_LSB);
|
||||
|
||||
uint32_t base = (uint32_t)2 << 23;
|
||||
float error;
|
||||
|
||||
// check the first bit
|
||||
if(raw & 0x80000) {
|
||||
// frequency error is negative
|
||||
raw = ~raw + 1;
|
||||
error = (((float)raw * (float)base)/32000000.0) * (_bw/500.0) * -1.0;
|
||||
} else {
|
||||
error = (((float)raw * (float)base)/32000000.0) * (_bw/500.0);
|
||||
}
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
int16_t SX127x::setFrequencyRaw(float newFreq) {
|
||||
// set mode to standby
|
||||
int16_t state = setMode(SX127X_STANDBY);
|
||||
|
||||
// calculate register values
|
||||
uint32_t base = 1;
|
||||
uint32_t FRF = (newFreq * (base << 19)) / 32.0;
|
||||
|
||||
// write registers
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FRF_MSB, (FRF & 0xFF0000) >> 16);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FRF_MID, (FRF & 0x00FF00) >> 8);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_FRF_LSB, FRF & 0x0000FF);
|
||||
return(state);
|
||||
}
|
||||
|
||||
int16_t SX127x::config() {
|
||||
// set mode to SLEEP
|
||||
int16_t state = setMode(SX127X_SLEEP);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// set LoRa mode
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_LORA, 7, 7);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_LORA, 7, 7);
|
||||
|
||||
// set mode to STANDBY
|
||||
state = setMode(SX127X_STANDBY);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// set overcurrent protection and LNA gain
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_OCP, SX127X_OCP_ON | SX127X_OCP_TRIM, 5, 0);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_LNA, SX127X_LNA_GAIN_1 | SX127X_LNA_BOOST_ON);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
state |= setMode(SX127X_STANDBY);
|
||||
|
||||
// turn off frequency hopping
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_HOP_PERIOD, SX127X_HOP_PERIOD_OFF);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// set default preamble length
|
||||
state = _mod->SPIsetRegValue(SX127X_REG_PREAMBLE_MSB, SX127X_PREAMBLE_LENGTH_MSB);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_PREAMBLE_LSB, SX127X_PREAMBLE_LENGTH_LSB);
|
||||
if(state != ERR_NONE) {
|
||||
return(state);
|
||||
}
|
||||
|
||||
// set mode to STANDBY
|
||||
state = setMode(SX127X_STANDBY);
|
||||
state |= _mod->SPIsetRegValue(SX127X_REG_HOP_PERIOD, SX127X_HOP_PERIOD_OFF);
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
|
|
@ -78,14 +78,12 @@
|
|||
#define SX127X_OCP_TRIM 0b00001011 // 4 0 OCP current: I_max(OCP_TRIM = 0b1011) = 100 mA
|
||||
|
||||
// SX127X_REG_LNA
|
||||
#define SX127X_LNA_GAIN_0 0b00000000 // 7 5 LNA gain setting: not used
|
||||
#define SX127X_LNA_GAIN_1 0b00100000 // 7 5 max gain
|
||||
#define SX127X_LNA_GAIN_1 0b00100000 // 7 5 LNA gain setting: max gain
|
||||
#define SX127X_LNA_GAIN_2 0b01000000 // 7 5 .
|
||||
#define SX127X_LNA_GAIN_3 0b01100000 // 7 5 .
|
||||
#define SX127X_LNA_GAIN_4 0b10000000 // 7 5 .
|
||||
#define SX127X_LNA_GAIN_5 0b10100000 // 7 5 .
|
||||
#define SX127X_LNA_GAIN_6 0b11000000 // 7 5 min gain
|
||||
#define SX127X_LNA_GAIN_7 0b11100000 // 7 5 not used
|
||||
#define SX127X_LNA_BOOST_OFF 0b00000000 // 1 0 default LNA current
|
||||
#define SX127X_LNA_BOOST_ON 0b00000011 // 1 0 150% LNA current
|
||||
|
||||
|
@ -173,7 +171,7 @@ class SX127x {
|
|||
float lastPacketSNR;
|
||||
|
||||
// basic methods
|
||||
int16_t begin(uint8_t chipVersion, uint8_t syncWord);
|
||||
int16_t begin(uint8_t chipVersion, uint8_t syncWord, uint8_t currentLimit, uint16_t preambleLength);
|
||||
int16_t transmit(String& str);
|
||||
int16_t transmit(const char* str);
|
||||
int16_t transmit(uint8_t* data, size_t len);
|
||||
|
@ -182,15 +180,22 @@ class SX127x {
|
|||
int16_t scanChannel();
|
||||
int16_t sleep();
|
||||
int16_t standby();
|
||||
int16_t listen();
|
||||
|
||||
// interrupt methods
|
||||
void setDio0Action(void (*func)(void));
|
||||
void setDio1Action(void (*func)(void));
|
||||
int16_t startTransmit(String& str);
|
||||
int16_t startTransmit(const char* str);
|
||||
int16_t startTransmit(uint8_t* data, size_t len);
|
||||
int16_t startReceive();
|
||||
int16_t readData(String& str, size_t len = 0);
|
||||
int16_t readData(uint8_t* data, size_t len);
|
||||
void onReceive(void (*func)(void));
|
||||
|
||||
// configuration methods
|
||||
int16_t setSyncWord(uint8_t syncWord);
|
||||
int16_t setCurrentLimit(uint8_t currentLimit);
|
||||
int16_t setPreambleLength(uint16_t preambleLength);
|
||||
float getFrequencyError();
|
||||
|
||||
protected:
|
||||
Module* _mod;
|
||||
|
|
Ładowanie…
Reference in New Issue