From e3021b5a3702fbad1cc7acbcc1ef4fd5473cc0d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Grome=C5=A1?= Date: Thu, 2 Aug 2018 15:11:38 +0200 Subject: [PATCH] SX127x - Sync with LoRaLib v5.0.2 --- .../SX127x_ChannelActivityDetection.ino | 24 +- examples/SX127x_Receive/SX127x_Receive.ino | 33 ++- .../SX127x_ReceiveInterrupt.ino | 20 +- examples/SX127x_Settings/SX127x_Settings.ino | 84 ++++-- examples/SX127x_Transmit/SX127x_Transmit.ino | 23 +- .../SX127x_TransmitInterrupt.ino | 108 ++++++++ keywords.txt | 4 + src/TypeDef.h | 3 + src/modules/SX1272.cpp | 77 ++++-- src/modules/SX1272.h | 7 +- src/modules/SX1273.cpp | 54 ++++ src/modules/SX1273.h | 3 + src/modules/SX1276.cpp | 69 ++++- src/modules/SX1276.h | 3 + src/modules/SX1277.cpp | 69 ++++- src/modules/SX1277.h | 3 + src/modules/SX1278.cpp | 107 +++---- src/modules/SX1278.h | 7 +- src/modules/SX1279.cpp | 47 ++++ src/modules/SX1279.h | 3 + src/modules/SX127x.cpp | 260 ++++++++++++------ src/modules/SX127x.h | 17 +- 22 files changed, 775 insertions(+), 250 deletions(-) create mode 100644 examples/SX127x_TransmitInterrupt/SX127x_TransmitInterrupt.ino diff --git a/examples/SX127x_ChannelActivityDetection/SX127x_ChannelActivityDetection.ino b/examples/SX127x_ChannelActivityDetection/SX127x_ChannelActivityDetection.ino index fb809b9b..90835401 100644 --- a/examples/SX127x_ChannelActivityDetection/SX127x_ChannelActivityDetection.ino +++ b/examples/SX127x_ChannelActivityDetection/SX127x_ChannelActivityDetection.ino @@ -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!")); diff --git a/examples/SX127x_Receive/SX127x_Receive.ino b/examples/SX127x_Receive/SX127x_Receive.ino index e76cad0b..f7a50220 100644 --- a/examples/SX127x_Receive/SX127x_Receive.ino +++ b/examples/SX127x_Receive/SX127x_Receive.ino @@ -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!")); diff --git a/examples/SX127x_ReceiveInterrupt/SX127x_ReceiveInterrupt.ino b/examples/SX127x_ReceiveInterrupt/SX127x_ReceiveInterrupt.ino index c6f2927b..85622a4e 100644 --- a/examples/SX127x_ReceiveInterrupt/SX127x_ReceiveInterrupt.ino +++ b/examples/SX127x_ReceiveInterrupt/SX127x_ReceiveInterrupt.ino @@ -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 diff --git a/examples/SX127x_Settings/SX127x_Settings.ino b/examples/SX127x_Settings/SX127x_Settings.ino index 574b971f..3a53da12 100644 --- a/examples/SX127x_Settings/SX127x_Settings.ino +++ b/examples/SX127x_Settings/SX127x_Settings.ino @@ -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!"); } diff --git a/examples/SX127x_Transmit/SX127x_Transmit.ino b/examples/SX127x_Transmit/SX127x_Transmit.ino index 179e8d54..f5881858 100644 --- a/examples/SX127x_Transmit/SX127x_Transmit.ino +++ b/examples/SX127x_Transmit/SX127x_Transmit.ino @@ -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!"); diff --git a/examples/SX127x_TransmitInterrupt/SX127x_TransmitInterrupt.ino b/examples/SX127x_TransmitInterrupt/SX127x_TransmitInterrupt.ino new file mode 100644 index 00000000..18a49d30 --- /dev/null +++ b/examples/SX127x_TransmitInterrupt/SX127x_TransmitInterrupt.ino @@ -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 + +// 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); + } + } + +} diff --git a/keywords.txt b/keywords.txt index 7e68f4ad..5d766dce 100644 --- a/keywords.txt +++ b/keywords.txt @@ -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 diff --git a/src/TypeDef.h b/src/TypeDef.h index 3ee0b1bc..91cd2cf5 100644 --- a/src/TypeDef.h +++ b/src/TypeDef.h @@ -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 diff --git a/src/modules/SX1272.cpp b/src/modules/SX1272.cpp index e4048be8..82040d72 100644 --- a/src/modules/SX1272.cpp +++ b/src/modules/SX1272.cpp @@ -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); } diff --git a/src/modules/SX1272.h b/src/modules/SX1272.h index 5a4fe325..ffcd1074 100644 --- a/src/modules/SX1272.h +++ b/src/modules/SX1272.h @@ -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 diff --git a/src/modules/SX1273.cpp b/src/modules/SX1273.cpp index 0eaca103..a6b7a99a 100644 --- a/src/modules/SX1273.cpp +++ b/src/modules/SX1273.cpp @@ -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; diff --git a/src/modules/SX1273.h b/src/modules/SX1273.h index 69fafd58..61aff670 100644 --- a/src/modules/SX1273.h +++ b/src/modules/SX1273.h @@ -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); }; diff --git a/src/modules/SX1276.cpp b/src/modules/SX1276.cpp index 3d615e32..cf80f399 100644 --- a/src/modules/SX1276.cpp +++ b/src/modules/SX1276.cpp @@ -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); } diff --git a/src/modules/SX1276.h b/src/modules/SX1276.h index 252981ec..702335d7 100644 --- a/src/modules/SX1276.h +++ b/src/modules/SX1276.h @@ -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); }; diff --git a/src/modules/SX1277.cpp b/src/modules/SX1277.cpp index bc02716b..ce2d68c1 100644 --- a/src/modules/SX1277.cpp +++ b/src/modules/SX1277.cpp @@ -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); } diff --git a/src/modules/SX1277.h b/src/modules/SX1277.h index db085d8f..99bb8693 100644 --- a/src/modules/SX1277.h +++ b/src/modules/SX1277.h @@ -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); diff --git a/src/modules/SX1278.cpp b/src/modules/SX1278.cpp index a267c682..a171ff6a 100644 --- a/src/modules/SX1278.cpp +++ b/src/modules/SX1278.cpp @@ -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); } diff --git a/src/modules/SX1278.h b/src/modules/SX1278.h index 8f747fea..a2513a2b 100644 --- a/src/modules/SX1278.h +++ b/src/modules/SX1278.h @@ -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 diff --git a/src/modules/SX1279.cpp b/src/modules/SX1279.cpp index c493f534..5e7fd2ea 100644 --- a/src/modules/SX1279.cpp +++ b/src/modules/SX1279.cpp @@ -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)) { diff --git a/src/modules/SX1279.h b/src/modules/SX1279.h index 22db6d47..a49fb8db 100644 --- a/src/modules/SX1279.h +++ b/src/modules/SX1279.h @@ -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); }; diff --git a/src/modules/SX127x.cpp b/src/modules/SX127x.cpp index cbdb598a..6aa2f735 100644 --- a/src/modules/SX127x.cpp +++ b/src/modules/SX127x.cpp @@ -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); } diff --git a/src/modules/SX127x.h b/src/modules/SX127x.h index e2d3d272..f3427bc4 100644 --- a/src/modules/SX127x.h +++ b/src/modules/SX127x.h @@ -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;