SX127x - Synced code with LoRaLib 2.0.0

This commit is contained in:
Jan Gromeš 2018-07-06 15:45:40 +02:00
parent 5c1e12e310
commit 5335280288
14 changed files with 408 additions and 530 deletions

View file

@ -4,66 +4,82 @@ SX1272::SX1272(Module* mod) : SX127x(mod) {
}
uint8_t SX1272::begin(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t addrEeprom) {
uint8_t state = SX127x::begin(freq, bw, sf, cr, syncWord, addrEeprom);
uint8_t SX1272::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t addrEeprom) {
// execute common part
uint8_t state = SX127x::begin(syncWord, power, addrEeprom);
if(state != ERR_NONE) {
return(state);
}
return(config(freq, bw, sf, cr, syncWord));
// 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);
}
return(ERR_NONE);
}
uint8_t SX1272::setBandwidth(uint32_t bw) {
uint8_t state = SX1272::config(bw, _sf, _cr, _freq, _syncWord);
if(state == ERR_NONE) {
_bw = bw;
uint8_t SX1272::setFrequency(float freq) {
// check frequency range
if((freq < 860.0) || (freq > 1020.0)) {
return(ERR_INVALID_FREQUENCY);
}
uint8_t state = SX1272::setFrequencyRaw(freq);
if(state == ERR_NONE) {
SX127x::_freq = freq;
}
return(state);
}
uint8_t SX1272::setBandwidth(float bw) {
uint8_t newBandwidth;
// check alowed bandwidth values
if(bw == 125.0) {
newBandwidth = SX1272_BW_125_00_KHZ;
} else if(bw == 250.0) {
newBandwidth = SX1272_BW_250_00_KHZ;
} else if(bw == 500.0) {
newBandwidth = SX1272_BW_500_00_KHZ;
} else {
return(ERR_INVALID_BANDWIDTH);
}
uint8_t state = SX1272::setBandwidthRaw(newBandwidth);
if(state == ERR_NONE) {
SX127x::_bw = bw;
}
return(state);
}
uint8_t SX1272::setSpreadingFactor(uint8_t sf) {
uint8_t state = SX1272::config(_bw, sf, _cr, _freq, _syncWord);
if(state == ERR_NONE) {
_sf = sf;
}
return(state);
}
uint8_t SX1272::setCodingRate(uint8_t cr) {
uint8_t state = SX1272::config(_bw, _sf, cr, _freq, _syncWord);
if(state == ERR_NONE) {
_cr = cr;
}
return(state);
}
uint8_t SX1272::setFrequency(float freq) {
uint8_t state = SX1272::config(_bw, _sf, _cr, freq, _syncWord);
if(state == ERR_NONE) {
_freq = freq;
}
return(state);
}
uint8_t SX1272::config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord) {
uint8_t status = ERR_NONE;
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
// check the supplied BW, CR and SF values
switch(bw) {
case 125000:
newBandwidth = SX1272_BW_125_00_KHZ;
break;
case 250000:
newBandwidth = SX1272_BW_250_00_KHZ;
break;
case 500000:
newBandwidth = SX1272_BW_500_00_KHZ;
break;
default:
return(ERR_INVALID_BANDWIDTH);
}
uint8_t newSpreadingFactor;
// check allowed spreading factor values
switch(sf) {
case 6:
newSpreadingFactor = SX127X_SF_6;
@ -90,6 +106,18 @@ uint8_t SX1272::config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t
return(ERR_INVALID_SPREADING_FACTOR);
}
uint8_t state = SX1272::setSpreadingFactorRaw(newSpreadingFactor);
if(state == ERR_NONE) {
SX127x::_sf = sf;
}
return(state);
}
uint8_t SX1272::setCodingRate(uint8_t cr) {
uint8_t newCodingRate;
// check allowed coding rate values
switch(cr) {
case 5:
newCodingRate = SX1272_CR_4_5;
@ -107,65 +135,78 @@ uint8_t SX1272::config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t
return(ERR_INVALID_CODING_RATE);
}
if((freq < 137.0) || (freq > 525.0)) {
return(ERR_INVALID_FREQUENCY);
uint8_t state = SX1272::setCodingRateRaw(newCodingRate);
if(state == ERR_NONE) {
SX127x::_cr = cr;
}
// execute common part
status = SX1272::configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
if(status != ERR_NONE) {
return(status);
}
// configuration successful, save the new settings
_bw = bw;
_sf = sf;
_cr = cr;
_freq = freq;
return(ERR_NONE);
return(state);
}
uint8_t SX1272::configCommon(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
uint8_t SX1272::setBandwidthRaw(uint8_t newBandwidth) {
// set mode to standby
SX127x::standby();
// write register
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newBandwidth, 7, 6));
}
uint8_t SX1272::setSpreadingFactorRaw(uint8_t newSpreadingFactor) {
// set mode to standby
SX127x::standby();
// write registers
uint8_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);
state |= _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_6, 2, 0);
state |= _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_6);
} else {
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_HEADER_EXPL_MODE | SX1272_RX_CRC_MODE_ON, 2, 1);
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, newSpreadingFactor | SX127X_TX_MODE_SINGLE, 7, 3);
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);
}
uint8_t SX1272::setCodingRateRaw(uint8_t newCodingRate) {
// set mode to standby
SX127x::standby();
// write register
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newCodingRate, 5, 3));
}
uint8_t SX1272::config() {
// configure common registers
uint8_t status = SX127x::config(bw, sf, cr, freq, syncWord);
if(status != ERR_NONE) {
return(status);
uint8_t state = SX127x::config();
if(state != ERR_NONE) {
return(state);
}
// output power configuration
status = _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0);
if(status != ERR_NONE) {
return(status);
state = _mod->SPIsetRegValue(SX1272_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0);
if(state != ERR_NONE) {
return(state);
}
// enable LNA gain setting by register
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1272_AGC_AUTO_OFF, 2, 2);
if(status != ERR_NONE) {
return(status);
}
// set SF6 optimizations
if(sf == SX127X_SF_6) {
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, bw | cr | SX1272_HEADER_IMPL_MODE | SX1272_RX_CRC_MODE_OFF, 7, 1);
} else {
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, bw | cr | SX1272_HEADER_EXPL_MODE | SX1272_RX_CRC_MODE_ON, 7, 1);
}
if(status != ERR_NONE) {
return(status);
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;
if(symbolLength >= 0.016) {
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_ON, 0, 0);
state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_ON, 0, 0);
} else {
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0);
}
if(status != ERR_NONE) {
return(status);
state = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1272_LOW_DATA_RATE_OPT_OFF, 0, 0);
}
return(status);
return(state);
}

View file

@ -47,19 +47,20 @@ class SX1272: public SX127x {
public:
SX1272(Module* mod);
uint8_t begin(float freq = 434.0, uint32_t bw = 125000, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = SX127X_SYNC_WORD, uint16_t addrEeprom = 0);
uint8_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, uint16_t addrEeprom = 0);
uint8_t setBandwidth(uint32_t bw);
uint8_t setFrequency(float freq);
uint8_t setBandwidth(float bw);
uint8_t setSpreadingFactor(uint8_t sf);
uint8_t setCodingRate(uint8_t cr);
uint8_t setFrequency(float freq);
protected:
uint8_t configCommon(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord); // common for SX1272/73
uint8_t setBandwidthRaw(uint8_t newBandwidth);
uint8_t setSpreadingFactorRaw(uint8_t newSpreadingFactor);
uint8_t setCodingRateRaw(uint8_t newCodingRate);
private:
uint8_t config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord); // specific to SX1272
uint8_t config();
};
#endif

View file

@ -4,25 +4,10 @@ SX1273::SX1273(Module* mod) : SX1272(mod) {
}
uint8_t SX1273::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
uint8_t status = ERR_NONE;
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
// check the supplied BW, CR and SF values
switch(bw) {
case 125000:
newBandwidth = SX1272_BW_125_00_KHZ;
break;
case 250000:
newBandwidth = SX1272_BW_250_00_KHZ;
break;
case 500000:
newBandwidth = SX1272_BW_500_00_KHZ;
break;
default:
return(ERR_INVALID_BANDWIDTH);
}
uint8_t SX1273::setSpreadingFactor(uint8_t sf) {
uint8_t newSpreadingFactor;
// check allowed spreading factor values
switch(sf) {
case 6:
newSpreadingFactor = SX127X_SF_6;
@ -40,37 +25,10 @@ uint8_t SX1273::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t
return(ERR_INVALID_SPREADING_FACTOR);
}
switch(cr) {
case 5:
newCodingRate = SX1272_CR_4_5;
break;
case 6:
newCodingRate = SX1272_CR_4_6;
break;
case 7:
newCodingRate = SX1272_CR_4_7;
break;
case 8:
newCodingRate = SX1272_CR_4_8;
break;
default:
return(ERR_INVALID_CODING_RATE);
uint8_t state = setSpreadingFactorRaw(newSpreadingFactor);
if(state == ERR_NONE) {
SX127x::_sf = sf;
}
if((freq < 860.0) || (freq > 1020.0)) {
return(ERR_INVALID_FREQUENCY);
}
// execute common part
status = configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
if(status != ERR_NONE) {
return(status);
}
// configuration successful, save the new settings
_bw = bw;
_sf = sf;
_cr = cr;
return(ERR_NONE);
return(state);
}

View file

@ -8,8 +8,7 @@ class SX1273: public SX1272 {
public:
SX1273(Module* mod);
private:
uint8_t config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
uint8_t setSpreadingFactor(uint8_t sf);
};
#endif

View file

@ -4,82 +4,15 @@ SX1276::SX1276(Module* mod) : SX1278(mod) {
}
uint8_t SX1276::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
uint8_t status = ERR_NONE;
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
// check the supplied BW, CR and SF values
switch(bw) {
case 125000:
newBandwidth = SX1278_BW_125_00_KHZ;
break;
case 250000:
newBandwidth = SX1278_BW_250_00_KHZ;
break;
case 500000:
newBandwidth = SX1278_BW_500_00_KHZ;
break;
default:
return(ERR_INVALID_BANDWIDTH);
}
switch(sf) {
case 6:
newSpreadingFactor = SX127X_SF_6;
break;
case 7:
newSpreadingFactor = SX127X_SF_7;
break;
case 8:
newSpreadingFactor = SX127X_SF_8;
break;
case 9:
newSpreadingFactor = SX127X_SF_9;
break;
case 10:
newSpreadingFactor = SX127X_SF_10;
break;
case 11:
newSpreadingFactor = SX127X_SF_11;
break;
case 12:
newSpreadingFactor = SX127X_SF_12;
break;
default:
return(ERR_INVALID_SPREADING_FACTOR);
}
switch(cr) {
case 5:
newCodingRate = SX1278_CR_4_5;
break;
case 6:
newCodingRate = SX1278_CR_4_6;
break;
case 7:
newCodingRate = SX1278_CR_4_7;
break;
case 8:
newCodingRate = SX1278_CR_4_8;
break;
default:
return(ERR_INVALID_CODING_RATE);
}
uint8_t SX1276::setFrequency(float freq) {
// check frequency range
if((freq < 137.0) || (freq > 1020.0)) {
return(ERR_INVALID_FREQUENCY);
}
// execute common part
status = configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
if(status != ERR_NONE) {
return(status);
uint8_t state = SX1278::setFrequencyRaw(freq);
if(state == ERR_NONE) {
SX127x::_freq = freq;
}
// configuration successful, save the new settings
_bw = bw;
_sf = sf;
_cr = cr;
return(ERR_NONE);
return(state);
}

View file

@ -8,8 +8,7 @@ class SX1276: public SX1278 {
public:
SX1276(Module* mod);
private:
uint8_t config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
uint8_t setFrequency(float freq);
};
#endif

View file

@ -4,25 +4,23 @@ SX1277::SX1277(Module* mod) : SX1278(mod) {
}
uint8_t SX1277::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
uint8_t status = ERR_NONE;
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
// check the supplied BW, CR and SF values
switch(bw) {
case 125000:
newBandwidth = SX1278_BW_125_00_KHZ;
break;
case 250000:
newBandwidth = SX1278_BW_250_00_KHZ;
break;
case 500000:
newBandwidth = SX1278_BW_500_00_KHZ;
break;
default:
return(ERR_INVALID_BANDWIDTH);
uint8_t SX1277::setFrequency(float freq) {
// check frequency range
if((freq < 137.0) || (freq > 1020.0)) {
return(ERR_INVALID_FREQUENCY);
}
uint8_t state = SX1278::setFrequencyRaw(freq);
if(state == ERR_NONE) {
SX127x::_freq = freq;
}
return(state);
}
uint8_t SX1277::setSpreadingFactor(uint8_t sf) {
uint8_t newSpreadingFactor;
// check allowed spreading factor values
switch(sf) {
case 6:
newSpreadingFactor = SX127X_SF_6;
@ -40,37 +38,10 @@ uint8_t SX1277::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t
return(ERR_INVALID_SPREADING_FACTOR);
}
switch(cr) {
case 5:
newCodingRate = SX1278_CR_4_5;
break;
case 6:
newCodingRate = SX1278_CR_4_6;
break;
case 7:
newCodingRate = SX1278_CR_4_7;
break;
case 8:
newCodingRate = SX1278_CR_4_8;
break;
default:
return(ERR_INVALID_CODING_RATE);
uint8_t state = SX1278::setSpreadingFactorRaw(newSpreadingFactor);
if(state == ERR_NONE) {
SX127x::_sf = sf;
}
if((freq < 137.0) || (freq > 1020.0)) {
return(ERR_INVALID_FREQUENCY);
}
// execute common part
status = configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
if(status != ERR_NONE) {
return(status);
}
// configuration successful, save the new settings
_bw = bw;
_sf = sf;
_cr = cr;
return(ERR_NONE);
return(state);
}

View file

@ -8,8 +8,8 @@ class SX1277: public SX1278 {
public:
SX1277(Module* mod);
private:
uint8_t config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
uint8_t setFrequency(float freq);
uint8_t setSpreadingFactor(uint8_t sf);
};
#endif

View file

@ -4,87 +4,94 @@ SX1278::SX1278(Module* mod) : SX127x(mod) {
}
uint8_t SX1278::begin(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t addrEeprom) {
uint8_t state = SX127x::begin(freq, bw, sf, cr, syncWord, addrEeprom);
uint8_t SX1278::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t addrEeprom) {
// execute common part
uint8_t state = SX127x::begin(syncWord, power, addrEeprom);
if(state != ERR_NONE) {
return(state);
}
return(config(freq, bw, sf, cr, syncWord));
// 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);
}
return(ERR_NONE);
}
uint8_t SX1278::setBandwidth(uint32_t bw) {
uint8_t state = SX1278::config(bw, _sf, _cr, _freq, _syncWord);
if(state == ERR_NONE) {
_bw = bw;
uint8_t SX1278::setFrequency(float freq) {
// check frequency range
if((freq < 137.0) || (freq > 525.0)) {
return(ERR_INVALID_FREQUENCY);
}
uint8_t state = SX1278::setFrequencyRaw(freq);
if(state == ERR_NONE) {
SX127x::_freq = freq;
}
return(state);
}
uint8_t SX1278::setBandwidth(float bw) {
uint8_t newBandwidth;
// check alowed bandwidth values
if(bw == 7.8) {
newBandwidth = SX1278_BW_7_80_KHZ;
} else if(bw == 10.4) {
newBandwidth = SX1278_BW_10_40_KHZ;
} else if(bw == 15.6) {
newBandwidth = SX1278_BW_15_60_KHZ;
} else if(bw == 20.8) {
newBandwidth = SX1278_BW_20_80_KHZ;
} else if(bw == 31.25) {
newBandwidth = SX1278_BW_31_25_KHZ;
} else if(bw == 62.5) {
newBandwidth = SX1278_BW_62_50_KHZ;
} else if(bw == 125.0) {
newBandwidth = SX1278_BW_125_00_KHZ;
} else if(bw == 250.0) {
newBandwidth = SX1278_BW_250_00_KHZ;
} else if(bw == 500.0) {
newBandwidth = SX1278_BW_500_00_KHZ;
} else {
return(ERR_INVALID_BANDWIDTH);
}
uint8_t state = SX1278::setBandwidthRaw(newBandwidth);
if(state == ERR_NONE) {
SX127x::_bw = bw;
}
return(state);
}
uint8_t SX1278::setSpreadingFactor(uint8_t sf) {
uint8_t state = SX1278::config(_bw, sf, _cr, _freq, _syncWord);
if(state == ERR_NONE) {
_sf = sf;
}
return(state);
}
uint8_t SX1278::setCodingRate(uint8_t cr) {
uint8_t state = SX1278::config(_bw, _sf, cr, _freq, _syncWord);
if(state == ERR_NONE) {
_cr = cr;
}
return(state);
}
uint8_t SX1278::setFrequency(float freq) {
uint8_t state = SX1278::config(_bw, _sf, _cr, freq, _syncWord);
if(state == ERR_NONE) {
_freq = freq;
}
return(state);
}
uint8_t SX1278::config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord) {
uint8_t status = ERR_NONE;
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
// check the supplied BW, CR and SF values
switch(bw) {
case 7800:
newBandwidth = SX1278_BW_7_80_KHZ;
break;
case 10400:
newBandwidth = SX1278_BW_10_40_KHZ;
break;
case 15600:
newBandwidth = SX1278_BW_15_60_KHZ;
break;
case 20800:
newBandwidth = SX1278_BW_20_80_KHZ;
break;
case 31250:
newBandwidth = SX1278_BW_31_25_KHZ;
break;
case 41700:
newBandwidth = SX1278_BW_41_70_KHZ;
break;
case 62500:
newBandwidth = SX1278_BW_62_50_KHZ;
break;
case 125000:
newBandwidth = SX1278_BW_125_00_KHZ;
break;
case 250000:
newBandwidth = SX1278_BW_250_00_KHZ;
break;
case 500000:
newBandwidth = SX1278_BW_500_00_KHZ;
break;
default:
return(ERR_INVALID_BANDWIDTH);
}
uint8_t newSpreadingFactor;
// check allowed spreading factor values
switch(sf) {
case 6:
newSpreadingFactor = SX127X_SF_6;
@ -111,6 +118,18 @@ uint8_t SX1278::config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t
return(ERR_INVALID_SPREADING_FACTOR);
}
uint8_t state = SX1278::setSpreadingFactorRaw(newSpreadingFactor);
if(state == ERR_NONE) {
SX127x::_sf = sf;
}
return(state);
}
uint8_t SX1278::setCodingRate(uint8_t cr) {
uint8_t newCodingRate;
// check allowed coding rate values
switch(cr) {
case 5:
newCodingRate = SX1278_CR_4_5;
@ -128,65 +147,79 @@ uint8_t SX1278::config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t
return(ERR_INVALID_CODING_RATE);
}
if((freq < 137.0) || (freq > 525.0)) {
return(ERR_INVALID_FREQUENCY);
uint8_t state = SX1278::setCodingRateRaw(newCodingRate);
if(state == ERR_NONE) {
SX127x::_cr = cr;
}
// execute common part
status = SX1278::configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
if(status != ERR_NONE) {
return(status);
}
// configuration successful, save the new settings
_bw = bw;
_sf = sf;
_cr = cr;
_freq = freq;
return(ERR_NONE);
return(state);
}
uint8_t SX1278::configCommon(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
uint8_t SX1278::setBandwidthRaw(uint8_t newBandwidth) {
// set mode to standby
SX127x::standby();
// write register
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newBandwidth, 7, 4));
}
uint8_t SX1278::setSpreadingFactorRaw(uint8_t newSpreadingFactor) {
// set mode to standby
SX127x::standby();
// write registers
uint8_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);
state |= _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_6, 2, 0);
state |= _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_6);
} else {
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, SX1278_HEADER_EXPL_MODE, 0, 0);
state |= _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, newSpreadingFactor | SX127X_TX_MODE_SINGLE | SX1278_RX_CRC_MODE_OFF, 7, 2);
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);
}
uint8_t SX1278::setCodingRateRaw(uint8_t newCodingRate) {
// set mode to standby
SX127x::standby();
// write register
return(_mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, newCodingRate, 3, 1));
}
uint8_t SX1278::config() {
// configure common registers
uint8_t status = SX127x::config(bw, sf, cr, freq, syncWord);
if(status != ERR_NONE) {
return(status);
uint8_t state = SX127x::config();
if(state != ERR_NONE) {
return(state);
}
// output power configuration
status = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_MAX_POWER, 6, 4);
status = _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0);
if(status != ERR_NONE) {
return(status);
state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX1278_MAX_POWER, 6, 4);
state |= _mod->SPIsetRegValue(SX1278_REG_PA_DAC, SX127X_PA_BOOST_ON, 2, 0);
if(state != ERR_NONE) {
return(state);
}
// enable LNA gain setting by register
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_AGC_AUTO_OFF, 2, 2);
if(status != ERR_NONE) {
return(status);
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;
if(symbolLength >= 0.016) {
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_ON, 0, 0);
state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_ON, 0, 0);
} else {
status = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 0, 0);
}
if(status != ERR_NONE) {
return(status);
state = _mod->SPIsetRegValue(SX1278_REG_MODEM_CONFIG_3, SX1278_LOW_DATA_RATE_OPT_OFF, 0, 0);
}
// set SF6 optimizations
if(sf == SX127X_SF_6) {
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1278_RX_CRC_MODE_OFF, 2, 2);
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, bw | cr | SX1278_HEADER_IMPL_MODE);
} else {
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX1278_RX_CRC_MODE_ON, 2, 2);
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_1, bw | cr | SX1278_HEADER_EXPL_MODE);
}
return(status);
return(state);
}

View file

@ -64,18 +64,20 @@ class SX1278: public SX127x {
public:
SX1278(Module* mod);
uint8_t begin(float freq = 434.0, uint32_t bw = 125000, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = SX127X_SYNC_WORD, uint16_t addrEeprom = 0);
uint8_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, uint16_t addrEeprom = 0);
uint8_t setBandwidth(uint32_t bw);
uint8_t setFrequency(float freq);
uint8_t setBandwidth(float bw);
uint8_t setSpreadingFactor(uint8_t sf);
uint8_t setCodingRate(uint8_t cr);
uint8_t setFrequency(float freq);
protected:
uint8_t configCommon(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord); // common for SX1276/77/78/79
uint8_t setBandwidthRaw(uint8_t newBandwidth);
uint8_t setSpreadingFactorRaw(uint8_t newSpreadingFactor);
uint8_t setCodingRateRaw(uint8_t newCodingRate);
private:
uint8_t config(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord); // specific to SX1278
uint8_t config();
};
#endif

View file

@ -4,73 +4,15 @@ SX1279::SX1279(Module* mod) : SX1278(mod) {
}
uint8_t SX1279::config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
uint8_t status = ERR_NONE;
uint8_t newBandwidth, newSpreadingFactor, newCodingRate;
// check the supplied BW, CR and SF values
switch(bw) {
case 125000:
newBandwidth = SX1278_BW_125_00_KHZ;
break;
case 250000:
newBandwidth = SX1278_BW_250_00_KHZ;
break;
case 500000:
newBandwidth = SX1278_BW_500_00_KHZ;
break;
default:
return(ERR_INVALID_BANDWIDTH);
}
switch(sf) {
case 6:
newSpreadingFactor = SX127X_SF_6;
break;
case 7:
newSpreadingFactor = SX127X_SF_7;
break;
case 8:
newSpreadingFactor = SX127X_SF_8;
break;
case 9:
newSpreadingFactor = SX127X_SF_9;
break;
default:
return(ERR_INVALID_SPREADING_FACTOR);
}
switch(cr) {
case 5:
newCodingRate = SX1278_CR_4_5;
break;
case 6:
newCodingRate = SX1278_CR_4_6;
break;
case 7:
newCodingRate = SX1278_CR_4_7;
break;
case 8:
newCodingRate = SX1278_CR_4_8;
break;
default:
return(ERR_INVALID_CODING_RATE);
}
uint8_t SX1279::setFrequency(float freq) {
// check frequency range
if((freq < 137.0) || (freq > 960.0)) {
return(ERR_INVALID_FREQUENCY);
}
// execute common part
status = configCommon(newBandwidth, newSpreadingFactor, newCodingRate, freq, syncWord);
if(status != ERR_NONE) {
return(status);
uint8_t state = SX1278::setFrequencyRaw(freq);
if(state == ERR_NONE) {
SX127x::_freq = freq;
}
// configuration successful, save the new settings
_bw = bw;
_sf = sf;
_cr = cr;
return(ERR_NONE);
return(state);
}

View file

@ -8,8 +8,7 @@ class SX1279: public SX1278 {
public:
SX1279(Module* mod);
private:
uint8_t config(uint32_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
uint8_t setFrequency(float freq);
};
#endif

View file

@ -4,14 +4,7 @@ SX127x::SX127x(Module* mod) {
_mod = mod;
}
uint8_t SX127x::begin(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t addrEeprom) {
// copy LoRa modem settings
_freq = freq;
_bw = bw;
_sf = sf;
_cr = cr;
_syncWord = syncWord;
uint8_t SX127x::begin(uint8_t syncWord, int8_t power, uint16_t addrEeprom) {
// ESP32-only: initialize EEPROM
#ifdef ESP32
if(!EEPROM.begin(9)) {
@ -82,9 +75,22 @@ uint8_t SX127x::begin(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t s
SPI.end();
return(ERR_CHIP_NOT_FOUND);
} else {
DEBUG_PRINTLN_STR("Found SX127x! (match by SX127X_REG_VERSION == 0x12)");
DEBUG_PRINTLN_STR("Found SX127x!");
}
// set LoRa sync word
uint8_t state = SX127x::setSyncWord(syncWord);
if(state != ERR_NONE) {
return(state);
}
// set output power
state = SX127x::setOutputPower(power);
if(state != ERR_NONE) {
return(state);
}
return(ERR_NONE);
}
@ -124,8 +130,8 @@ uint8_t SX127x::transmit(Packet& pack) {
_mod->SPIsetRegValue(SX127X_REG_FIFO_ADDR_PTR, SX127X_FIFO_TX_BASE_ADDR_MAX);
// write packet to FIFO
_mod->SPIwriteRegisterBurstStr(SX127X_REG_FIFO, pack.source, 8);
_mod->SPIwriteRegisterBurstStr(SX127X_REG_FIFO, pack.destination, 8);
_mod->SPIwriteRegisterBurstStr(SX127X_REG_FIFO, (char*)pack.source, 8);
_mod->SPIwriteRegisterBurstStr(SX127X_REG_FIFO, (char*)pack.destination, 8);
_mod->SPIwriteRegisterBurstStr(SX127X_REG_FIFO, pack.data, pack.length - 16);
// start transmission
@ -184,8 +190,8 @@ uint8_t SX127x::receive(Packet& pack) {
}
// read packet addresses
_mod->SPIreadRegisterBurstStr(SX127X_REG_FIFO, 8, pack.source);
_mod->SPIreadRegisterBurstStr(SX127X_REG_FIFO, 8, pack.destination);
_mod->SPIreadRegisterBurstStr(SX127X_REG_FIFO, 8, (char*)pack.source);
_mod->SPIreadRegisterBurstStr(SX127X_REG_FIFO, 8, (char*)pack.destination);
// read packet data
delete[] pack.data;
@ -233,10 +239,13 @@ uint8_t SX127x::standby() {
}
uint8_t SX127x::setSyncWord(uint8_t syncWord) {
uint8_t state = SX127x::config(_bw, _sf, _cr, _freq, syncWord);
setMode(SX127X_STANDBY);
uint8_t state = _mod->SPIsetRegValue(SX127X_REG_SYNC_WORD, syncWord);
if(state == ERR_NONE) {
_syncWord = syncWord;
}
return(state);
}
@ -247,79 +256,67 @@ uint8_t SX127x::setOutputPower(int8_t power) {
return(ERR_INVALID_OUTPUT_POWER);
}
return(_mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, power - 2, 3, 0));
uint8_t state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, power - 2, 3, 0);
if(state == ERR_NONE) {
_power = power;
}
return(state);
}
uint8_t SX127x::config(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord) {
uint8_t status = ERR_NONE;
uint8_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
uint8_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);
}
uint8_t SX127x::config() {
// set mode to SLEEP
status = setMode(SX127X_SLEEP);
if(status != ERR_NONE) {
return(status);
uint8_t state = setMode(SX127X_SLEEP);
if(state != ERR_NONE) {
return(state);
}
// set LoRa mode
status = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_LORA, 7, 7);
if(status != ERR_NONE) {
return(status);
}
// set carrier frequency
uint32_t base = 1;
uint32_t FRF = (freq * (base << 19)) / 32.0;
status = _mod->SPIsetRegValue(SX127X_REG_FRF_MSB, (FRF & 0xFF0000) >> 16);
status = _mod->SPIsetRegValue(SX127X_REG_FRF_MID, (FRF & 0x00FF00) >> 8);
status = _mod->SPIsetRegValue(SX127X_REG_FRF_LSB, FRF & 0x0000FF);
if(status != ERR_NONE) {
return(status);
state = _mod->SPIsetRegValue(SX127X_REG_OP_MODE, SX127X_LORA, 7, 7);
if(state != ERR_NONE) {
return(state);
}
// output power configuration
status = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST | SX127X_OUTPUT_POWER);
status = _mod->SPIsetRegValue(SX127X_REG_OCP, SX127X_OCP_ON | SX127X_OCP_TRIM, 5, 0);
status = _mod->SPIsetRegValue(SX127X_REG_LNA, SX127X_LNA_GAIN_1 | SX127X_LNA_BOOST_ON);
if(status != ERR_NONE) {
return(status);
state = _mod->SPIsetRegValue(SX127X_REG_PA_CONFIG, SX127X_PA_SELECT_BOOST | SX127X_OUTPUT_POWER);
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);
}
// turn off frequency hopping
status = _mod->SPIsetRegValue(SX127X_REG_HOP_PERIOD, SX127X_HOP_PERIOD_OFF);
if(status != ERR_NONE) {
return(status);
}
// basic setting (bw, cr, sf, header mode and CRC)
if(sf == SX127X_SF_6) {
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, SX127X_SF_6 | SX127X_TX_MODE_SINGLE, 7, 3);
status = _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_6, 2, 0);
status = _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_6);
} else {
status = _mod->SPIsetRegValue(SX127X_REG_MODEM_CONFIG_2, sf | SX127X_TX_MODE_SINGLE, 7, 3);
status = _mod->SPIsetRegValue(SX127X_REG_DETECT_OPTIMIZE, SX127X_DETECT_OPTIMIZE_SF_7_12, 2, 0);
status = _mod->SPIsetRegValue(SX127X_REG_DETECTION_THRESHOLD, SX127X_DETECTION_THRESHOLD_SF_7_12);
}
if(status != ERR_NONE) {
return(status);
}
// set the sync word
status = _mod->SPIsetRegValue(SX127X_REG_SYNC_WORD, syncWord);
if(status != ERR_NONE) {
return(status);
state = _mod->SPIsetRegValue(SX127X_REG_HOP_PERIOD, SX127X_HOP_PERIOD_OFF);
if(state != ERR_NONE) {
return(state);
}
// set default preamble length
status = _mod->SPIsetRegValue(SX127X_REG_PREAMBLE_MSB, SX127X_PREAMBLE_LENGTH_MSB);
status = _mod->SPIsetRegValue(SX127X_REG_PREAMBLE_LSB, SX127X_PREAMBLE_LENGTH_LSB);
if(status != ERR_NONE) {
return(status);
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
status = setMode(SX127X_STANDBY);
return(status);
state = setMode(SX127X_STANDBY);
return(state);
}
void SX127x::generateNodeAdress() {

View file

@ -173,7 +173,7 @@ class SX127x {
int8_t lastPacketRSSI;
float lastPacketSNR;
uint8_t begin(float freq, uint32_t bw, uint8_t sf, uint8_t cr, uint8_t syncWord, uint16_t addrEeprom);
uint8_t begin(uint8_t syncWord, int8_t power, uint16_t addrEeprom);
uint8_t transmit(Packet& pack);
uint8_t receive(Packet& pack);
uint8_t scanChannel();
@ -187,16 +187,19 @@ class SX127x {
protected:
Module* _mod;
uint32_t _bw;
float _freq;
float _bw;
uint8_t _sf;
uint8_t _cr;
float _freq;
uint8_t _syncWord;
int8_t _power;
uint8_t tx(char* data, uint8_t length);
uint8_t rxSingle(char* data, uint8_t* length);
uint8_t config(uint8_t bw, uint8_t sf, uint8_t cr, float freq, uint8_t syncWord);
uint8_t setFrequencyRaw(float newFreq);
uint8_t config();
private:
uint8_t _address[8] = {0, 0, 0, 0, 0, 0, 0, 0};