[SX127x] Reworked errata fix (#372)

This commit is contained in:
jgromes 2021-09-22 22:17:12 +02:00
parent 64faa57325
commit 498b638234
9 changed files with 112 additions and 199 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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