diff --git a/src/modules/SX1272.cpp b/src/modules/SX1272.cpp index 9877ceed..1b9d727e 100644 --- a/src/modules/SX1272.cpp +++ b/src/modules/SX1272.cpp @@ -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); } diff --git a/src/modules/SX1272.h b/src/modules/SX1272.h index 25dd9579..fc10ec85 100644 --- a/src/modules/SX1272.h +++ b/src/modules/SX1272.h @@ -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 diff --git a/src/modules/SX1273.cpp b/src/modules/SX1273.cpp index 57f71cce..01c5847e 100644 --- a/src/modules/SX1273.cpp +++ b/src/modules/SX1273.cpp @@ -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); } diff --git a/src/modules/SX1273.h b/src/modules/SX1273.h index d03b246d..93c3b5e3 100644 --- a/src/modules/SX1273.h +++ b/src/modules/SX1273.h @@ -7,9 +7,8 @@ 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 diff --git a/src/modules/SX1276.cpp b/src/modules/SX1276.cpp index 4e76645f..510da10c 100644 --- a/src/modules/SX1276.cpp +++ b/src/modules/SX1276.cpp @@ -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); } diff --git a/src/modules/SX1276.h b/src/modules/SX1276.h index d8d6a197..6b8713e5 100644 --- a/src/modules/SX1276.h +++ b/src/modules/SX1276.h @@ -7,9 +7,8 @@ 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 diff --git a/src/modules/SX1277.cpp b/src/modules/SX1277.cpp index 86ff3e51..b21dd654 100644 --- a/src/modules/SX1277.cpp +++ b/src/modules/SX1277.cpp @@ -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); } diff --git a/src/modules/SX1277.h b/src/modules/SX1277.h index a97ad783..99e8813e 100644 --- a/src/modules/SX1277.h +++ b/src/modules/SX1277.h @@ -7,9 +7,9 @@ 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 diff --git a/src/modules/SX1278.cpp b/src/modules/SX1278.cpp index d136ef12..64d7a7f0 100644 --- a/src/modules/SX1278.cpp +++ b/src/modules/SX1278.cpp @@ -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); } diff --git a/src/modules/SX1278.h b/src/modules/SX1278.h index ca71e4be..3a358a0b 100644 --- a/src/modules/SX1278.h +++ b/src/modules/SX1278.h @@ -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 + protected: + 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 diff --git a/src/modules/SX1279.cpp b/src/modules/SX1279.cpp index 745be1dc..0412f5f7 100644 --- a/src/modules/SX1279.cpp +++ b/src/modules/SX1279.cpp @@ -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); } diff --git a/src/modules/SX1279.h b/src/modules/SX1279.h index 5ccbc73b..42b81d9a 100644 --- a/src/modules/SX1279.h +++ b/src/modules/SX1279.h @@ -7,9 +7,8 @@ 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 diff --git a/src/modules/SX127x.cpp b/src/modules/SX127x.cpp index 6d5ed4d4..c66d1fa5 100644 --- a/src/modules/SX127x.cpp +++ b/src/modules/SX127x.cpp @@ -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() { diff --git a/src/modules/SX127x.h b/src/modules/SX127x.h index 7c7d8b94..5120215c 100644 --- a/src/modules/SX127x.h +++ b/src/modules/SX127x.h @@ -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};