diff --git a/src/modules/SX127x/SX1272.cpp b/src/modules/SX127x/SX1272.cpp index 66e95cfa..cab42675 100644 --- a/src/modules/SX127x/SX1272.cpp +++ b/src/modules/SX127x/SX1272.cpp @@ -10,11 +10,6 @@ int16_t SX1272::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync int16_t state = SX127x::begin(SX1272_CHIP_VERSION, syncWord, preambleLength); RADIOLIB_ASSERT(state); - // mitigation of receiver spurious response - // see SX1272/73 Errata, section 2.2 for details - state = _mod->SPIsetRegValue(0x31, 0b10000000, 7, 7); - RADIOLIB_ASSERT(state); - // configure publicly accessible settings state = setBandwidth(bw); RADIOLIB_ASSERT(state); @@ -499,4 +494,12 @@ int16_t SX1272::configFSK() { return(state); } +void SX1272::errataFix(bool rx) { + (void)rx; + + // mitigation of receiver spurious response + // see SX1272/73 Errata, section 2.2 for details + _mod->SPIsetRegValue(0x31, 0b10000000, 7, 7); +} + #endif diff --git a/src/modules/SX127x/SX1272.h b/src/modules/SX127x/SX1272.h index 60fcf7e7..8f333e35 100644 --- a/src/modules/SX127x/SX1272.h +++ b/src/modules/SX127x/SX1272.h @@ -300,6 +300,7 @@ class SX1272: public SX127x { int16_t setHeaderType(uint8_t headerType, size_t len = 0xFF); int16_t configFSK(); + void errataFix(bool rx); #if !defined(RADIOLIB_GODMODE) private: diff --git a/src/modules/SX127x/SX1273.cpp b/src/modules/SX127x/SX1273.cpp index 6ac6a6bf..46aa680c 100644 --- a/src/modules/SX127x/SX1273.cpp +++ b/src/modules/SX127x/SX1273.cpp @@ -10,11 +10,6 @@ int16_t SX1273::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t sync int16_t state = SX127x::begin(SX1272_CHIP_VERSION, syncWord, preambleLength); RADIOLIB_ASSERT(state); - // mitigation of receiver spurious response - // see SX1272/73 Errata, section 2.2 for details - state = _mod->SPIsetRegValue(0x31, 0b10000000, 7, 7); - RADIOLIB_ASSERT(state); - // configure publicly accessible settings state = setBandwidth(bw); RADIOLIB_ASSERT(state); diff --git a/src/modules/SX127x/SX1276.cpp b/src/modules/SX127x/SX1276.cpp index e97d7ef9..8c97f447 100644 --- a/src/modules/SX127x/SX1276.cpp +++ b/src/modules/SX127x/SX1276.cpp @@ -53,69 +53,6 @@ int16_t SX1276::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t int16_t SX1276::setFrequency(float freq) { RADIOLIB_CHECK_RANGE(freq, 137.0, 1020.0, ERR_INVALID_FREQUENCY); - // SX1276/77/78 Errata fixes - if(getActiveModem() == SX127X_LORA) { - // sensitivity optimization for 500kHz bandwidth - // see SX1276/77/78 Errata, section 2.1 for details - if(fabs(_bw - 500.0) <= 0.001) { - if((freq >= 862.0) && (freq <= 1020.0)) { - _mod->SPIwriteRegister(0x36, 0x02); - _mod->SPIwriteRegister(0x3a, 0x64); - } else if((freq >= 410.0) && (freq <= 525.0)) { - _mod->SPIwriteRegister(0x36, 0x02); - _mod->SPIwriteRegister(0x3a, 0x7F); - } - } - - // mitigation of receiver spurious response - // see SX1276/77/78 Errata, section 2.3 for details - if(fabs(_bw - 7.8) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x48); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 7.8; - } else if(fabs(_bw - 10.4) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 10.4; - } else if(fabs(_bw - 15.6) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 15.6; - } else if(fabs(_bw - 20.8) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 20.8; - } else if(fabs(_bw - 31.25) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 31.25; - } else if(fabs(_bw - 41.7) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 41.7; - } else if(fabs(_bw - 62.5) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x40); - _mod->SPIsetRegValue(0x30, 0x00); - } else if(fabs(_bw - 125.0) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x40); - _mod->SPIsetRegValue(0x30, 0x00); - } else if(fabs(_bw - 250.0) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x40); - _mod->SPIsetRegValue(0x30, 0x00); - } else if(fabs(_bw - 500.0) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b1000000, 7, 7); - } - } - // set frequency and if successful, save the new setting int16_t state = SX127x::setFrequencyRaw(freq); if(state == ERR_NONE) { diff --git a/src/modules/SX127x/SX1277.cpp b/src/modules/SX127x/SX1277.cpp index 86f58d5e..a150c462 100644 --- a/src/modules/SX127x/SX1277.cpp +++ b/src/modules/SX127x/SX1277.cpp @@ -53,69 +53,6 @@ int16_t SX1277::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t int16_t SX1277::setFrequency(float freq) { RADIOLIB_CHECK_RANGE(freq, 137.0, 1020.0, ERR_INVALID_FREQUENCY); - // SX1276/77/78 Errata fixes - if(getActiveModem() == SX127X_LORA) { - // sensitivity optimization for 500kHz bandwidth - // see SX1276/77/78 Errata, section 2.1 for details - if(fabs(_bw - 500.0) <= 0.001) { - if((freq >= 862.0) && (freq <= 1020.0)) { - _mod->SPIwriteRegister(0x36, 0x02); - _mod->SPIwriteRegister(0x3a, 0x64); - } else if((freq >= 410.0) && (freq <= 525.0)) { - _mod->SPIwriteRegister(0x36, 0x02); - _mod->SPIwriteRegister(0x3a, 0x7F); - } - } - - // mitigation of receiver spurious response - // see SX1276/77/78 Errata, section 2.3 for details - if(fabs(_bw - 7.8) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x48); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 7.8; - } else if(fabs(_bw - 10.4) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 10.4; - } else if(fabs(_bw - 15.6) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 15.6; - } else if(fabs(_bw - 20.8) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 20.8; - } else if(fabs(_bw - 31.25) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 31.25; - } else if(fabs(_bw - 41.7) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 41.7; - } else if(fabs(_bw - 62.5) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x40); - _mod->SPIsetRegValue(0x30, 0x00); - } else if(fabs(_bw - 125.0) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x40); - _mod->SPIsetRegValue(0x30, 0x00); - } else if(fabs(_bw - 250.0) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x40); - _mod->SPIsetRegValue(0x30, 0x00); - } else if(fabs(_bw - 500.0) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b1000000, 7, 7); - } - } - // set frequency and if successful, save the new setting int16_t state = SX127x::setFrequencyRaw(freq); if(state == ERR_NONE) { diff --git a/src/modules/SX127x/SX1278.cpp b/src/modules/SX127x/SX1278.cpp index b309c9b8..d315dd52 100644 --- a/src/modules/SX127x/SX1278.cpp +++ b/src/modules/SX127x/SX1278.cpp @@ -70,69 +70,6 @@ void SX1278::reset() { int16_t SX1278::setFrequency(float freq) { RADIOLIB_CHECK_RANGE(freq, 137.0, 525.0, ERR_INVALID_FREQUENCY); - // SX1276/77/78 Errata fixes - if(getActiveModem() == SX127X_LORA) { - // sensitivity optimization for 500kHz bandwidth - // see SX1276/77/78 Errata, section 2.1 for details - if(fabs(_bw - 500.0) <= 0.001) { - if((freq >= 862.0) && (freq <= 1020.0)) { - _mod->SPIwriteRegister(0x36, 0x02); - _mod->SPIwriteRegister(0x3a, 0x64); - } else if((freq >= 410.0) && (freq <= 525.0)) { - _mod->SPIwriteRegister(0x36, 0x02); - _mod->SPIwriteRegister(0x3a, 0x7F); - } - } - - // mitigation of receiver spurious response - // see SX1276/77/78 Errata, section 2.3 for details - if(fabs(_bw - 7.8) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x48); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 7.8; - } else if(fabs(_bw - 10.4) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 10.4; - } else if(fabs(_bw - 15.6) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 15.6; - } else if(fabs(_bw - 20.8) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 20.8; - } else if(fabs(_bw - 31.25) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 31.25; - } else if(fabs(_bw - 41.7) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x44); - _mod->SPIsetRegValue(0x30, 0x00); - freq += 41.7; - } else if(fabs(_bw - 62.5) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x40); - _mod->SPIsetRegValue(0x30, 0x00); - } else if(fabs(_bw - 125.0) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x40); - _mod->SPIsetRegValue(0x30, 0x00); - } else if(fabs(_bw - 250.0) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b0000000, 7, 7); - _mod->SPIsetRegValue(0x2F, 0x40); - _mod->SPIsetRegValue(0x30, 0x00); - } else if(fabs(_bw - 500.0) <= 0.001) { - _mod->SPIsetRegValue(0x31, 0b1000000, 7, 7); - } - } - // set frequency and if successful, save the new setting int16_t state = SX127x::setFrequencyRaw(freq); if(state == ERR_NONE) { @@ -577,4 +514,92 @@ int16_t SX1278::configFSK() { return(state); } +void SX1278::errataFix(bool rx) { + // only apply in LoRa mode + if(getActiveModem() != SX127X_LORA) { + return; + } + + // sensitivity optimization for 500kHz bandwidth + // see SX1276/77/78 Errata, section 2.1 for details + if(fabs(_bw - 500.0) <= 0.001) { + if((_freq >= 862.0) && (_freq <= 1020.0)) { + _mod->SPIwriteRegister(0x36, 0x02); + _mod->SPIwriteRegister(0x3a, 0x64); + } else if((_freq >= 410.0) && (_freq <= 525.0)) { + _mod->SPIwriteRegister(0x36, 0x02); + _mod->SPIwriteRegister(0x3a, 0x7F); + } + } + + // mitigation of receiver spurious response + // see SX1276/77/78 Errata, section 2.3 for details + + // figure out what we need to set + uint8_t fixedRegs[3]; + float rxFreq = _freq; + if(fabs(_bw - 7.8) <= 0.001) { + fixedRegs[0] = 0b0000000; + fixedRegs[1] = 0x48; + fixedRegs[2] = 0x00; + rxFreq += 0.00781; + } else if(fabs(_bw - 10.4) <= 0.001) { + fixedRegs[0] = 0b0000000; + fixedRegs[1] = 0x44; + fixedRegs[2] = 0x00; + rxFreq += 0.01042; + } else if(fabs(_bw - 15.6) <= 0.001) { + fixedRegs[0] = 0b0000000; + fixedRegs[1] = 0x44; + fixedRegs[2] = 0x00; + rxFreq += 0.01562; + } else if(fabs(_bw - 20.8) <= 0.001) { + fixedRegs[0] = 0b0000000; + fixedRegs[1] = 0x44; + fixedRegs[2] = 0x00; + rxFreq += 0.02083; + } else if(fabs(_bw - 31.25) <= 0.001) { + fixedRegs[0] = 0b0000000; + fixedRegs[1] = 0x44; + fixedRegs[2] = 0x00; + rxFreq += 0.03125; + } else if(fabs(_bw - 41.7) <= 0.001) { + fixedRegs[0] = 0b0000000; + fixedRegs[1] = 0x44; + fixedRegs[2] = 0x00; + rxFreq += 0.04167; + } else if(fabs(_bw - 62.5) <= 0.001) { + fixedRegs[0] = 0b0000000; + fixedRegs[1] = 0x40; + fixedRegs[2] = 0x00; + } else if(fabs(_bw - 125.0) <= 0.001) { + fixedRegs[0] = 0b0000000; + fixedRegs[1] = 0x40; + fixedRegs[2] = 0x00; + } else if(fabs(_bw - 250.0) <= 0.001) { + fixedRegs[0] = 0b0000000; + fixedRegs[1] = 0x40; + fixedRegs[2] = 0x00; + } else if(fabs(_bw - 500.0) <= 0.001) { + fixedRegs[0] = 0b1000000; + fixedRegs[1] = _mod->SPIreadRegister(0x2F); + fixedRegs[2] = _mod->SPIreadRegister(0x30); + } + + // first, go to standby + standby(); + + // shift the freqency up when receiving, or restore the original when transmitting + if(rx) { + SX127x::setFrequencyRaw(rxFreq); + } else { + SX127x::setFrequencyRaw(_freq); + } + + // finally, apply errata fixes + _mod->SPIsetRegValue(0x31, fixedRegs[0], 7, 7); + _mod->SPIsetRegValue(0x2F, fixedRegs[1]); + _mod->SPIsetRegValue(0x30, fixedRegs[2]); +} + #endif diff --git a/src/modules/SX127x/SX1278.h b/src/modules/SX127x/SX1278.h index 1a68a47e..d22145cf 100644 --- a/src/modules/SX127x/SX1278.h +++ b/src/modules/SX127x/SX1278.h @@ -308,6 +308,7 @@ class SX1278: public SX127x { int16_t setHeaderType(uint8_t headerType, size_t len = 0xFF); int16_t configFSK(); + void errataFix(bool rx); #if !defined(RADIOLIB_GODMODE) private: diff --git a/src/modules/SX127x/SX127x.cpp b/src/modules/SX127x/SX127x.cpp index 2c1abbfd..e39fe48b 100644 --- a/src/modules/SX127x/SX127x.cpp +++ b/src/modules/SX127x/SX127x.cpp @@ -323,6 +323,9 @@ int16_t SX127x::transmitDirect(uint32_t frf) { int16_t state = directMode(); RADIOLIB_ASSERT(state); + // apply fixes to errata + errataFix(false); + // start transmitting return(setMode(SX127X_TX)); } @@ -340,6 +343,9 @@ int16_t SX127x::receiveDirect() { int16_t state = directMode(); RADIOLIB_ASSERT(state); + // apply fixes to errata + errataFix(true); + // start receiving return(setMode(SX127X_RX)); } @@ -381,6 +387,9 @@ int16_t SX127x::startReceive(uint8_t len, uint8_t mode) { state |= _mod->SPIsetRegValue(SX127X_REG_PAYLOAD_LENGTH, len); } + // apply fixes to errata + errataFix(true); + // clear interrupt flags clearIRQFlags(); @@ -446,6 +455,9 @@ int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) { // set DIO mapping _mod->SPIsetRegValue(SX127X_REG_DIO_MAPPING_1, SX127X_DIO0_TX_DONE, 7, 6); + // apply fixes to errata + errataFix(false); + // clear interrupt flags clearIRQFlags(); diff --git a/src/modules/SX127x/SX127x.h b/src/modules/SX127x/SX127x.h index fd9175ff..dc33ec08 100644 --- a/src/modules/SX127x/SX127x.h +++ b/src/modules/SX127x/SX127x.h @@ -1085,6 +1085,8 @@ class SX127x: public PhysicalLayer { * \returns bandwidth in manitsa and exponent format */ static uint8_t calculateBWManExp(float bandwidth); + + virtual void errataFix(bool rx) = 0; }; #endif