From cfe6128656fb9fe6cc2a98c8b36bb9a99e3175be Mon Sep 17 00:00:00 2001 From: jgromes Date: Sat, 18 Mar 2023 10:56:00 +0100 Subject: [PATCH] [SX126x] Added frequency error reading --- .../SX126x/SX126x_Receive/SX126x_Receive.ino | 5 +++ .../SX126x_Receive_Interrupt.ino | 5 +++ src/modules/SX126x/SX126x.cpp | 33 +++++++++++++++++++ src/modules/SX126x/SX126x.h | 22 ++++++++----- 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/examples/SX126x/SX126x_Receive/SX126x_Receive.ino b/examples/SX126x/SX126x_Receive/SX126x_Receive.ino index b2f49d28..d00f4f64 100644 --- a/examples/SX126x/SX126x_Receive/SX126x_Receive.ino +++ b/examples/SX126x/SX126x_Receive/SX126x_Receive.ino @@ -88,6 +88,11 @@ void loop() { Serial.print(radio.getSNR()); Serial.println(F(" dB")); + // print frequency error + Serial.print(F("[SX1262] 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!")); diff --git a/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino b/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino index 2e2c2faa..a7f87a36 100644 --- a/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino +++ b/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino @@ -127,6 +127,11 @@ void loop() { Serial.print(radio.getSNR()); Serial.println(F(" dB")); + // print frequency error + Serial.print(F("[SX1262] 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!")); diff --git a/src/modules/SX126x/SX126x.cpp b/src/modules/SX126x/SX126x.cpp index 121670a7..70115feb 100644 --- a/src/modules/SX126x/SX126x.cpp +++ b/src/modules/SX126x/SX126x.cpp @@ -1241,6 +1241,39 @@ float SX126x::getSNR() { } } +float SX126x::getFrequencyError() { + // check active modem + uint8_t modem = getPacketType(); + if(modem != RADIOLIB_SX126X_PACKET_TYPE_LORA) { + return(0.0); + } + + // read the raw frequency error register values + uint8_t efeRaw[3] = {0}; + int16_t state = readRegister(RADIOLIB_SX126X_REG_FREQ_ERROR + 2, &efeRaw[0], 1); + RADIOLIB_ASSERT(state); + state = readRegister(RADIOLIB_SX126X_REG_FREQ_ERROR + 1, &efeRaw[1], 1); + RADIOLIB_ASSERT(state); + state = readRegister(RADIOLIB_SX126X_REG_FREQ_ERROR, &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 = 0; + + // check the first bit + if (efe & 0x80000) { + // frequency error is negative + efe |= (uint32_t) 0xFFF00000; + efe = ~efe + 1; + error = 1.55 * (float) efe / (160.0 / (float) _bwKhz) * -1.0; + } else { + error = 1.55 * (float) efe / (160.0 / (float) _bwKhz); + } + + return(error); +} + size_t SX126x::getPacketLength(bool update) { (void)update; uint8_t rxBufStatus[2] = {0, 0}; diff --git a/src/modules/SX126x/SX126x.h b/src/modules/SX126x/SX126x.h index c27e64c3..aca8356b 100644 --- a/src/modules/SX126x/SX126x.h +++ b/src/modules/SX126x/SX126x.h @@ -73,6 +73,9 @@ #define RADIOLIB_SX126X_CMD_SET_SPECTR_SCAN_PARAMS 0x9B // SX126X register map +#define RADIOLIB_SX126X_REG_RX_GAIN_RETENTION_0 0x029F // SX1268 datasheet v1.1, section 9.6 +#define RADIOLIB_SX126X_REG_RX_GAIN_RETENTION_1 0x02A0 // SX1268 datasheet v1.1, section 9.6 +#define RADIOLIB_SX126X_REG_RX_GAIN_RETENTION_2 0x02A1 // SX1268 datasheet v1.1, section 9.6 #define RADIOLIB_SX126X_REG_VERSION_STRING 0x0320 #define RADIOLIB_SX126X_REG_HOPPING_ENABLE 0x0385 #define RADIOLIB_SX126X_REG_LR_FHSS_PACKET_LENGTH 0x0386 @@ -85,6 +88,7 @@ #define RADIOLIB_SX126X_REG_LR_FHSS_FREQX_3(X) (0x038D + (X)*6) #define RADIOLIB_SX126X_REG_SPECTRAL_SCAN_RESULT 0x0401 #define RADIOLIB_SX126X_REG_DIOX_OUT_ENABLE 0x0580 +#define RADIOLIB_SX126X_REG_DIOX_DRIVE_STRENGTH 0x0582 #define RADIOLIB_SX126X_REG_DIOX_IN_ENABLE 0x0583 #define RADIOLIB_SX126X_REG_DIOX_PULL_UP_CTRL 0x0584 #define RADIOLIB_SX126X_REG_DIOX_PULL_DOWN_CTRL 0x0585 @@ -120,7 +124,7 @@ #define RADIOLIB_SX126X_REG_RANDOM_NUMBER_1 0x081A #define RADIOLIB_SX126X_REG_RANDOM_NUMBER_2 0x081B #define RADIOLIB_SX126X_REG_RANDOM_NUMBER_3 0x081C -#define RADIOLIB_SX126X_REG_TX_MODULATION 0x0889 +#define RADIOLIB_SX126X_REG_SENSITIVITY_CONFIG 0x0889 // SX1268 datasheet v1.1, section 15.1 #define RADIOLIB_SX126X_REG_RF_FREQUENCY_0 0x088B #define RADIOLIB_SX126X_REG_RF_FREQUENCY_1 0x088C #define RADIOLIB_SX126X_REG_RF_FREQUENCY_2 0x088D @@ -138,13 +142,6 @@ #define RADIOLIB_SX126X_REG_EVENT_MASK 0x0944 #define RADIOLIB_SX126X_REG_PATCH_MEMORY_BASE 0x8000 -// undocumented registers -#define RADIOLIB_SX126X_REG_SENSITIVITY_CONFIG 0x0889 // SX1268 datasheet v1.1, section 15.1 -#define RADIOLIB_SX126X_REG_RX_GAIN_RETENTION_0 0x029F // SX1268 datasheet v1.1, section 9.6 -#define RADIOLIB_SX126X_REG_RX_GAIN_RETENTION_1 0x02A0 // SX1268 datasheet v1.1, section 9.6 -#define RADIOLIB_SX126X_REG_RX_GAIN_RETENTION_2 0x02A1 // SX1268 datasheet v1.1, section 9.6 - - // SX126X SPI command variables //RADIOLIB_SX126X_CMD_SET_SLEEP MSB LSB DESCRIPTION #define RADIOLIB_SX126X_SLEEP_START_COLD 0b00000000 // 2 2 sleep mode: cold start, configuration is lost (default) @@ -931,6 +928,15 @@ class SX126x: public PhysicalLayer { */ float getSNR(); + /*! + \brief Gets frequency error of the latest received packet. + WARNING: This functionality is based on SX128x implementation and not documented on SX126x. + While it seems to be working, it should be used with caution! + + \returns Frequency error in Hz. + */ + float getFrequencyError(); + /*! \brief Query modem for the packet length of received payload.