Merge pull request #481 from JasonRJ/master

Add method to support SX128x Frequency Error of last received LoRa or…
This commit is contained in:
Jan Gromeš 2022-02-28 18:42:45 +01:00 committed by GitHub
commit 84c086eeac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 0 deletions

View file

@ -85,6 +85,12 @@ void loop() {
Serial.print(radio.getSNR());
Serial.println(F(" dB"));
// print the Frequency Error
// of the last received packet
Serial.print(F("[SX1280] Frequency Error:\t"));
Serial.print(radio.getFrequencyError());
Serial.println(F(" Hz"));
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));

View file

@ -136,6 +136,12 @@ void loop() {
Serial.print(radio.getSNR());
Serial.println(F(" dB"));
// print the Frequency Error
// of the last received packet
Serial.print(F("[SX1280] Frequency Error:\t"));
Serial.print(radio.getFrequencyError());
Serial.println(F(" Hz"));
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));

View file

@ -1020,6 +1020,54 @@ int16_t SX128x::setAccessAddress(uint32_t addr) {
return(SX128x::writeRegister(RADIOLIB_SX128X_REG_ACCESS_ADDRESS_BYTE_3, addrBuff, 4));
}
int16_t SX128x::setHighSensitivityMode(bool hsm) {
// update register
uint8_t RxGain = 0;
int16_t state = readRegister(RADIOLIB_SX128X_REG_GAIN_MODE, &RxGain, 1);
RADIOLIB_ASSERT(state);
if (hsm) {
RxGain |= 0xC0; // Set bits 6 and 7
} else {
RxGain &= ~0xC0; // Unset bits 6 and 7
}
state = writeRegister(RADIOLIB_SX128X_REG_GAIN_MODE, &RxGain, 1);
RADIOLIB_ASSERT(state);
return(0);
}
int16_t SX128x::setGainControl(uint8_t gain) {
// update registers
uint8_t ManualGainSetting = 0;
int16_t state = readRegister(RADIOLIB_SX128X_REG_MANUAL_GAIN_CONTROL_ENABLE_2, &ManualGainSetting, 1);
RADIOLIB_ASSERT(state);
uint8_t LNAGainValue = 0;
state = readRegister(RADIOLIB_SX128X_REG_MANUAL_GAIN_SETTING, &LNAGainValue, 1);
RADIOLIB_ASSERT(state);
uint8_t LNAGainControl = 0;
state = readRegister(RADIOLIB_SX128X_REG_MANUAL_GAIN_CONTROL_ENABLE_1, &LNAGainControl, 1);
RADIOLIB_ASSERT(state);
if (gain > 0 && gain < 14) {
// Set manual gain
ManualGainSetting &= ~0x01; // Set bit 0 to 0 (Enable Manual Gain Control)
LNAGainValue &= 0xF0; // Bits 0, 1, 2 and 3 to 0
LNAGainValue |= gain; // Set bits 0, 1, 2 and 3 to Manual Gain Setting (1-13)
LNAGainControl |= 0x80; // Set bit 7 to 1 (Enable Manual Gain Control)
} else {
// Set automatic gain if 0 or out of range
ManualGainSetting |= 0x01; // Set bit 0 to 1 (Enable Automatic Gain Control)
LNAGainValue &= 0xF0; // Bits 0, 1, 2 and 3 to 0
LNAGainValue |= 0x0A; // Set bits 0, 1, 2 and 3 to Manual Gain Setting (1-13)
LNAGainControl &= ~0x80; // Set bit 7 to 0 (Enable Automatic Gain Control)
}
state = writeRegister(RADIOLIB_SX128X_REG_MANUAL_GAIN_CONTROL_ENABLE_2, &ManualGainSetting, 1);
RADIOLIB_ASSERT(state);
state = writeRegister(RADIOLIB_SX128X_REG_MANUAL_GAIN_SETTING, &LNAGainValue, 1);
RADIOLIB_ASSERT(state);
state = writeRegister(RADIOLIB_SX128X_REG_MANUAL_GAIN_CONTROL_ENABLE_1, &LNAGainControl, 1);
RADIOLIB_ASSERT(state);
return(0);
}
float SX128x::getRSSI() {
// get packet status
uint8_t packetStatus[5];
@ -1064,6 +1112,39 @@ float SX128x::getSNR() {
}
}
float SX128x::getFrequencyError() {
// check active modem
uint8_t modem = getPacketType();
if (!((modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) || (modem == RADIOLIB_SX128X_PACKET_TYPE_RANGING))) {
return (0.0);
}
uint8_t efeRaw[3] = {0};
// read the raw frequency error register values
int16_t state = readRegister(RADIOLIB_SX128X_REG_FEI_MSB, &efeRaw[0], 1);
RADIOLIB_ASSERT(state);
state = readRegister(RADIOLIB_SX128X_REG_FEI_MID, &efeRaw[1], 1);
RADIOLIB_ASSERT(state);
state = readRegister(RADIOLIB_SX128X_REG_FEI_LSB, &efeRaw[2], 1);
RADIOLIB_ASSERT(state);
uint32_t efe = ((uint32_t) efeRaw[0] << 16) | ((uint32_t) efeRaw[1] << 8) | efeRaw[2];
efe &= 0x0FFFFF;
float error;
// check the first bit
if (efe & 0x80000) {
// frequency error is negative
efe |= (uint32_t) 0xFFF00000;
efe = ~efe + 1;
error = 1.55 * (float) efe / (1600.0 / (float) _bwKhz) * -1.0;
} else {
error = 1.55 * (float) efe / (1600.0 / (float) _bwKhz);
}
return (error);
}
size_t SX128x::getPacketLength(bool update) {
(void)update;
uint8_t rxBufStatus[2] = {0, 0};

View file

@ -713,6 +713,24 @@ class SX128x: public PhysicalLayer {
*/
int16_t setAccessAddress(uint32_t addr);
/*!
\brief Enables or disables receiver high sensitivity mode.
\param True to enable and false to disable.
\returns 0
*/
int16_t setHighSensitivityMode(bool hsm = false);
/*!
\brief Enables or disables receiver manual gain control.
\param Gain 0 automatic gain; 1 minimum gain to 13 maximum gain.
\returns 0
*/
int16_t setGainControl(uint8_t gain = 0);
/*!
\brief Gets RSSI (Recorded Signal Strength Indicator) of the last received packet.
@ -727,6 +745,13 @@ class SX128x: public PhysicalLayer {
*/
float getSNR();
/*!
\brief Gets frequency error of the latest received packet.
\returns Frequency error in Hz.
*/
float getFrequencyError();
/*!
\brief Query modem for the packet length of received payload.