SX127x - Sync with LoRaLib v5.0.2

pull/1/head
Jan Gromeš 2018-08-02 15:11:38 +02:00
rodzic 0ca15ac41f
commit e3021b5a37
22 zmienionych plików z 775 dodań i 250 usunięć

Wyświetl plik

@ -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!"));

Wyświetl plik

@ -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!"));

Wyświetl plik

@ -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

Wyświetl plik

@ -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!");
}

Wyświetl plik

@ -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!");

Wyświetl plik

@ -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);
}
}
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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);
};

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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);
};

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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)) {

Wyświetl plik

@ -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);
};

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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;