diff --git a/examples/ADC_Button/ADC button connection diagram.jpg b/examples/ADC_Button/ADC button connection diagram.jpg new file mode 100644 index 0000000..bfa3022 Binary files /dev/null and b/examples/ADC_Button/ADC button connection diagram.jpg differ diff --git a/examples/ADC_Button/ADC_Button.ino b/examples/ADC_Button/ADC_Button.ino new file mode 100644 index 0000000..e40952a --- /dev/null +++ b/examples/ADC_Button/ADC_Button.ino @@ -0,0 +1,95 @@ +/** + * @file ADC_Button.ino + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd + * @date 2024-06-24 + * @note The example demonstrates how to use ADC as a key function. Please see the example picture for the external circuit. + */ +#include + +// Select the board model to be used and adjust the Pin according to the actual situation + +// #define LILYGO_T_INTERNET_POE +// #define LILYGO_T_ETH_POE_PRO +// #define LILYGO_T_INTER_COM //Can't run +// #define LILYGO_T_ETH_LITE_ESP32 +// #define LILYGO_T_ETH_LITE_ESP32S3 +// #define LILYGO_T_ETH_ELITE_ESP32S3 + +#if defined(LILYGO_T_INTERNET_POE) +// IO34 35,39,34,36 can only be used for input,ADC function is limited to GPIO33 and above +#define ADC_PIN 36 +#elif defined(LILYGO_T_ETH_POE_PRO) +// IO34 35,39,34,36 can only be used for input,ADC function is limited to GPIO33 and above +#define ADC_PIN 36 +#elif defined(LILYGO_T_INTER_COM) +//No free pin +#error "No free pin" +#elif defined(LILYGO_T_ETH_LITE_ESP32) +// IO35,36,37,38,39 can only be used for input and cannot be set as output +#define ADC_PIN 36 +#elif defined(LILYGO_T_ETH_LITE_ESP32S3) +// ESP32S3 can freely map unused Pins , ADC function is limited to GPIO33 and below +#define ADC_PIN 7 +#elif defined(LILYGO_T_ETH_ELITE_ESP32S3) +// ESP32S3 can freely map unused Pins , ADC function is limited to GPIO33 and below +#define ADC_PIN 7 +#endif + +#define SAMPLE_TIME 200 +#define DEVIATION 0.1 + +xQueueHandle adc_queue = NULL; + +void button_task(void *arg) +{ + while (1) { + double voltage = 0; + voltage = analogReadMilliVolts(ADC_PIN) / 1000.0; + xQueueSend(adc_queue, (double *)&voltage, 0); + vTaskDelay(pdMS_TO_TICKS(SAMPLE_TIME)); + } + vTaskDelete(NULL); +} + +void setup() +{ + Serial.begin(115200); + adc_queue = xQueueCreate(1, sizeof(double)); + analogReadResolution(12); + analogSetAttenuation(ADC_11db); + xTaskCreatePinnedToCore(&button_task, "btn", 3 * 1024, NULL, 5, NULL, 0); +} + + +void loop() +{ + double voltage = 0; + xQueueReceive(adc_queue, &voltage, portMAX_DELAY); + if (voltage > 2.6) { + } else if (voltage > 2.2 - DEVIATION && voltage <= 2.2 + DEVIATION) { + Serial.println("B5"); + } else if (voltage > 1.65 - DEVIATION && voltage <= 1.65 + DEVIATION) { + Serial.println("B4"); + } else if (voltage > 1.11 - DEVIATION && voltage <= 1.11 + DEVIATION) { + Serial.println("B3"); + } else if (voltage > 0.76 - DEVIATION && voltage <= 0.76 + DEVIATION) { + Serial.println("B2"); + } else if (voltage > 0.43 - DEVIATION && voltage <= 0.43 + DEVIATION) { + Serial.println("B1"); + } + delay(5); +} + + + + + + + + + + + + diff --git a/examples/T-ETH-ELite-Shield/LoRa_Receive_Interrupt/LoRa_Receive_Interrupt.ino b/examples/T-ETH-ELite-Shield/LoRa_Receive_Interrupt/LoRa_Receive_Interrupt.ino new file mode 100644 index 0000000..12e5d04 --- /dev/null +++ b/examples/T-ETH-ELite-Shield/LoRa_Receive_Interrupt/LoRa_Receive_Interrupt.ino @@ -0,0 +1,472 @@ +/* + RadioLib Receive with Interrupts Example + + This example listens for LoRa transmissions and tries to + receive them. Once a packet is received, an interrupt is + triggered. To successfully receive data, the following + settings have to be the same on both transmitter + and receiver: + - carrier frequency + - bandwidth + - spreading factor + - coding rate + - sync word + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +#include +#include +#include +#include +#include "utilities.h" + +// #define USING_SX1262 +// #define USING_LR1121 +// #define USING_SX1280 +// #define USING_SX1276 +// #define USING_SX1276_TCXO +// #define USING_SX1280PA + + +#define DISPLAY_MODEL U8G2_SSD1306_128X64_NONAME_F_HW_I2C +#define DISPLAY_ADDR 0x3C + +#define U8G2_HOR_ALIGN_CENTER(t) ((u8g2->getDisplayWidth() - (u8g2->getUTF8Width(t))) / 2) +#define U8G2_HOR_ALIGN_RIGHT(t) ( u8g2->getDisplayWidth() - u8g2->getUTF8Width(t)) + + + +#if defined(USING_SX1276) +#define CONFIG_RADIO_FREQ 868.0 +#define CONFIG_RADIO_OUTPUT_POWER 17 +#define CONFIG_RADIO_BW 125.0 +SX1276 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + + +#elif defined(USING_SX1276_TCXO) +#define CONFIG_RADIO_FREQ 868.0 +#define CONFIG_RADIO_OUTPUT_POWER 17 +#define CONFIG_RADIO_BW 125.0 +#define TCXO_ENABLE_PIN 38 +SX1276 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + + +#elif defined(USING_SX1278) +#define CONFIG_RADIO_FREQ 433.0 +#define CONFIG_RADIO_OUTPUT_POWER 17 +#define CONFIG_RADIO_BW 125.0 +SX1278 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_SX1262) +#define CONFIG_RADIO_FREQ 868.0 +#define CONFIG_RADIO_OUTPUT_POWER 22 +#define CONFIG_RADIO_BW 125.0 + +SX1262 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_SX1280) +#define CONFIG_RADIO_FREQ 2400.0 +#define CONFIG_RADIO_OUTPUT_POWER 13 +#define CONFIG_RADIO_BW 203.125 +SX1280 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#define RADIO_RX_PIN 13 +#define RADIO_TX_PIN 38 + +#elif defined(USING_SX1280PA) +#define CONFIG_RADIO_FREQ 2400.0 +// PA Version power range : -18 ~ 3dBm +#define CONFIG_RADIO_OUTPUT_POWER 3 +#define CONFIG_RADIO_BW 203.125 +SX1280 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + + +#define RADIO_RX_PIN 13 +#define RADIO_TX_PIN 38 + + +#elif defined(USING_SX1268) +#define CONFIG_RADIO_FREQ 433.0 +#define CONFIG_RADIO_OUTPUT_POWER 22 +#define CONFIG_RADIO_BW 125.0 +SX1268 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_LR1121) +// The maximum power of LR1121 2.4G band can only be set to 13 dBm +#define CONFIG_RADIO_FREQ 2450.0 +#define CONFIG_RADIO_OUTPUT_POWER 13 +#define CONFIG_RADIO_BW 125.0 + +// The maximum power of LR1121 Sub 1G band can only be set to 22 dBm +// #define CONFIG_RADIO_FREQ 868.0 +// #define CONFIG_RADIO_OUTPUT_POWER 22 +// #define CONFIG_RADIO_BW 125.0 + +LR1121 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#else + +#error "Please select the LoRa model you need to use !" + +#endif + +void printResult(bool radio_online); +bool beginDisplay(); +void drawMain(); + +DISPLAY_MODEL *u8g2 = NULL; + +// flag to indicate that a packet was received +static volatile bool receivedFlag = false; +static String rssi = "0dBm"; +static String snr = "0dB"; +static String payload = "0"; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) +{ + // we got a packet, set the flag + receivedFlag = true; +} + +void setup() +{ + + Serial.begin(115200); + + // Onboard LED is a multiplexed function + // SX1276-TCXO: LED IO38 is multiplexed as TCXO enable function + // SX1280PA: LED IO38 is multiplexed as LoRa (TX) antenna control function enable function + // When using other model modules, it is only LED function +#ifdef TCXO_ENABLE_PIN + pinMode(TCXO_ENABLE_PIN, OUTPUT); + digitalWrite(TCXO_ENABLE_PIN, HIGH); +#else + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); +#endif + + // Initialize SPI bus + SPI.begin(SPI_SCLK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN); + + // Radio and SD card share the bus. During initialization, their respective CS Pin needs to be set to HIGH. + pinMode(RADIO_CS_PIN, OUTPUT); + digitalWrite(RADIO_CS_PIN, HIGH); + // Radio and SD card share the bus. During initialization, their respective CS Pin needs to be set to HIGH. + pinMode(SD_CS_PIN, OUTPUT); + digitalWrite(SD_CS_PIN, HIGH); + + if (!SD.begin(SD_CS_PIN)) { + Serial.println("Warning: Failed to init SD card"); + } else { + Serial.println("SD card init succeeded, size : "); + Serial.print(SD.cardSize() / (1024 * 1024)); + Serial.println("MBytes"); + } + + Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN); + beginDisplay(); + + // When the power is turned on, a delay is required. + delay(1500); + +#ifdef RADIO_TCXO_ENABLE + pinMode(RADIO_TCXO_ENABLE, OUTPUT); + digitalWrite(RADIO_TCXO_ENABLE, HIGH); +#endif + + // initialize radio with default settings + int state = radio.begin(); + + printResult(state == RADIOLIB_ERR_NONE); + + Serial.print(F("Radio Initializing ... ")); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set the function that will be called + // when new packet is received + radio.setPacketReceivedAction(setFlag); + + /* + * Sets carrier frequency. + * SX1278/SX1276 : Allowed values range from 137.0 MHz to 525.0 MHz. + * SX1268/SX1262 : Allowed values are in range from 150.0 to 960.0 MHz. + * SX1280 : Allowed values are in range from 2400.0 to 2500.0 MHz. + * LR1121 : Allowed values are in range from 150.0 to 960.0 MHz, 1900 - 2200 MHz and 2400 - 2500 MHz. Will also perform calibrations. + * * * */ + + if (radio.setFrequency(CONFIG_RADIO_FREQ) == RADIOLIB_ERR_INVALID_FREQUENCY) { + Serial.println(F("Selected frequency is invalid for this module!")); + while (true); + } + + /* + * Sets LoRa link bandwidth. + * SX1278/SX1276 : Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz. Only available in %LoRa mode. + * SX1268/SX1262 : Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125.0, 250.0 and 500.0 kHz. + * SX1280 : Allowed values are 203.125, 406.25, 812.5 and 1625.0 kHz. + * LR1121 : Allowed values are 62.5, 125.0, 250.0 and 500.0 kHz. + * * * */ + if (radio.setBandwidth(CONFIG_RADIO_BW) == RADIOLIB_ERR_INVALID_BANDWIDTH) { + Serial.println(F("Selected bandwidth is invalid for this module!")); + while (true); + } + + + /* + * Sets LoRa link spreading factor. + * SX1278/SX1276 : Allowed values range from 6 to 12. Only available in LoRa mode. + * SX1262 : Allowed values range from 5 to 12. + * SX1280 : Allowed values range from 5 to 12. + * LR1121 : Allowed values range from 5 to 12. + * * * */ + if (radio.setSpreadingFactor(12) == RADIOLIB_ERR_INVALID_SPREADING_FACTOR) { + Serial.println(F("Selected spreading factor is invalid for this module!")); + while (true); + } + + /* + * Sets LoRa coding rate denominator. + * SX1278/SX1276/SX1268/SX1262 : Allowed values range from 5 to 8. Only available in LoRa mode. + * SX1280 : Allowed values range from 5 to 8. + * LR1121 : Allowed values range from 5 to 8. + * * * */ + if (radio.setCodingRate(6) == RADIOLIB_ERR_INVALID_CODING_RATE) { + Serial.println(F("Selected coding rate is invalid for this module!")); + while (true); + } + + /* + * Sets LoRa sync word. + * SX1278/SX1276/SX1268/SX1262/SX1280 : Sets LoRa sync word. Only available in LoRa mode. + * * */ + if (radio.setSyncWord(0xAB) != RADIOLIB_ERR_NONE) { + Serial.println(F("Unable to set sync word!")); + while (true); + } + + /* + * Sets transmission output power. + * SX1278/SX1276 : Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin). High power +20 dBm operation is also supported, on the PA_BOOST pin. Defaults to PA_BOOST. + * SX1262 : Allowed values are in range from -9 to 22 dBm. This method is virtual to allow override from the SX1261 class. + * SX1268 : Allowed values are in range from -9 to 22 dBm. + * SX1280 : Allowed values are in range from -18 to 13 dBm. PA Version range : -18 ~ 3dBm + * LR1121 : Allowed values are in range from -17 to 22 dBm (high-power PA) or -18 to 13 dBm (High-frequency PA) + * * * */ + if (radio.setOutputPower(CONFIG_RADIO_OUTPUT_POWER) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { + Serial.println(F("Selected output power is invalid for this module!")); + while (true); + } + +#if !defined(USING_SX1280) && !defined(USING_LR1121) + /* + * Sets current limit for over current protection at transmitter amplifier. + * SX1278/SX1276 : Allowed values range from 45 to 120 mA in 5 mA steps and 120 to 240 mA in 10 mA steps. + * SX1262/SX1268 : Allowed values range from 45 to 120 mA in 2.5 mA steps and 120 to 240 mA in 10 mA steps. + * NOTE: set value to 0 to disable overcurrent protection + * * * */ + if (radio.setCurrentLimit(140) == RADIOLIB_ERR_INVALID_CURRENT_LIMIT) { + Serial.println(F("Selected current limit is invalid for this module!")); + while (true); + } +#endif + + /* + * Sets preamble length for LoRa or FSK modem. + * SX1278/SX1276 : Allowed values range from 6 to 65535 in %LoRa mode or 0 to 65535 in FSK mode. + * SX1262/SX1268 : Allowed values range from 1 to 65535. + * SX1280 : Allowed values range from 1 to 65535. preamble length is multiple of 4 + * LR1121 : Allowed values range from 1 to 65535. + * * */ + if (radio.setPreambleLength(16) == RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH) { + Serial.println(F("Selected preamble length is invalid for this module!")); + while (true); + } + + // Enables or disables CRC check of received packets. + if (radio.setCRC(false) == RADIOLIB_ERR_INVALID_CRC_CONFIGURATION) { + Serial.println(F("Selected CRC is invalid for this module!")); + while (true); + } + +#if defined(USING_LR1121) + // LR1121 + // set RF switch configuration for Wio WM1110 + // Wio WM1110 uses DIO5 and DIO6 for RF switching + static const uint32_t rfswitch_dio_pins[] = { + RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, + RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC + }; + + static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + { LR11x0::MODE_STBY, { LOW, LOW } }, + { LR11x0::MODE_RX, { HIGH, LOW } }, + { LR11x0::MODE_TX, { LOW, HIGH } }, + { LR11x0::MODE_TX_HP, { LOW, HIGH } }, + { LR11x0::MODE_TX_HF, { LOW, LOW } }, + { LR11x0::MODE_GNSS, { LOW, LOW } }, + { LR11x0::MODE_WIFI, { LOW, LOW } }, + END_OF_MODE_TABLE, + }; + radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); + + // LR1121 TCXO Voltage 2.85~3.15V + radio.setTCXO(3.0); + + +#endif + +#ifdef USING_DIO2_AS_RF_SWITCH +#ifdef USING_SX1262 + // Some SX126x modules use DIO2 as RF switch. To enable + // this feature, the following method can be used. + // NOTE: As long as DIO2 is configured to control RF switch, + // it can't be used as interrupt pin! + if (radio.setDio2AsRfSwitch() != RADIOLIB_ERR_NONE) { + Serial.println(F("Failed to set DIO2 as RF switch!")); + while (true); + } +#endif //USING_SX1262 +#endif //USING_DIO2_AS_RF_SWITCH + + +#ifdef RADIO_RX_PIN + // SX1280 PA Version + radio.setRfSwitchPins(RADIO_RX_PIN, RADIO_TX_PIN); +#endif + + + delay(1000); + + // start listening for LoRa packets + Serial.print(F("Radio Starting to listen ... ")); + state = radio.startReceive(); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + } + + drawMain(); + +} + + + + +void loop() +{ + // check if the flag is set + if (receivedFlag) { + + // reset flag + receivedFlag = false; + + // you can read received data as an Arduino String + int state = radio.readData(payload); + + // you can also read received data as byte array + /* + byte byteArr[8]; + int state = radio.readData(byteArr, 8); + */ + + if (state == RADIOLIB_ERR_NONE) { + + rssi = String(radio.getRSSI()) + "dBm"; + snr = String(radio.getSNR()) + "dB"; + + drawMain(); + + // packet was successfully received + Serial.println(F("Radio Received packet!")); + + // print data of the packet + Serial.print(F("Radio Data:\t\t")); + Serial.println(payload); + + // print RSSI (Received Signal Strength Indicator) + Serial.print(F("Radio RSSI:\t\t")); + Serial.println(rssi); + + // print SNR (Signal-to-Noise Ratio) + Serial.print(F("Radio SNR:\t\t")); + Serial.println(snr); + + } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { + // packet was received, but is malformed + Serial.println(F("CRC error!")); + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + } + + // put module back to listen mode + radio.startReceive(); + + } +} + +void drawMain() +{ + if (u8g2) { + u8g2->clearBuffer(); + u8g2->drawRFrame(0, 0, 128, 64, 5); + u8g2->setFont(u8g2_font_pxplusibmvga8_mr); + u8g2->setCursor(15, 20); + u8g2->print("RX:"); + u8g2->setCursor(15, 35); + u8g2->print("SNR:"); + u8g2->setCursor(15, 50); + u8g2->print("RSSI:"); + + u8g2->setFont(u8g2_font_crox1h_tr); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(payload.c_str()) - 21, 20 ); + u8g2->print(payload); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(snr.c_str()) - 21, 35 ); + u8g2->print(snr); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(rssi.c_str()) - 21, 50 ); + u8g2->print(rssi); + u8g2->sendBuffer(); + } +} + +bool beginDisplay() +{ + Wire.beginTransmission(DISPLAY_ADDR); + if (Wire.endTransmission() == 0) { + Serial.printf("Find Display model at 0x%X address\n", DISPLAY_ADDR); + u8g2 = new DISPLAY_MODEL(U8G2_R0, U8X8_PIN_NONE); + u8g2->begin(); + u8g2->clearBuffer(); + u8g2->setFont(u8g2_font_inb19_mr); + u8g2->drawStr(0, 30, "LilyGo"); + u8g2->drawHLine(2, 35, 47); + u8g2->drawHLine(3, 36, 47); + u8g2->drawVLine(45, 32, 12); + u8g2->drawVLine(46, 33, 12); + u8g2->setFont(u8g2_font_inb19_mf); + u8g2->drawStr(58, 60, "LoRa"); + u8g2->sendBuffer(); + u8g2->setFont(u8g2_font_fur11_tf); + delay(3000); + return true; + } + + Serial.printf("Warning: Failed to find Display at 0x%0X address\n", DISPLAY_ADDR); + return false; +} diff --git a/examples/T-ETH-ELite-Shield/LoRa_Transmit_Interrupt/LoRa_Transmit_Interrupt.ino b/examples/T-ETH-ELite-Shield/LoRa_Transmit_Interrupt/LoRa_Transmit_Interrupt.ino new file mode 100644 index 0000000..c49a37e --- /dev/null +++ b/examples/T-ETH-ELite-Shield/LoRa_Transmit_Interrupt/LoRa_Transmit_Interrupt.ino @@ -0,0 +1,489 @@ +/* +* RadioLib Transmit with Interrupts Example +* +* This example transmits packets using SX1276/SX1278/SX1262/SX1268/SX1280/LR1121 LoRa radio module. +* Each packet contains up to 256 bytes of data, in the form of: +* - Arduino String +* - null-terminated char array (C-string) +* - arbitrary binary data (byte array) +* +* For full API reference, see the GitHub Pages +* https://jgromes.github.io/RadioLib/ +* +* +*/ +#include +#include +#include +#include +#include "utilities.h" + + +// The example is adapted to T-ETH-Elite-LoRa-Shield. Uncomment the model you want to use according to the wireless LoRa module you purchased. + +// #define USING_SX1262 +// #define USING_LR1121 +// #define USING_SX1280 +// #define USING_SX1276 +// #define USING_SX1276_TCXO +// #define USING_SX1280PA + + +#define DISPLAY_MODEL U8G2_SSD1306_128X64_NONAME_F_HW_I2C +#define DISPLAY_ADDR 0x3C + +#define U8G2_HOR_ALIGN_CENTER(t) ((u8g2->getDisplayWidth() - (u8g2->getUTF8Width(t))) / 2) +#define U8G2_HOR_ALIGN_RIGHT(t) ( u8g2->getDisplayWidth() - u8g2->getUTF8Width(t)) + + + +#if defined(USING_SX1276) +#define CONFIG_RADIO_FREQ 868.0 +#define CONFIG_RADIO_OUTPUT_POWER 17 +#define CONFIG_RADIO_BW 125.0 +SX1276 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + + +#elif defined(USING_SX1276_TCXO) +#define CONFIG_RADIO_FREQ 868.0 +#define CONFIG_RADIO_OUTPUT_POWER 17 +#define CONFIG_RADIO_BW 125.0 +#define TCXO_ENABLE_PIN 38 +SX1276 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + + +#elif defined(USING_SX1278) +#define CONFIG_RADIO_FREQ 433.0 +#define CONFIG_RADIO_OUTPUT_POWER 17 +#define CONFIG_RADIO_BW 125.0 +SX1278 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_SX1262) +#define CONFIG_RADIO_FREQ 868.0 +#define CONFIG_RADIO_OUTPUT_POWER 22 +#define CONFIG_RADIO_BW 125.0 + +SX1262 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_SX1280) +#define CONFIG_RADIO_FREQ 2400.0 +#define CONFIG_RADIO_OUTPUT_POWER 13 +#define CONFIG_RADIO_BW 203.125 +SX1280 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_SX1280PA) +#define CONFIG_RADIO_FREQ 2400.0 +// PA Version power range : -18 ~ 3dBm +#define CONFIG_RADIO_OUTPUT_POWER 3 +#define CONFIG_RADIO_BW 203.125 +SX1280 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); +#define RADIO_RX_PIN 13 +#define RADIO_TX_PIN 38 + +#elif defined(USING_SX1268) +#define CONFIG_RADIO_FREQ 433.0 +#define CONFIG_RADIO_OUTPUT_POWER 22 +#define CONFIG_RADIO_BW 125.0 +SX1268 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_LR1121) +// The maximum power of LR1121 2.4G band can only be set to 13 dBm +#define CONFIG_RADIO_FREQ 2450.0 +#define CONFIG_RADIO_OUTPUT_POWER 13 +#define CONFIG_RADIO_BW 125.0 + +// The maximum power of LR1121 Sub 1G band can only be set to 22 dBm +// #define CONFIG_RADIO_FREQ 868.0 +// #define CONFIG_RADIO_OUTPUT_POWER 22 +// #define CONFIG_RADIO_BW 125.0 + +LR1121 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#else + +#error "Please select the LoRa model you need to use !" + +#endif + +void printResult(bool radio_online); +bool beginDisplay(); +void drawMain(); + +// save transmission state between loops +static int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +static volatile bool transmittedFlag = false; +static uint32_t counter = 0; +static String payload; + + +DISPLAY_MODEL *u8g2 = NULL; + + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) +{ + // we sent a packet, set the flag + transmittedFlag = true; +} + +void setup() +{ + + Serial.begin(115200); + + // Onboard LED is a multiplexed function + // SX1276-TCXO: LED IO38 is multiplexed as TCXO enable function + // SX1280PA: LED IO38 is multiplexed as LoRa (TX) antenna control function enable function + // When using other model modules, it is only LED function +#if defined(TCXO_ENABLE_PIN) || defined(USING_SX1280PA) + pinMode(TCXO_ENABLE_PIN, OUTPUT); + digitalWrite(TCXO_ENABLE_PIN, HIGH); +#else + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); +#endif + + // Initialize SPI bus + SPI.begin(SPI_SCLK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN); + + // Radio and SD card share the bus. During initialization, their respective CS Pin needs to be set to HIGH. + pinMode(RADIO_CS_PIN, OUTPUT); + digitalWrite(RADIO_CS_PIN, HIGH); + // Radio and SD card share the bus. During initialization, their respective CS Pin needs to be set to HIGH. + pinMode(SD_CS_PIN, OUTPUT); + digitalWrite(SD_CS_PIN, HIGH); + + if (!SD.begin(SD_CS_PIN)) { + Serial.println("Warning: Failed to init SD card"); + } else { + Serial.println("SD card init succeeded, size : "); + Serial.print(SD.cardSize() / (1024 * 1024)); + Serial.println("MBytes"); + } + + Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN); + beginDisplay(); + + // When the power is turned on, a delay is required. + delay(1500); + + + // initialize radio with default settings + int state = radio.begin(); + + printResult(state == RADIOLIB_ERR_NONE); + + Serial.print(F("Radio Initializing ... ")); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set the function that will be called + // when packet transmission is finished + radio.setPacketSentAction(setFlag); + + + /* + * Sets carrier frequency. + * SX1278/SX1276 : Allowed values range from 137.0 MHz to 525.0 MHz. + * SX1268/SX1262 : Allowed values are in range from 150.0 to 960.0 MHz. + * SX1280 : Allowed values are in range from 2400.0 to 2500.0 MHz. + * LR1121 : Allowed values are in range from 150.0 to 960.0 MHz, 1900 - 2200 MHz and 2400 - 2500 MHz. Will also perform calibrations. + * * * */ + + if (radio.setFrequency(CONFIG_RADIO_FREQ) == RADIOLIB_ERR_INVALID_FREQUENCY) { + Serial.println(F("Selected frequency is invalid for this module!")); + while (true); + } + + /* + * Sets LoRa link bandwidth. + * SX1278/SX1276 : Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz. Only available in %LoRa mode. + * SX1268/SX1262 : Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125.0, 250.0 and 500.0 kHz. + * SX1280 : Allowed values are 203.125, 406.25, 812.5 and 1625.0 kHz. + * LR1121 : Allowed values are 62.5, 125.0, 250.0 and 500.0 kHz. + * * * */ + if (radio.setBandwidth(CONFIG_RADIO_BW) == RADIOLIB_ERR_INVALID_BANDWIDTH) { + Serial.println(F("Selected bandwidth is invalid for this module!")); + while (true); + } + + + /* + * Sets LoRa link spreading factor. + * SX1278/SX1276 : Allowed values range from 6 to 12. Only available in LoRa mode. + * SX1262 : Allowed values range from 5 to 12. + * SX1280 : Allowed values range from 5 to 12. + * LR1121 : Allowed values range from 5 to 12. + * * * */ + if (radio.setSpreadingFactor(12) == RADIOLIB_ERR_INVALID_SPREADING_FACTOR) { + Serial.println(F("Selected spreading factor is invalid for this module!")); + while (true); + } + + /* + * Sets LoRa coding rate denominator. + * SX1278/SX1276/SX1268/SX1262 : Allowed values range from 5 to 8. Only available in LoRa mode. + * SX1280 : Allowed values range from 5 to 8. + * LR1121 : Allowed values range from 5 to 8. + * * * */ + if (radio.setCodingRate(6) == RADIOLIB_ERR_INVALID_CODING_RATE) { + Serial.println(F("Selected coding rate is invalid for this module!")); + while (true); + } + + /* + * Sets LoRa sync word. + * SX1278/SX1276/SX1268/SX1262/SX1280 : Sets LoRa sync word. Only available in LoRa mode. + * * */ + if (radio.setSyncWord(0xAB) != RADIOLIB_ERR_NONE) { + Serial.println(F("Unable to set sync word!")); + while (true); + } + + /* + * Sets transmission output power. + * SX1278/SX1276 : Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin). High power +20 dBm operation is also supported, on the PA_BOOST pin. Defaults to PA_BOOST. + * SX1262 : Allowed values are in range from -9 to 22 dBm. This method is virtual to allow override from the SX1261 class. + * SX1268 : Allowed values are in range from -9 to 22 dBm. + * SX1280 : Allowed values are in range from -18 to 13 dBm. PA Version range : -18 ~ 3dBm + * LR1121 : Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA) + * * * */ + if (radio.setOutputPower(CONFIG_RADIO_OUTPUT_POWER) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { + Serial.println(F("Selected output power is invalid for this module!")); + while (true); + } + +#if !defined(USING_SX1280) && !defined(USING_SX1280PA) && !defined(USING_LR1121) + /* + * Sets current limit for over current protection at transmitter amplifier. + * SX1278/SX1276 : Allowed values range from 45 to 120 mA in 5 mA steps and 120 to 240 mA in 10 mA steps. + * SX1262/SX1268 : Allowed values range from 45 to 120 mA in 2.5 mA steps and 120 to 240 mA in 10 mA steps. + * NOTE: set value to 0 to disable overcurrent protection + * * * */ + if (radio.setCurrentLimit(140) == RADIOLIB_ERR_INVALID_CURRENT_LIMIT) { + Serial.println(F("Selected current limit is invalid for this module!")); + while (true); + } +#endif + + /* + * Sets preamble length for LoRa or FSK modem. + * SX1278/SX1276 : Allowed values range from 6 to 65535 in %LoRa mode or 0 to 65535 in FSK mode. + * SX1262/SX1268 : Allowed values range from 1 to 65535. + * SX1280 : Allowed values range from 1 to 65535. preamble length is multiple of 4 + * LR1121 : Allowed values range from 1 to 65535. + * * */ + if (radio.setPreambleLength(16) == RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH) { + Serial.println(F("Selected preamble length is invalid for this module!")); + while (true); + } + + // Enables or disables CRC check of received packets. + if (radio.setCRC(false) == RADIOLIB_ERR_INVALID_CRC_CONFIGURATION) { + Serial.println(F("Selected CRC is invalid for this module!")); + while (true); + } + +#ifdef USING_DIO2_AS_RF_SWITCH +#ifdef USING_SX1262 + // Some SX126x modules use DIO2 as RF switch. To enable + // this feature, the following method can be used. + // NOTE: As long as DIO2 is configured to control RF switch, + // it can't be used as interrupt pin! + if (radio.setDio2AsRfSwitch() != RADIOLIB_ERR_NONE) { + Serial.println(F("Failed to set DIO2 as RF switch!")); + while (true); + } +#endif //USING_SX1262 +#endif //USING_DIO2_AS_RF_SWITCH + + +#if defined(USING_LR1121) + // LR1121 + // set RF switch configuration for Wio WM1110 + // Wio WM1110 uses DIO5 and DIO6 for RF switching + static const uint32_t rfswitch_dio_pins[] = { + RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, + RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC + }; + + static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + { LR11x0::MODE_STBY, { LOW, LOW } }, + { LR11x0::MODE_RX, { HIGH, LOW } }, + { LR11x0::MODE_TX, { LOW, HIGH } }, + { LR11x0::MODE_TX_HP, { LOW, HIGH } }, + { LR11x0::MODE_TX_HF, { LOW, LOW } }, + { LR11x0::MODE_GNSS, { LOW, LOW } }, + { LR11x0::MODE_WIFI, { LOW, LOW } }, + END_OF_MODE_TABLE, + }; + radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); + + // LR1121 TCXO Voltage 2.85~3.15V + radio.setTCXO(3.0); +#endif + +#ifdef RADIO_RX_PIN + // SX1280 PA Version + radio.setRfSwitchPins(RADIO_RX_PIN, RADIO_TX_PIN); +#endif + + // start transmitting the first packet + Serial.print(F("Radio Sending first packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + transmissionState = radio.startTransmit(String(counter).c_str()); + + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + state = radio.startTransmit(byteArr, 8); + */ + delay(1000); + + drawMain(); +} + +void loop() +{ + // check if the previous transmission finished + if (transmittedFlag) { + + payload = "#" + String(counter++); + + // reset flag + transmittedFlag = false; + + if (transmissionState == RADIOLIB_ERR_NONE) { + // packet was successfully sent + Serial.println(F("transmission finished!")); + // NOTE: when using interrupt-driven transmit method, + // it is not possible to automatically measure + // transmission data rate using getDataRate() + } else { + Serial.print(F("failed, code ")); + Serial.println(transmissionState); + } + + + drawMain(); + // wait a second before transmitting again + delay(1000); + + // send another one + Serial.print(F("Radio Sending another packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + transmissionState = radio.startTransmit(payload); + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + int state = radio.startTransmit(byteArr, 8); + */ + + } +} + + +void drawMain() +{ + if (u8g2) { + u8g2->clearBuffer(); + u8g2->drawRFrame(0, 0, 128, 64, 5); + + u8g2->setFont(u8g2_font_pxplusibmvga8_mr); + u8g2->setCursor(22, 25); + u8g2->print("TX:"); + u8g2->setCursor(22, 40); + u8g2->print("STATE:"); + + u8g2->setFont(u8g2_font_crox1h_tr); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(payload.c_str()) - 21, 25 ); + u8g2->print(payload); + String state = transmissionState == RADIOLIB_ERR_NONE ? "NONE" : String(transmissionState); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(state.c_str()) - 21, 40 ); + u8g2->print(state); + u8g2->sendBuffer(); + } +} + + + +bool beginDisplay() +{ + Wire.beginTransmission(DISPLAY_ADDR); + if (Wire.endTransmission() == 0) { + Serial.printf("Find Display model at 0x%X address\n", DISPLAY_ADDR); + u8g2 = new DISPLAY_MODEL(U8G2_R0, U8X8_PIN_NONE); + u8g2->begin(); + u8g2->clearBuffer(); + u8g2->setFont(u8g2_font_inb19_mr); + u8g2->drawStr(0, 30, "LilyGo"); + u8g2->drawHLine(2, 35, 47); + u8g2->drawHLine(3, 36, 47); + u8g2->drawVLine(45, 32, 12); + u8g2->drawVLine(46, 33, 12); + u8g2->setFont(u8g2_font_inb19_mf); + u8g2->drawStr(58, 60, "LoRa"); + u8g2->sendBuffer(); + u8g2->setFont(u8g2_font_fur11_tf); + delay(3000); + return true; + } + + Serial.printf("Warning: Failed to find Display at 0x%0X address\n", DISPLAY_ADDR); + return false; +} + + + +void printResult(bool radio_online) +{ + Serial.print("Radio : "); + Serial.println((radio_online) ? "+" : "-"); + Serial.print("PSRAM : "); + Serial.println((psramFound()) ? "+" : "-"); + Serial.print("Display : "); + Serial.println(( u8g2) ? "+" : "-"); + Serial.print("Sd Card : "); + Serial.println((SD.cardSize() != 0) ? "+" : "-"); + +#ifdef HAS_PMU + Serial.print("Power : "); + Serial.println(( PMU ) ? "+" : "-"); +#endif + + + if (u8g2) { + + u8g2->clearBuffer(); + u8g2->setFont(u8g2_font_NokiaLargeBold_tf ); + uint16_t str_w = u8g2->getStrWidth("T-ETH"); + u8g2->drawStr((u8g2->getWidth() - str_w) / 2, 16, "T-ETH"); + u8g2->drawHLine(5, 21, u8g2->getWidth() - 5); + u8g2->drawStr( 0, 38, "Disp:"); u8g2->drawStr( 45, 38, ( u8g2) ? "+" : "-"); + u8g2->drawStr( 0, 54, "SD :"); u8g2->drawStr( 45, 54, (SD.cardSize() != 0) ? "+" : "-"); + u8g2->drawStr( 62, 38, "Radio:"); u8g2->drawStr( 120, 38, ( radio_online ) ? "+" : "-"); + +#ifdef HAS_PMU + u8g2->drawStr( 62, 54, "Power:"); u8g2->drawStr( 120, 54, ( PMU ) ? "+" : "-"); +#endif + + u8g2->sendBuffer(); + + } +} \ No newline at end of file diff --git a/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/T-ETH-Elite-Gateway-Shield.ino b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/T-ETH-Elite-Gateway-Shield.ino new file mode 100644 index 0000000..25d59d0 --- /dev/null +++ b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/T-ETH-Elite-Gateway-Shield.ino @@ -0,0 +1,242 @@ +/** + * @file T-ETH-Elite-Gateway-Shield.ino + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd + * @date 2024-04-18 + * @note It is only used to test whether SX1302 is connected and whether GPS is working properly. + * If the message "No GPS data received" appears, please check whether the GPS switch on the back of the T-ETH-Elite-Gateway-Shield board has been turned to the ON side. + */ +#include +#include +#include "utilities.h" +#include "loragw_reg.h" +#include "loragw_hal.h" +#include "loragw_spi.h" + +#include +TinyGPSPlus gps; + +#define LGW_TOTALREGS 1044 +#define SX1302_REG_COMMON_CTRL0_CLK32_RIF_CTRL 1 +#define LGW_REG_SUCCESS 0 +#define LGW_REG_ERROR -1 +extern const struct lgw_reg_s loregs[LGW_TOTALREGS + 1]; + +// The baud rate may not be suitable for all GPS modules. Adjust the baud rate according to your own GPS module. +#define GPS_BAUD 9600 +#define GPSSerial Serial1 + +void test_loragw_reg(); + + +// This custom version of delay() ensures that the gps object +// is being "fed". +static void smartDelay(unsigned long ms) +{ + unsigned long start = millis(); + do { + while (GPSSerial.available()) { + + // Serial.write(GPSSerial.read()); + gps.encode(GPSSerial.read()); + } + } while (millis() - start < ms); +} + +static void printFloat(float val, bool valid, int len, int prec) +{ + if (!valid) { + while (len-- > 1) + Serial.print('*'); + Serial.print(' '); + } else { + Serial.print(val, prec); + int vi = abs((int)val); + int flen = prec + (val < 0.0 ? 2 : 1); // . and - + flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1; + for (int i = flen; i < len; ++i) + Serial.print(' '); + } + smartDelay(0); +} + +static void printInt(unsigned long val, bool valid, int len) +{ + char sz[32] = "*****************"; + if (valid) + sprintf(sz, "%ld", val); + sz[len] = 0; + for (int i = strlen(sz); i < len; ++i) + sz[i] = ' '; + if (len > 0) + sz[len - 1] = ' '; + Serial.print(sz); + smartDelay(0); +} + +static void printDateTime(TinyGPSDate &d, TinyGPSTime &t) +{ + if (!d.isValid()) { + Serial.print(F("********** ")); + } else { + char sz[32]; + sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year()); + Serial.print(sz); + } + + if (!t.isValid()) { + Serial.print(F("******** ")); + } else { + char sz[32]; + sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second()); + Serial.print(sz); + } + + printInt(d.age(), d.isValid(), 5); + smartDelay(0); +} + +static void printStr(const char *str, int len) +{ + int slen = strlen(str); + for (int i = 0; i < len; ++i) + Serial.print(i < slen ? str[i] : ' '); + smartDelay(0); +} + + +void setup() +{ + Serial.begin(115200); + + GPSSerial.begin(GPS_BAUD, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + + while (lgw_connect("") != LGW_REG_SUCCESS) { + while (1) { + Serial.printf("ERROR: failed to connect\n"); delay(1000); + } + } + test_loragw_reg(); + + Serial.println("-----------------"); + Serial.println("GPS Start ......"); +} + +void loop() +{ + if (gps.location.isValid() && gps.time.isValid() && gps.date.isValid()) { + printInt(gps.satellites.value(), gps.satellites.isValid(), 5); + printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1); + printFloat(gps.location.lat(), gps.location.isValid(), 11, 6); + printFloat(gps.location.lng(), gps.location.isValid(), 12, 6); + printInt(gps.location.age(), gps.location.isValid(), 5); + printDateTime(gps.date, gps.time); + printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2); + printFloat(gps.course.deg(), gps.course.isValid(), 7, 2); + printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2); + printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6); + printInt(gps.charsProcessed(), true, 6); + printInt(gps.sentencesWithFix(), true, 10); + printInt(gps.failedChecksum(), true, 9); + Serial.println(); + } else { + Serial.print("."); + } + smartDelay(1000); + if (millis() > 5000 && gps.charsProcessed() < 10) { + Serial.println(F("No GPS data received: check wiring")); + Serial.println(F("Please check whether the GPS switch on the back of the T-ETH-Elite-Gateway-Shield board has been turned to the ON side.")); + delay(500); + } +} + + +void test_loragw_reg() +{ + int x, i; + int32_t val; + bool error_found = false; + uint8_t rand_values[LGW_TOTALREGS]; + bool reg_ignored[LGW_TOTALREGS]; /* store register to be ignored */ + uint8_t reg_val; + uint8_t reg_max; + + uint8_t data = 0; + + /* The following registers cannot be tested this way */ + memset(reg_ignored, 0, sizeof reg_ignored); + reg_ignored[SX1302_REG_COMMON_CTRL0_CLK32_RIF_CTRL] = true; /* all test fails if we set this one to 1 */ + + /* Test 1: read all registers and check default value for non-read-only registers */ + Serial.printf("## TEST#1: read all registers and check default value for non-read-only registers\n"); + error_found = false; + for (i = 0; i < LGW_TOTALREGS; i++) { + if (loregs[i].rdon == 0) { + x = lgw_reg_r(i, &val); + if (x != LGW_REG_SUCCESS) { + Serial.printf("ERROR: failed to read register at index %d\n", i); + return; + } + if (val != loregs[i].dflt) { + Serial.printf("ERROR: default value for register at index %d is %d, should be %d\n", i, val, loregs[i].dflt); + error_found = true; + } + } + } + Serial.printf("------------------\n"); + Serial.printf(" TEST#1 %s\n", (error_found == false) ? "PASSED" : "FAILED"); + Serial.printf("------------------\n\n"); + + /* Test 2: read/write test on all non-read-only, non-pulse, non-w0clr, non-w1clr registers */ + Serial.printf("## TEST#2: read/write test on all non-read-only, non-pulse, non-w0clr, non-w1clr registers\n"); + /* Write all registers with a random value */ + error_found = false; + for (i = 0; i < LGW_TOTALREGS; i++) { + if ((loregs[i].rdon == 0) && (reg_ignored[i] == false)) { + /* Peek a random value different form the default reg value */ + reg_max = pow(2, loregs[i].leng) - 1; + if (loregs[i].leng == 1) { + reg_val = !loregs[i].dflt; + } else { + /* ensure random value is not the default one */ + do { + if (loregs[i].sign == 1) { + reg_val = rand() % (reg_max / 2); + } else { + reg_val = rand() % reg_max; + } + } while (reg_val == loregs[i].dflt); + } + /* Write selected value */ + x = lgw_reg_w(i, reg_val); + if (x != LGW_REG_SUCCESS) { + Serial.printf("ERROR: failed to read register at index %d\n", i); + return ; + } + /* store value for later check */ + rand_values[i] = reg_val; + } + } + /* Read all registers and check if we got proper random value back */ + for (i = 0; i < LGW_TOTALREGS; i++) { + if ((loregs[i].rdon == 0) && (loregs[i].chck == 1) && (reg_ignored[i] == false)) { + x = lgw_reg_r(i, &val); + if (x != LGW_REG_SUCCESS) { + Serial.printf("ERROR: failed to read register at index %d\n", i); + return ; + } + /* check value */ + if (val != rand_values[i]) { + Serial.printf("ERROR: value read from register at index %d differs from the written value (w:%u r:%d)\n", i, rand_values[i], val); + error_found = true; + } else { + //Serial.printf("INFO: MATCH reg %d (%u, %u)\n", i, rand_values[i], (uint8_t)val); + } + } + } + Serial.printf("------------------\n"); + Serial.printf(" TEST#2 %s\n", (error_found == false) ? "PASSED" : "FAILED"); + Serial.printf("------------------\n\n"); + delay(2000); +} \ No newline at end of file diff --git a/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_hal.h b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_hal.h new file mode 100644 index 0000000..d47246d --- /dev/null +++ b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_hal.h @@ -0,0 +1,470 @@ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2019 Semtech + +Description: + LoRa concentrator Hardware Abstraction Layer + +License: Revised BSD License, see LICENSE.TXT file include in the project +*/ + + +#ifndef _LORAGW_HAL_H +#define _LORAGW_HAL_H + +/* -------------------------------------------------------------------------- */ +/* --- DEPENDANCIES --------------------------------------------------------- */ + +#include /* C99 types */ +#include /* bool type */ + + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC MACROS -------------------------------------------------------- */ + +#define IS_LORA_BW(bw) ((bw == BW_125KHZ) || (bw == BW_250KHZ) || (bw == BW_500KHZ)) +#define IS_LORA_DR(dr) ((dr == DR_LORA_SF5) || (dr == DR_LORA_SF6) || (dr == DR_LORA_SF7) || (dr == DR_LORA_SF8) || (dr == DR_LORA_SF9) || (dr == DR_LORA_SF10) || (dr == DR_LORA_SF11) || (dr == DR_LORA_SF12)) +#define IS_LORA_CR(cr) ((cr == CR_LORA_4_5) || (cr == CR_LORA_4_6) || (cr == CR_LORA_4_7) || (cr == CR_LORA_4_8)) + +#define IS_FSK_BW(bw) ((bw >= 1) && (bw <= 7)) +#define IS_FSK_DR(dr) ((dr >= DR_FSK_MIN) && (dr <= DR_FSK_MAX)) + +#define IS_TX_MODE(mode) ((mode == IMMEDIATE) || (mode == TIMESTAMPED) || (mode == ON_GPS)) + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC CONSTANTS ----------------------------------------------------- */ + +/* return status code */ +#define LGW_HAL_SUCCESS 0 +#define LGW_HAL_ERROR -1 +#define LGW_LBT_ISSUE 1 + +/* radio-specific parameters */ +#define LGW_XTAL_FREQU 32000000 /* frequency of the RF reference oscillator */ +#define LGW_RF_CHAIN_NB 2 /* number of RF chains */ +#define LGW_RF_RX_BANDWIDTH {1000000, 1000000} /* bandwidth of the radios */ + +/* concentrator chipset-specific parameters */ +/* to use array parameters, declare a local const and use 'if_chain' as index */ +#define LGW_IF_CHAIN_NB 10 /* number of IF+modem RX chains */ +#define LGW_REF_BW 125000 /* typical bandwidth of data channel */ +#define LGW_MULTI_NB 8 /* number of LoRa 'multi SF' chains */ + +/* values available for the 'modulation' parameters */ +/* NOTE: arbitrary values */ +#define MOD_UNDEFINED 0 +#define MOD_CW 0x08 +#define MOD_LORA 0x10 +#define MOD_FSK 0x20 + +/* values available for the 'bandwidth' parameters (LoRa & FSK) */ +/* NOTE: directly encode FSK RX bandwidth, do not change */ +#define BW_UNDEFINED 0 +#define BW_500KHZ 0x06 +#define BW_250KHZ 0x05 +#define BW_125KHZ 0x04 + +/* values available for the 'datarate' parameters */ +/* NOTE: LoRa values used directly to code SF bitmask in 'multi' modem, do not change */ +#define DR_UNDEFINED 0 +#define DR_LORA_SF5 5 +#define DR_LORA_SF6 6 +#define DR_LORA_SF7 7 +#define DR_LORA_SF8 8 +#define DR_LORA_SF9 9 +#define DR_LORA_SF10 10 +#define DR_LORA_SF11 11 +#define DR_LORA_SF12 12 +/* NOTE: for FSK directly use baudrate between 500 bauds and 250 kbauds */ +#define DR_FSK_MIN 500 +#define DR_FSK_MAX 250000 + +/* values available for the 'coderate' parameters (LoRa only) */ +/* NOTE: arbitrary values */ +#define CR_UNDEFINED 0 +#define CR_LORA_4_5 0x01 +#define CR_LORA_4_6 0x02 +#define CR_LORA_4_7 0x03 +#define CR_LORA_4_8 0x04 + +/* values available for the 'status' parameter */ +/* NOTE: values according to hardware specification */ +#define STAT_UNDEFINED 0x00 +#define STAT_NO_CRC 0x01 +#define STAT_CRC_BAD 0x11 +#define STAT_CRC_OK 0x10 + +/* values available for the 'tx_mode' parameter */ +#define IMMEDIATE 0 +#define TIMESTAMPED 1 +#define ON_GPS 2 + +/* values available for 'select' in the status function */ +#define TX_STATUS 1 +#define RX_STATUS 2 + +/* status code for TX_STATUS */ +/* NOTE: arbitrary values */ +#define TX_STATUS_UNKNOWN 0 +#define TX_OFF 1 /* TX modem disabled, it will ignore commands */ +#define TX_FREE 2 /* TX modem is free, ready to receive a command */ +#define TX_SCHEDULED 3 /* TX modem is loaded, ready to send the packet after an event and/or delay */ +#define TX_EMITTING 4 /* TX modem is emitting */ + +/* status code for RX_STATUS */ +/* NOTE: arbitrary values */ +#define RX_STATUS_UNKNOWN 0 +#define RX_OFF 1 /* RX modem is disabled, it will ignore commands */ +#define RX_ON 2 /* RX modem is receiving */ +#define RX_SUSPENDED 3 /* RX is suspended while a TX is ongoing */ + +/* Maximum size of Tx gain LUT */ +#define TX_GAIN_LUT_SIZE_MAX 16 + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC TYPES --------------------------------------------------------- */ + +/** +@enum lgw_radio_type_t +@brief Radio types that can be found on the LoRa Gateway +*/ +typedef enum { + LGW_RADIO_TYPE_NONE, + LGW_RADIO_TYPE_SX1255, + LGW_RADIO_TYPE_SX1257, + LGW_RADIO_TYPE_SX1272, + LGW_RADIO_TYPE_SX1276, + LGW_RADIO_TYPE_SX1250 +} lgw_radio_type_t; + +/** +@struct lgw_conf_board_s +@brief Configuration structure for board specificities +*/ +struct lgw_conf_board_s { + bool lorawan_public; /*!> Enable ONLY for *public* networks using the LoRa MAC protocol */ + uint8_t clksrc; /*!> Index of RF chain which provides clock to concentrator */ + bool full_duplex; /*!> Indicates if the gateway operates in full duplex mode or not */ + char spidev_path[64];/*!> Path to access the SPI device to connect to the SX1302 */ +}; + +/** +@struct lgw_rssi_tcomp_s +@brief Structure containing all coefficients necessary to compute the offset to be applied on RSSI for current temperature +*/ +struct lgw_rssi_tcomp_s { + float coeff_a; + float coeff_b; + float coeff_c; + float coeff_d; + float coeff_e; +}; + +/** +@struct lgw_conf_rxrf_s +@brief Configuration structure for a RF chain +*/ +struct lgw_conf_rxrf_s { + bool enable; /*!> enable or disable that RF chain */ + uint32_t freq_hz; /*!> center frequency of the radio in Hz */ + float rssi_offset; /*!> Board-specific RSSI correction factor */ + struct lgw_rssi_tcomp_s rssi_tcomp; /*!> Board-specific RSSI temperature compensation coefficients */ + lgw_radio_type_t type; /*!> Radio type for that RF chain (SX1255, SX1257....) */ + bool tx_enable; /*!> enable or disable TX on that RF chain */ + bool single_input_mode; /*!> Configure the radio in single or differential input mode (SX1250 only) */ +}; + +/** +@struct lgw_conf_rxif_s +@brief Configuration structure for an IF chain +*/ +struct lgw_conf_rxif_s { + bool enable; /*!> enable or disable that IF chain */ + uint8_t rf_chain; /*!> to which RF chain is that IF chain associated */ + int32_t freq_hz; /*!> center frequ of the IF chain, relative to RF chain frequency */ + uint8_t bandwidth; /*!> RX bandwidth, 0 for default */ + uint32_t datarate; /*!> RX datarate, 0 for default */ + uint8_t sync_word_size; /*!> size of FSK sync word (number of bytes, 0 for default) */ + uint64_t sync_word; /*!> FSK sync word (ALIGN RIGHT, eg. 0xC194C1) */ + bool implicit_hdr; /*!> LoRa Service implicit header */ + uint8_t implicit_payload_length; /*!> LoRa Service implicit header payload length (number of bytes, 0 for default) */ + bool implicit_crc_en; /*!> LoRa Service implicit header CRC enable */ + uint8_t implicit_coderate; /*!> LoRa Service implicit header coding rate */ +}; + +/** +@struct lgw_pkt_rx_s +@brief Structure containing the metadata of a packet that was received and a pointer to the payload +*/ +struct lgw_pkt_rx_s { + uint32_t freq_hz; /*!> central frequency of the IF chain */ + int32_t freq_offset; + uint8_t if_chain; /*!> by which IF chain was packet received */ + uint8_t status; /*!> status of the received packet */ + uint32_t count_us; /*!> internal concentrator counter for timestamping, 1 microsecond resolution */ + uint8_t rf_chain; /*!> through which RF chain the packet was received */ + uint8_t modem_id; + uint8_t modulation; /*!> modulation used by the packet */ + uint8_t bandwidth; /*!> modulation bandwidth (LoRa only) */ + uint32_t datarate; /*!> RX datarate of the packet (SF for LoRa) */ + uint8_t coderate; /*!> error-correcting code of the packet (LoRa only) */ + float rssic; /*!> average RSSI of the channel in dB */ + float rssis; /*!> average RSSI of the signal in dB */ + float snr; /*!> average packet SNR, in dB (LoRa only) */ + float snr_min; /*!> minimum packet SNR, in dB (LoRa only) */ + float snr_max; /*!> maximum packet SNR, in dB (LoRa only) */ + uint16_t crc; /*!> CRC that was received in the payload */ + uint16_t size; /*!> payload size in bytes */ + uint8_t payload[256]; /*!> buffer containing the payload */ +}; + +/** +@struct lgw_pkt_tx_s +@brief Structure containing the configuration of a packet to send and a pointer to the payload +*/ +struct lgw_pkt_tx_s { + uint32_t freq_hz; /*!> center frequency of TX */ + uint8_t tx_mode; /*!> select on what event/time the TX is triggered */ + uint32_t count_us; /*!> timestamp or delay in microseconds for TX trigger */ + uint8_t rf_chain; /*!> through which RF chain will the packet be sent */ + int8_t rf_power; /*!> TX power, in dBm */ + uint8_t modulation; /*!> modulation to use for the packet */ + int8_t freq_offset; /*!> frequency offset from Radio Tx frequency (CW mode) */ + uint8_t bandwidth; /*!> modulation bandwidth (LoRa only) */ + uint32_t datarate; /*!> TX datarate (baudrate for FSK, SF for LoRa) */ + uint8_t coderate; /*!> error-correcting code of the packet (LoRa only) */ + bool invert_pol; /*!> invert signal polarity, for orthogonal downlinks (LoRa only) */ + uint8_t f_dev; /*!> frequency deviation, in kHz (FSK only) */ + uint16_t preamble; /*!> set the preamble length, 0 for default */ + bool no_crc; /*!> if true, do not send a CRC in the packet */ + bool no_header; /*!> if true, enable implicit header mode (LoRa), fixed length (FSK) */ + uint16_t size; /*!> payload size in bytes */ + uint8_t payload[256]; /*!> buffer containing the payload */ +}; + +/** +@struct lgw_tx_gain_s +@brief Structure containing all gains of Tx chain +*/ +struct lgw_tx_gain_s { + int8_t rf_power; /*!> measured TX power at the board connector, in dBm */ + uint8_t dig_gain; /*!> (sx125x) 2 bits: control of the digital gain of SX1302 */ + uint8_t pa_gain; /*!> (sx125x) 2 bits: control of the external PA (SX1302 I/O) + (sx1250) 1 bits: enable/disable the external PA (SX1302 I/O) */ + uint8_t dac_gain; /*!> (sx125x) 2 bits: control of the radio DAC */ + uint8_t mix_gain; /*!> (sx125x) 4 bits: control of the radio mixer */ + int8_t offset_i; /*!> (sx125x) calibrated I offset */ + int8_t offset_q; /*!> (sx125x) calibrated Q offset */ + uint8_t pwr_idx; /*!> (sx1250) 6 bits: control the radio power index to be used for configuration */ +}; + +/** +@struct lgw_tx_gain_lut_s +@brief Structure defining the Tx gain LUT +*/ +struct lgw_tx_gain_lut_s { + struct lgw_tx_gain_s lut[TX_GAIN_LUT_SIZE_MAX]; /*!> Array of Tx gain struct */ + uint8_t size; /*!> Number of LUT indexes */ +}; + +/** +@struct lgw_conf_debug_s +@brief Configuration structure for debug +*/ +struct conf_ref_payload_s { + uint32_t id; + uint8_t payload[255]; + uint32_t prev_cnt; +}; +struct lgw_conf_debug_s { + uint8_t nb_ref_payload; + struct conf_ref_payload_s ref_payload[16]; + char log_file_name[128]; +}; + +/** +@struct lgw_conf_debug_s +@brief Configuration structure for debug +*/ +struct lgw_conf_timestamp_s { + bool enable_precision_ts; + uint8_t max_ts_metrics; + uint8_t nb_symbols; +}; + +/** +@struct lgw_context_s +@brief Configuration context shared across modules +*/ +typedef struct lgw_context_s { + /* Global context */ + bool is_started; + struct lgw_conf_board_s board_cfg; + /* RX context */ + struct lgw_conf_rxrf_s rf_chain_cfg[LGW_RF_CHAIN_NB]; + struct lgw_conf_rxif_s if_chain_cfg[LGW_IF_CHAIN_NB]; + struct lgw_conf_rxif_s lora_service_cfg; /* LoRa service channel config parameters */ + struct lgw_conf_rxif_s fsk_cfg; /* FSK channel config parameters */ + /* TX context */ + struct lgw_tx_gain_lut_s tx_gain_lut[LGW_RF_CHAIN_NB]; + /* Misc */ + struct lgw_conf_timestamp_s timestamp_cfg; + /* Debug */ + struct lgw_conf_debug_s debug_cfg; +} lgw_context_t; + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */ + +/** +@brief Configure the gateway board +@param conf structure containing the configuration parameters +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_board_setconf(struct lgw_conf_board_s *conf); + +/** +@brief Configure an RF chain (must configure before start) +@param rf_chain number of the RF chain to configure [0, LGW_RF_CHAIN_NB - 1] +@param conf structure containing the configuration parameters +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_rxrf_setconf(uint8_t rf_chain, struct lgw_conf_rxrf_s *conf); + +/** +@brief Configure an IF chain + modem (must configure before start) +@param if_chain number of the IF chain + modem to configure [0, LGW_IF_CHAIN_NB - 1] +@param conf structure containing the configuration parameters +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_rxif_setconf(uint8_t if_chain, struct lgw_conf_rxif_s *conf); + +/** +@brief Configure the Tx gain LUT +@param pointer to structure defining the LUT +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_txgain_setconf(uint8_t rf_chain, struct lgw_tx_gain_lut_s *conf); + +/** +@brief Configure the precision timestamp +@param pointer to structure defining the config to be applied +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_timestamp_setconf(struct lgw_conf_timestamp_s *conf); + +/** +@brief Configure the debug context +@param pointer to structure defining the config to be applied +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_debug_setconf(struct lgw_conf_debug_s *conf); + +/** +@brief Connect to the LoRa concentrator, reset it and configure it according to previously set parameters +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_start(void); + +/** +@brief Stop the LoRa concentrator and disconnect it +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_stop(void); + +/** +@brief A non-blocking function that will fetch up to 'max_pkt' packets from the LoRa concentrator FIFO and data buffer +@param max_pkt maximum number of packet that must be retrieved (equal to the size of the array of struct) +@param pkt_data pointer to an array of struct that will receive the packet metadata and payload pointers +@return LGW_HAL_ERROR id the operation failed, else the number of packets retrieved +*/ +int lgw_receive(uint8_t max_pkt, struct lgw_pkt_rx_s *pkt_data); + +/** +@brief Schedule a packet to be send immediately or after a delay depending on tx_mode +@param pkt_data structure containing the data and metadata for the packet to send +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else + +/!\ When sending a packet, there is a delay (approx 1.5ms) for the analog +circuitry to start and be stable. This delay is adjusted by the HAL depending +on the board version (lgw_i_tx_start_delay_us). + +In 'timestamp' mode, this is transparent: the modem is started +lgw_i_tx_start_delay_us microseconds before the user-set timestamp value is +reached, the preamble of the packet start right when the internal timestamp +counter reach target value. + +In 'immediate' mode, the packet is emitted as soon as possible: transferring the +packet (and its parameters) from the host to the concentrator takes some time, +then there is the lgw_i_tx_start_delay_us, then the packet is emitted. + +In 'triggered' mode (aka PPS/GPS mode), the packet, typically a beacon, is +emitted lgw_i_tx_start_delay_us microsenconds after a rising edge of the +trigger signal. Because there is no way to anticipate the triggering event and +start the analog circuitry beforehand, that delay must be taken into account in +the protocol. +*/ +int lgw_send(struct lgw_pkt_tx_s *pkt_data); + +/** +@brief Give the the status of different part of the LoRa concentrator +@param select is used to select what status we want to know +@param code is used to return the status code +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_status(uint8_t rf_chain, uint8_t select, uint8_t *code); + +/** +@brief Abort a currently scheduled or ongoing TX +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_abort_tx(uint8_t rf_chain); + +/** +@brief Return value of internal counter when latest event (eg GPS pulse) was captured +@param trig_cnt_us pointer to receive timestamp value +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_get_trigcnt(uint32_t *trig_cnt_us); + +/** +@brief Return instateneous value of internal counter +@param inst_cnt_us pointer to receive timestamp value +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_get_instcnt(uint32_t *inst_cnt_us); + +/** +@brief Return the LoRa concentrator EUI +@param eui pointer to receive eui +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_get_eui(uint64_t *eui); + +/** +@brief Return the temperature measured by the LoRa concentrator sensor +@param temperature The temperature measured, in degree celcius +@return LGW_HAL_ERROR id the operation failed, LGW_HAL_SUCCESS else +*/ +int lgw_get_temperature(float *temperature); + +/** +@brief Allow user to check the version/options of the library once compiled +@return pointer on a human-readable null terminated string +*/ +const char *lgw_version_info(void); + +/** +@brief Return time on air of given packet, in milliseconds +@param packet is a pointer to the packet structure +@return the packet time on air in milliseconds +*/ +uint32_t lgw_time_on_air(struct lgw_pkt_tx_s *packet); + +#endif + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_reg.c b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_reg.c new file mode 100644 index 0000000..b1c8af0 --- /dev/null +++ b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_reg.c @@ -0,0 +1,1495 @@ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2019 Semtech + +Description: + Functions used to handle a single LoRa SX1302 concentrator. + Registers are addressed by name. + Multi-bytes registers are handled automatically. + Read-modify-write is handled automatically. + +License: Revised BSD License, see LICENSE.TXT file include in the project +*/ + + +/* -------------------------------------------------------------------------- */ +/* --- DEPENDANCIES --------------------------------------------------------- */ + +#include /* C99 types */ +#include /* bool type */ +#include /* printf fprintf */ + +#include "loragw_spi.h" +#include "loragw_reg.h" + +/* -------------------------------------------------------------------------- */ +/* --- PRIVATE MACROS ------------------------------------------------------- */ + + +/* -------------------------------------------------------------------------- */ +/* --- PRIVATE CONSTANTS ---------------------------------------------------- */ + +#define SX1302_REG_EXT_MEM_PAGED_BASE_ADDR 0x0 +#define SX1302_REG_RX_BUFFER_BASE_ADDR 0x4000 +#define SX1302_REG_TX_TOP_A_BASE_ADDR 0x5200 +#define SX1302_REG_TX_TOP_B_BASE_ADDR 0x5400 +#define SX1302_REG_COMMON_BASE_ADDR 0x5600 +#define SX1302_REG_GPIO_BASE_ADDR 0x5640 +#define SX1302_REG_MBIST_BASE_ADDR 0x56c0 +#define SX1302_REG_RADIO_FE_BASE_ADDR 0x5700 +#define SX1302_REG_AGC_MCU_BASE_ADDR 0x5780 +#define SX1302_REG_CLK_CTRL_BASE_ADDR 0x57c0 +#define SX1302_REG_RX_TOP_BASE_ADDR 0x5800 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR 0x5b00 +#define SX1302_REG_CAPTURE_RAM_BASE_ADDR 0x6000 +#define SX1302_REG_ARB_MCU_BASE_ADDR 0x6080 +#define SX1302_REG_TIMESTAMP_BASE_ADDR 0x6100 +#define SX1302_REG_OTP_BASE_ADDR 0x6180 + +const struct lgw_reg_s loregs[LGW_TOTALREGS+1] = { + {0,SX1302_REG_COMMON_BASE_ADDR+0,0,0,2,0,1,0}, // COMMON_PAGE_PAGE + {0,SX1302_REG_COMMON_BASE_ADDR+1,4,0,1,0,1,0}, // COMMON_CTRL0_CLK32_RIF_CTRL + {0,SX1302_REG_COMMON_BASE_ADDR+1,3,0,1,0,1,1}, // COMMON_CTRL0_HOST_RADIO_CTRL + {0,SX1302_REG_COMMON_BASE_ADDR+1,2,0,1,0,1,0}, // COMMON_CTRL0_RADIO_MISC_EN + {0,SX1302_REG_COMMON_BASE_ADDR+1,1,0,1,0,1,1}, // COMMON_CTRL0_SX1261_MODE_RADIO_B + {0,SX1302_REG_COMMON_BASE_ADDR+1,0,0,1,0,1,1}, // COMMON_CTRL0_SX1261_MODE_RADIO_A + {0,SX1302_REG_COMMON_BASE_ADDR+2,3,0,1,0,1,0}, // COMMON_CTRL1_SWAP_IQ_RADIO_B + {0,SX1302_REG_COMMON_BASE_ADDR+2,2,0,1,0,1,1}, // COMMON_CTRL1_SAMPLING_EDGE_RADIO_B + {0,SX1302_REG_COMMON_BASE_ADDR+2,1,0,1,0,1,0}, // COMMON_CTRL1_SWAP_IQ_RADIO_A + {0,SX1302_REG_COMMON_BASE_ADDR+2,0,0,1,0,1,1}, // COMMON_CTRL1_SAMPLING_EDGE_RADIO_A + {0,SX1302_REG_COMMON_BASE_ADDR+3,0,0,8,0,1,2}, // COMMON_SPI_DIV_RATIO_SPI_HALF_PERIOD + {0,SX1302_REG_COMMON_BASE_ADDR+4,0,0,8,0,1,128}, // COMMON_RADIO_SELECT_RADIO_SELECT + {0,SX1302_REG_COMMON_BASE_ADDR+5,3,0,1,0,1,0}, // COMMON_GEN_GLOBAL_EN + {0,SX1302_REG_COMMON_BASE_ADDR+5,2,0,1,0,1,0}, // COMMON_GEN_FSK_MODEM_ENABLE + {0,SX1302_REG_COMMON_BASE_ADDR+5,1,0,1,0,1,0}, // COMMON_GEN_CONCENTRATOR_MODEM_ENABLE + {0,SX1302_REG_COMMON_BASE_ADDR+5,0,0,1,0,1,0}, // COMMON_GEN_MBWSSF_MODEM_ENABLE + {0,SX1302_REG_COMMON_BASE_ADDR+6,0,0,8,1,1,16}, // COMMON_VERSION_VERSION + {0,SX1302_REG_COMMON_BASE_ADDR+7,0,0,1,1,1,0}, // COMMON_DUMMY_DUMMY + {0,SX1302_REG_AGC_MCU_BASE_ADDR+0,4,0,1,0,1,1}, // AGC_MCU_CTRL_CLK_EN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+0,3,0,1,0,1,0}, // AGC_MCU_CTRL_FORCE_HOST_FE_CTRL + {0,SX1302_REG_AGC_MCU_BASE_ADDR+0,2,0,1,0,1,1}, // AGC_MCU_CTRL_MCU_CLEAR + {0,SX1302_REG_AGC_MCU_BASE_ADDR+0,1,0,1,0,1,0}, // AGC_MCU_CTRL_HOST_PROG + {0,SX1302_REG_AGC_MCU_BASE_ADDR+0,0,0,1,1,1,0}, // AGC_MCU_CTRL_PARITY_ERROR + {0,SX1302_REG_AGC_MCU_BASE_ADDR+1,0,0,8,1,1,0}, // AGC_MCU_MCU_AGC_STATUS_MCU_AGC_STATUS + {0,SX1302_REG_AGC_MCU_BASE_ADDR+2,2,0,2,0,1,0}, // AGC_MCU_PA_GAIN_PA_B_GAIN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+2,0,0,2,0,1,0}, // AGC_MCU_PA_GAIN_PA_A_GAIN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+3,3,0,1,0,1,0}, // AGC_MCU_RF_EN_A_RADIO_RST + {0,SX1302_REG_AGC_MCU_BASE_ADDR+3,2,0,1,0,1,0}, // AGC_MCU_RF_EN_A_RADIO_EN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+3,1,0,1,0,1,0}, // AGC_MCU_RF_EN_A_PA_EN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+3,0,0,1,0,1,0}, // AGC_MCU_RF_EN_A_LNA_EN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+4,3,0,1,0,1,0}, // AGC_MCU_RF_EN_B_RADIO_RST + {0,SX1302_REG_AGC_MCU_BASE_ADDR+4,2,0,1,0,1,0}, // AGC_MCU_RF_EN_B_RADIO_EN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+4,1,0,1,0,1,0}, // AGC_MCU_RF_EN_B_PA_EN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+4,0,0,1,0,1,0}, // AGC_MCU_RF_EN_B_LNA_EN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+5,4,0,4,0,1,0}, // AGC_MCU_LUT_TABLE_A_PA_LUT + {0,SX1302_REG_AGC_MCU_BASE_ADDR+5,0,0,4,0,1,0}, // AGC_MCU_LUT_TABLE_A_LNA_LUT + {0,SX1302_REG_AGC_MCU_BASE_ADDR+6,4,0,4,0,1,0}, // AGC_MCU_LUT_TABLE_B_PA_LUT + {0,SX1302_REG_AGC_MCU_BASE_ADDR+6,0,0,4,0,1,0}, // AGC_MCU_LUT_TABLE_B_LNA_LUT + {0,SX1302_REG_AGC_MCU_BASE_ADDR+7,5,0,1,0,1,0}, // AGC_MCU_UART_CFG_MSBF + {0,SX1302_REG_AGC_MCU_BASE_ADDR+7,4,0,1,0,1,0}, // AGC_MCU_UART_CFG_PAR_EN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+7,3,0,1,0,1,0}, // AGC_MCU_UART_CFG_PAR_MODE + {0,SX1302_REG_AGC_MCU_BASE_ADDR+7,2,0,1,0,1,0}, // AGC_MCU_UART_CFG_START_LEN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+7,1,0,1,0,1,0}, // AGC_MCU_UART_CFG_STOP_LEN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+7,0,0,1,0,1,1}, // AGC_MCU_UART_CFG_WORD_LEN + {0,SX1302_REG_AGC_MCU_BASE_ADDR+8,0,0,8,0,1,0}, // AGC_MCU_UART_CFG2_BIT_RATE + {0,SX1302_REG_AGC_MCU_BASE_ADDR+9,0,0,8,0,1,0}, // AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE3_MCU_MAIL_BOX_WR_DATA + {0,SX1302_REG_AGC_MCU_BASE_ADDR+10,0,0,8,0,1,0}, // AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE2_MCU_MAIL_BOX_WR_DATA + {0,SX1302_REG_AGC_MCU_BASE_ADDR+11,0,0,8,0,1,0}, // AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE1_MCU_MAIL_BOX_WR_DATA + {0,SX1302_REG_AGC_MCU_BASE_ADDR+12,0,0,8,0,1,0}, // AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE0_MCU_MAIL_BOX_WR_DATA + {0,SX1302_REG_AGC_MCU_BASE_ADDR+13,0,0,8,1,1,0}, // AGC_MCU_MCU_MAIL_BOX_RD_DATA_BYTE3_MCU_MAIL_BOX_RD_DATA + {0,SX1302_REG_AGC_MCU_BASE_ADDR+14,0,0,8,1,1,0}, // AGC_MCU_MCU_MAIL_BOX_RD_DATA_BYTE2_MCU_MAIL_BOX_RD_DATA + {0,SX1302_REG_AGC_MCU_BASE_ADDR+15,0,0,8,1,1,0}, // AGC_MCU_MCU_MAIL_BOX_RD_DATA_BYTE1_MCU_MAIL_BOX_RD_DATA + {0,SX1302_REG_AGC_MCU_BASE_ADDR+16,0,0,8,1,1,0}, // AGC_MCU_MCU_MAIL_BOX_RD_DATA_BYTE0_MCU_MAIL_BOX_RD_DATA + {0,SX1302_REG_AGC_MCU_BASE_ADDR+17,0,0,1,1,1,0}, // AGC_MCU_DUMMY_DUMMY3 + {0,SX1302_REG_CLK_CTRL_BASE_ADDR+0,2,0,1,0,1,0}, // CLK_CTRL_CLK_SEL_CLKDIV_EN + {0,SX1302_REG_CLK_CTRL_BASE_ADDR+0,1,0,1,0,1,0}, // CLK_CTRL_CLK_SEL_CLK_RADIO_B_SEL + {0,SX1302_REG_CLK_CTRL_BASE_ADDR+0,0,0,1,0,1,0}, // CLK_CTRL_CLK_SEL_CLK_RADIO_A_SEL + {0,SX1302_REG_CLK_CTRL_BASE_ADDR+1,3,0,1,1,1,0}, // CLK_CTRL_DUMMY_DUMMY + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+0,3,0,1,0,0,0}, // TX_TOP_A_TX_TRIG_TX_FSM_CLR + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+0,2,0,1,0,1,0}, // TX_TOP_A_TX_TRIG_TX_TRIG_GPS + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+0,1,0,1,0,1,0}, // TX_TOP_A_TX_TRIG_TX_TRIG_DELAYED + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+0,0,0,1,0,1,0}, // TX_TOP_A_TX_TRIG_TX_TRIG_IMMEDIATE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+1,0,0,8,0,1,0}, // TX_TOP_A_TIMER_TRIG_BYTE3_TIMER_DELAYED_TRIG + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+2,0,0,8,0,1,0}, // TX_TOP_A_TIMER_TRIG_BYTE2_TIMER_DELAYED_TRIG + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+3,0,0,8,0,1,0}, // TX_TOP_A_TIMER_TRIG_BYTE1_TIMER_DELAYED_TRIG + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+4,0,0,8,0,1,0}, // TX_TOP_A_TIMER_TRIG_BYTE0_TIMER_DELAYED_TRIG + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+5,0,0,8,0,1,187}, // TX_TOP_A_TX_START_DELAY_MSB_TX_START_DELAY + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+6,0,0,8,0,1,128}, // TX_TOP_A_TX_START_DELAY_LSB_TX_START_DELAY + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+7,0,0,1,0,1,0}, // TX_TOP_A_TX_CTRL_WRITE_BUFFER + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+8,0,0,3,0,1,1}, // TX_TOP_A_TX_RAMP_DURATION_TX_RAMP_DURATION + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+9,0,0,1,0,1,0}, // TX_TOP_A_GEN_CFG_0_MODULATION_TYPE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+10,1,0,1,0,1,0}, // TX_TOP_A_TEST_0_TX_ACTIVE_CTRL + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+10,0,0,1,0,1,0}, // TX_TOP_A_TEST_0_TX_ACTIVE_SEL + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+11,1,0,1,0,0,0}, // TX_TOP_A_TX_FLAG_TX_TIMEOUT + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+11,0,0,1,0,0,0}, // TX_TOP_A_TX_FLAG_PKT_DONE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+12,0,0,8,0,1,0}, // TX_TOP_A_AGC_TX_BW_AGC_TX_BW + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+13,0,0,8,0,1,0}, // TX_TOP_A_AGC_TX_PWR_AGC_TX_PWR + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+14,0,0,8,0,1,0}, // TX_TOP_A_TIMEOUT_CNT_BYTE_2_TIMEOUT_CNT + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+15,0,0,8,0,1,0}, // TX_TOP_A_TIMEOUT_CNT_BYTE_1_TIMEOUT_CNT + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+16,0,0,8,0,1,0}, // TX_TOP_A_TIMEOUT_CNT_BYTE_0_TIMEOUT_CNT + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+17,0,0,8,1,1,0}, // TX_TOP_A_TX_FSM_STATUS_TX_STATUS + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+18,3,0,1,1,1,0}, // TX_TOP_A_DUMMY_CONTROL_DUMMY + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+32,5,0,3,0,1,0}, // TX_TOP_A_TX_RFFE_IF_CTRL_PLL_DIV_CTRL + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+32,4,0,1,0,1,1}, // TX_TOP_A_TX_RFFE_IF_CTRL_TX_CLK_EDGE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+32,3,0,1,0,1,1}, // TX_TOP_A_TX_RFFE_IF_CTRL_TX_MODE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+32,2,0,1,0,1,0}, // TX_TOP_A_TX_RFFE_IF_CTRL_TX_IF_DST + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+32,0,0,2,0,1,0}, // TX_TOP_A_TX_RFFE_IF_CTRL_TX_IF_SRC + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+33,1,0,1,0,1,0}, // TX_TOP_A_TX_RFFE_IF_CTRL2_SX125X_IQ_INVERT + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+33,0,0,1,0,1,0}, // TX_TOP_A_TX_RFFE_IF_CTRL2_PLL_DIV_CTRL_AGC + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+34,0,0,2,0,1,0}, // TX_TOP_A_TX_RFFE_IF_IQ_GAIN_IQ_GAIN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+35,0,0,8,0,1,0}, // TX_TOP_A_TX_RFFE_IF_I_OFFSET_I_OFFSET + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+36,0,0,8,0,1,0}, // TX_TOP_A_TX_RFFE_IF_Q_OFFSET_Q_OFFSET + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+37,0,0,8,0,1,108}, // TX_TOP_A_TX_RFFE_IF_FREQ_RF_H_FREQ_RF + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+38,0,0,8,0,1,144}, // TX_TOP_A_TX_RFFE_IF_FREQ_RF_M_FREQ_RF + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+39,0,0,8,0,1,0}, // TX_TOP_A_TX_RFFE_IF_FREQ_RF_L_FREQ_RF + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+40,0,0,4,0,1,0}, // TX_TOP_A_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+41,0,0,8,0,1,0}, // TX_TOP_A_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+42,0,0,8,0,1,64}, // TX_TOP_A_TX_RFFE_IF_TEST_MOD_FREQ + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+43,3,0,1,1,1,0}, // TX_TOP_A_DUMMY_MODULATOR_DUMMY + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+64,0,0,8,0,1,15}, // TX_TOP_A_FSK_PKT_LEN_PKT_LENGTH + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+65,5,0,1,0,1,0}, // TX_TOP_A_FSK_CFG_0_TX_CONT + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+65,4,0,1,0,1,0}, // TX_TOP_A_FSK_CFG_0_CRC_IBM + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+65,2,0,2,0,1,0}, // TX_TOP_A_FSK_CFG_0_DCFREE_ENC + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+65,1,0,1,0,1,1}, // TX_TOP_A_FSK_CFG_0_CRC_EN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+65,0,0,1,0,1,0}, // TX_TOP_A_FSK_CFG_0_PKT_MODE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+66,0,0,8,0,1,0}, // TX_TOP_A_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+67,0,0,8,0,1,20}, // TX_TOP_A_FSK_PREAMBLE_SIZE_LSB_PREAMBLE_SIZE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+68,0,0,8,0,1,26}, // TX_TOP_A_FSK_BIT_RATE_MSB_BIT_RATE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+69,0,0,8,0,1,11}, // TX_TOP_A_FSK_BIT_RATE_LSB_BIT_RATE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+70,5,0,3,0,1,3}, // TX_TOP_A_FSK_MOD_FSK_REF_PATTERN_SIZE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+70,4,0,1,0,1,0}, // TX_TOP_A_FSK_MOD_FSK_PREAMBLE_SEQ + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+70,3,0,1,0,1,1}, // TX_TOP_A_FSK_MOD_FSK_REF_PATTERN_EN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+70,1,0,2,0,1,0}, // TX_TOP_A_FSK_MOD_FSK_GAUSSIAN_SELECT_BT + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+70,0,0,1,0,1,0}, // TX_TOP_A_FSK_MOD_FSK_GAUSSIAN_EN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+71,0,0,8,0,1,151}, // TX_TOP_A_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+72,0,0,8,0,1,35}, // TX_TOP_A_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+73,0,0,8,0,1,82}, // TX_TOP_A_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+74,0,0,8,0,1,37}, // TX_TOP_A_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+75,0,0,8,0,1,86}, // TX_TOP_A_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+76,0,0,8,0,1,83}, // TX_TOP_A_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+77,0,0,8,0,1,101}, // TX_TOP_A_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+78,0,0,8,0,1,100}, // TX_TOP_A_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+79,3,0,1,1,1,0}, // TX_TOP_A_DUMMY_GSFK_DUMMY + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+96,4,0,4,0,1,5}, // TX_TOP_A_TXRX_CFG0_0_MODEM_BW + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+96,0,0,4,0,1,7}, // TX_TOP_A_TXRX_CFG0_0_MODEM_SF + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+97,6,0,2,0,1,2}, // TX_TOP_A_TXRX_CFG0_1_PPM_OFFSET_HDR_CTRL + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+97,4,0,2,0,1,0}, // TX_TOP_A_TXRX_CFG0_1_PPM_OFFSET + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+97,3,0,1,0,1,0}, // TX_TOP_A_TXRX_CFG0_1_POST_PREAMBLE_GAP_LONG + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+97,0,0,3,0,1,2}, // TX_TOP_A_TXRX_CFG0_1_CODING_RATE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+98,7,0,1,0,1,0}, // TX_TOP_A_TXRX_CFG0_2_FINE_SYNCH_EN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+98,6,0,1,0,1,0}, // TX_TOP_A_TXRX_CFG0_2_MODEM_EN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+98,4,0,2,0,1,2}, // TX_TOP_A_TXRX_CFG0_2_CADRXTX + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+98,1,0,1,0,1,0}, // TX_TOP_A_TXRX_CFG0_2_IMPLICIT_HEADER + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+98,0,0,1,0,1,1}, // TX_TOP_A_TXRX_CFG0_2_CRC_EN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+99,0,0,8,0,1,12}, // TX_TOP_A_TXRX_CFG0_3_PAYLOAD_LENGTH + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+100,7,0,1,0,1,0}, // TX_TOP_A_TXRX_CFG1_0_INT_STEP_ORIDE_EN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+100,0,0,6,0,1,0}, // TX_TOP_A_TXRX_CFG1_0_INT_STEP_ORIDE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+101,7,0,1,0,1,0}, // TX_TOP_A_TXRX_CFG1_1_MODEM_START + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+101,6,0,1,0,1,0}, // TX_TOP_A_TXRX_CFG1_1_HEADER_DIFF_MODE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+101,0,0,6,0,1,0}, // TX_TOP_A_TXRX_CFG1_1_ZERO_PAD + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+102,0,0,8,0,1,8}, // TX_TOP_A_TXRX_CFG1_2_PREAMBLE_SYMB_NB + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+103,0,0,8,0,1,0}, // TX_TOP_A_TXRX_CFG1_3_PREAMBLE_SYMB_NB + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+104,6,0,1,0,1,1}, // TX_TOP_A_TXRX_CFG1_4_AUTO_ACK_INT_DELAY + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+104,5,0,1,0,1,0}, // TX_TOP_A_TXRX_CFG1_4_AUTO_ACK_RX + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+104,4,0,1,0,1,0}, // TX_TOP_A_TXRX_CFG1_4_AUTO_ACK_TX + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+105,4,0,3,0,1,0}, // TX_TOP_A_TX_CFG0_0_CHIRP_LOWPASS + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+105,3,0,1,0,1,0}, // TX_TOP_A_TX_CFG0_0_PPM_OFFSET_SIG + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+105,2,0,1,0,1,1}, // TX_TOP_A_TX_CFG0_0_CONTCHIRP + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+105,1,0,1,0,1,1}, // TX_TOP_A_TX_CFG0_0_CHIRP_INVERT + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+105,0,0,1,0,1,0}, // TX_TOP_A_TX_CFG0_0_CONTINUOUS + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+106,0,0,6,0,1,20}, // TX_TOP_A_TX_CFG0_1_POWER_RANGING + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+107,0,0,8,0,1,0}, // TX_TOP_A_TX_CFG1_0_FRAME_NB + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+108,5,0,2,0,1,0}, // TX_TOP_A_TX_CFG1_1_HOP_CTRL + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+108,0,0,5,0,1,10}, // TX_TOP_A_TX_CFG1_1_IFS + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+109,7,0,1,0,1,1}, // TX_TOP_A_FRAME_SYNCH_0_AUTO_SCALE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+109,6,0,1,0,1,0}, // TX_TOP_A_FRAME_SYNCH_0_DROP_ON_SYNCH + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+109,5,0,1,0,1,1}, // TX_TOP_A_FRAME_SYNCH_0_GAIN + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+109,0,1,5,0,1,2}, // TX_TOP_A_FRAME_SYNCH_0_PEAK1_POS + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+110,7,0,1,0,1,0}, // TX_TOP_A_FRAME_SYNCH_1_FINETIME_ON_LAST + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+110,5,0,2,0,1,3}, // TX_TOP_A_FRAME_SYNCH_1_TIMEOUT_OPT + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+110,0,1,5,0,1,4}, // TX_TOP_A_FRAME_SYNCH_1_PEAK2_POS + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+111,0,0,4,1,1,0}, // TX_TOP_A_LORA_TX_STATE_STATUS + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+112,2,0,1,0,0,0}, // TX_TOP_A_LORA_TX_FLAG_FRAME_DONE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+112,1,0,1,0,0,0}, // TX_TOP_A_LORA_TX_FLAG_CONT_DONE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+112,0,0,1,0,0,0}, // TX_TOP_A_LORA_TX_FLAG_PLD_DONE + {0,SX1302_REG_TX_TOP_A_BASE_ADDR+113,3,0,1,1,1,0}, // TX_TOP_A_DUMMY_LORA_DUMMY + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+0,3,0,1,0,0,0}, // TX_TOP_B_TX_TRIG_TX_FSM_CLR + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+0,2,0,1,0,1,0}, // TX_TOP_B_TX_TRIG_TX_TRIG_GPS + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+0,1,0,1,0,1,0}, // TX_TOP_B_TX_TRIG_TX_TRIG_DELAYED + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+0,0,0,1,0,1,0}, // TX_TOP_B_TX_TRIG_TX_TRIG_IMMEDIATE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+1,0,0,8,0,1,0}, // TX_TOP_B_TIMER_TRIG_BYTE3_TIMER_DELAYED_TRIG + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+2,0,0,8,0,1,0}, // TX_TOP_B_TIMER_TRIG_BYTE2_TIMER_DELAYED_TRIG + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+3,0,0,8,0,1,0}, // TX_TOP_B_TIMER_TRIG_BYTE1_TIMER_DELAYED_TRIG + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+4,0,0,8,0,1,0}, // TX_TOP_B_TIMER_TRIG_BYTE0_TIMER_DELAYED_TRIG + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+5,0,0,8,0,1,187}, // TX_TOP_B_TX_START_DELAY_MSB_TX_START_DELAY + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+6,0,0,8,0,1,128}, // TX_TOP_B_TX_START_DELAY_LSB_TX_START_DELAY + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+7,0,0,1,0,1,0}, // TX_TOP_B_TX_CTRL_WRITE_BUFFER + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+8,0,0,3,0,1,1}, // TX_TOP_B_TX_RAMP_DURATION_TX_RAMP_DURATION + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+9,0,0,1,0,1,0}, // TX_TOP_B_GEN_CFG_0_MODULATION_TYPE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+10,1,0,1,0,1,0}, // TX_TOP_B_TEST_0_TX_ACTIVE_CTRL + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+10,0,0,1,0,1,0}, // TX_TOP_B_TEST_0_TX_ACTIVE_SEL + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+11,1,0,1,0,0,0}, // TX_TOP_B_TX_FLAG_TX_TIMEOUT + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+11,0,0,1,0,0,0}, // TX_TOP_B_TX_FLAG_PKT_DONE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+12,0,0,8,0,1,0}, // TX_TOP_B_AGC_TX_BW_AGC_TX_BW + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+13,0,0,8,0,1,0}, // TX_TOP_B_AGC_TX_PWR_AGC_TX_PWR + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+14,0,0,8,0,1,0}, // TX_TOP_B_TIMEOUT_CNT_BYTE_2_TIMEOUT_CNT + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+15,0,0,8,0,1,0}, // TX_TOP_B_TIMEOUT_CNT_BYTE_1_TIMEOUT_CNT + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+16,0,0,8,0,1,0}, // TX_TOP_B_TIMEOUT_CNT_BYTE_0_TIMEOUT_CNT + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+17,0,0,8,1,1,0}, // TX_TOP_B_TX_FSM_STATUS_TX_STATUS + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+18,3,0,1,1,1,0}, // TX_TOP_B_DUMMY_CONTROL_DUMMY + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+32,5,0,3,0,1,0}, // TX_TOP_B_TX_RFFE_IF_CTRL_PLL_DIV_CTRL + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+32,4,0,1,0,1,1}, // TX_TOP_B_TX_RFFE_IF_CTRL_TX_CLK_EDGE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+32,3,0,1,0,1,1}, // TX_TOP_B_TX_RFFE_IF_CTRL_TX_MODE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+32,2,0,1,0,1,0}, // TX_TOP_B_TX_RFFE_IF_CTRL_TX_IF_DST + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+32,0,0,2,0,1,0}, // TX_TOP_B_TX_RFFE_IF_CTRL_TX_IF_SRC + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+33,1,0,1,0,1,0}, // TX_TOP_B_TX_RFFE_IF_CTRL2_SX125X_IQ_INVERT + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+33,0,0,1,0,1,0}, // TX_TOP_B_TX_RFFE_IF_CTRL2_PLL_DIV_CTRL_AGC + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+34,0,0,2,0,1,0}, // TX_TOP_B_TX_RFFE_IF_IQ_GAIN_IQ_GAIN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+35,0,0,8,0,1,0}, // TX_TOP_B_TX_RFFE_IF_I_OFFSET_I_OFFSET + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+36,0,0,8,0,1,0}, // TX_TOP_B_TX_RFFE_IF_Q_OFFSET_Q_OFFSET + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+37,0,0,8,0,1,108}, // TX_TOP_B_TX_RFFE_IF_FREQ_RF_H_FREQ_RF + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+38,0,0,8,0,1,144}, // TX_TOP_B_TX_RFFE_IF_FREQ_RF_M_FREQ_RF + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+39,0,0,8,0,1,0}, // TX_TOP_B_TX_RFFE_IF_FREQ_RF_L_FREQ_RF + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+40,0,0,4,0,1,0}, // TX_TOP_B_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+41,0,0,8,0,1,0}, // TX_TOP_B_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+42,0,0,8,0,1,64}, // TX_TOP_B_TX_RFFE_IF_TEST_MOD_FREQ + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+43,3,0,1,1,1,0}, // TX_TOP_B_DUMMY_MODULATOR_DUMMY + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+64,0,0,8,0,1,15}, // TX_TOP_B_FSK_PKT_LEN_PKT_LENGTH + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+65,5,0,1,0,1,0}, // TX_TOP_B_FSK_CFG_0_TX_CONT + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+65,4,0,1,0,1,0}, // TX_TOP_B_FSK_CFG_0_CRC_IBM + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+65,2,0,2,0,1,0}, // TX_TOP_B_FSK_CFG_0_DCFREE_ENC + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+65,1,0,1,0,1,1}, // TX_TOP_B_FSK_CFG_0_CRC_EN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+65,0,0,1,0,1,0}, // TX_TOP_B_FSK_CFG_0_PKT_MODE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+66,0,0,8,0,1,0}, // TX_TOP_B_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+67,0,0,8,0,1,20}, // TX_TOP_B_FSK_PREAMBLE_SIZE_LSB_PREAMBLE_SIZE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+68,0,0,8,0,1,26}, // TX_TOP_B_FSK_BIT_RATE_MSB_BIT_RATE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+69,0,0,8,0,1,11}, // TX_TOP_B_FSK_BIT_RATE_LSB_BIT_RATE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+70,5,0,3,0,1,3}, // TX_TOP_B_FSK_MOD_FSK_REF_PATTERN_SIZE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+70,4,0,1,0,1,0}, // TX_TOP_B_FSK_MOD_FSK_PREAMBLE_SEQ + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+70,3,0,1,0,1,1}, // TX_TOP_B_FSK_MOD_FSK_REF_PATTERN_EN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+70,1,0,2,0,1,0}, // TX_TOP_B_FSK_MOD_FSK_GAUSSIAN_SELECT_BT + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+70,0,0,1,0,1,0}, // TX_TOP_B_FSK_MOD_FSK_GAUSSIAN_EN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+71,0,0,8,0,1,151}, // TX_TOP_B_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+72,0,0,8,0,1,35}, // TX_TOP_B_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+73,0,0,8,0,1,82}, // TX_TOP_B_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+74,0,0,8,0,1,37}, // TX_TOP_B_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+75,0,0,8,0,1,86}, // TX_TOP_B_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+76,0,0,8,0,1,83}, // TX_TOP_B_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+77,0,0,8,0,1,101}, // TX_TOP_B_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+78,0,0,8,0,1,100}, // TX_TOP_B_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+79,3,0,1,1,1,0}, // TX_TOP_B_DUMMY_GSFK_DUMMY + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+96,4,0,4,0,1,5}, // TX_TOP_B_TXRX_CFG0_0_MODEM_BW + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+96,0,0,4,0,1,7}, // TX_TOP_B_TXRX_CFG0_0_MODEM_SF + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+97,6,0,2,0,1,2}, // TX_TOP_B_TXRX_CFG0_1_PPM_OFFSET_HDR_CTRL + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+97,4,0,2,0,1,0}, // TX_TOP_B_TXRX_CFG0_1_PPM_OFFSET + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+97,3,0,1,0,1,0}, // TX_TOP_B_TXRX_CFG0_1_POST_PREAMBLE_GAP_LONG + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+97,0,0,3,0,1,2}, // TX_TOP_B_TXRX_CFG0_1_CODING_RATE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+98,7,0,1,0,1,0}, // TX_TOP_B_TXRX_CFG0_2_FINE_SYNCH_EN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+98,6,0,1,0,1,0}, // TX_TOP_B_TXRX_CFG0_2_MODEM_EN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+98,4,0,2,0,1,2}, // TX_TOP_B_TXRX_CFG0_2_CADRXTX + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+98,1,0,1,0,1,0}, // TX_TOP_B_TXRX_CFG0_2_IMPLICIT_HEADER + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+98,0,0,1,0,1,1}, // TX_TOP_B_TXRX_CFG0_2_CRC_EN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+99,0,0,8,0,1,12}, // TX_TOP_B_TXRX_CFG0_3_PAYLOAD_LENGTH + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+100,7,0,1,0,1,0}, // TX_TOP_B_TXRX_CFG1_0_INT_STEP_ORIDE_EN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+100,0,0,6,0,1,0}, // TX_TOP_B_TXRX_CFG1_0_INT_STEP_ORIDE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+101,7,0,1,0,1,0}, // TX_TOP_B_TXRX_CFG1_1_MODEM_START + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+101,6,0,1,0,1,0}, // TX_TOP_B_TXRX_CFG1_1_HEADER_DIFF_MODE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+101,0,0,6,0,1,0}, // TX_TOP_B_TXRX_CFG1_1_ZERO_PAD + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+102,0,0,8,0,1,8}, // TX_TOP_B_TXRX_CFG1_2_PREAMBLE_SYMB_NB + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+103,0,0,8,0,1,0}, // TX_TOP_B_TXRX_CFG1_3_PREAMBLE_SYMB_NB + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+104,6,0,1,0,1,1}, // TX_TOP_B_TXRX_CFG1_4_AUTO_ACK_INT_DELAY + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+104,5,0,1,0,1,0}, // TX_TOP_B_TXRX_CFG1_4_AUTO_ACK_RX + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+104,4,0,1,0,1,0}, // TX_TOP_B_TXRX_CFG1_4_AUTO_ACK_TX + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+105,4,0,3,0,1,0}, // TX_TOP_B_TX_CFG0_0_CHIRP_LOWPASS + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+105,3,0,1,0,1,0}, // TX_TOP_B_TX_CFG0_0_PPM_OFFSET_SIG + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+105,2,0,1,0,1,1}, // TX_TOP_B_TX_CFG0_0_CONTCHIRP + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+105,1,0,1,0,1,1}, // TX_TOP_B_TX_CFG0_0_CHIRP_INVERT + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+105,0,0,1,0,1,0}, // TX_TOP_B_TX_CFG0_0_CONTINUOUS + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+106,0,0,6,0,1,20}, // TX_TOP_B_TX_CFG0_1_POWER_RANGING + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+107,0,0,8,0,1,0}, // TX_TOP_B_TX_CFG1_0_FRAME_NB + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+108,5,0,2,0,1,0}, // TX_TOP_B_TX_CFG1_1_HOP_CTRL + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+108,0,0,5,0,1,10}, // TX_TOP_B_TX_CFG1_1_IFS + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+109,7,0,1,0,1,1}, // TX_TOP_B_FRAME_SYNCH_0_AUTO_SCALE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+109,6,0,1,0,1,0}, // TX_TOP_B_FRAME_SYNCH_0_DROP_ON_SYNCH + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+109,5,0,1,0,1,1}, // TX_TOP_B_FRAME_SYNCH_0_GAIN + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+109,0,1,5,0,1,2}, // TX_TOP_B_FRAME_SYNCH_0_PEAK1_POS + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+110,7,0,1,0,1,0}, // TX_TOP_B_FRAME_SYNCH_1_FINETIME_ON_LAST + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+110,5,0,2,0,1,3}, // TX_TOP_B_FRAME_SYNCH_1_TIMEOUT_OPT + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+110,0,1,5,0,1,4}, // TX_TOP_B_FRAME_SYNCH_1_PEAK2_POS + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+111,0,0,4,1,1,0}, // TX_TOP_B_LORA_TX_STATE_STATUS + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+112,2,0,1,0,0,0}, // TX_TOP_B_LORA_TX_FLAG_FRAME_DONE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+112,1,0,1,0,0,0}, // TX_TOP_B_LORA_TX_FLAG_CONT_DONE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+112,0,0,1,0,0,0}, // TX_TOP_B_LORA_TX_FLAG_PLD_DONE + {0,SX1302_REG_TX_TOP_B_BASE_ADDR+113,3,0,1,1,1,0}, // TX_TOP_B_DUMMY_LORA_DUMMY + {0,SX1302_REG_GPIO_BASE_ADDR+0,0,0,4,0,1,0}, // GPIO_GPIO_DIR_H_DIRECTION + {0,SX1302_REG_GPIO_BASE_ADDR+1,0,0,8,0,1,0}, // GPIO_GPIO_DIR_L_DIRECTION + {0,SX1302_REG_GPIO_BASE_ADDR+2,0,0,4,0,1,0}, // GPIO_GPIO_OUT_H_OUT_VALUE + {0,SX1302_REG_GPIO_BASE_ADDR+3,0,0,8,0,1,0}, // GPIO_GPIO_OUT_L_OUT_VALUE + {0,SX1302_REG_GPIO_BASE_ADDR+4,0,0,4,1,1,0}, // GPIO_GPIO_IN_H_IN_VALUE + {0,SX1302_REG_GPIO_BASE_ADDR+5,0,0,8,1,1,0}, // GPIO_GPIO_IN_L_IN_VALUE + {0,SX1302_REG_GPIO_BASE_ADDR+6,0,0,4,0,1,0}, // GPIO_GPIO_PD_H_PD_VALUE + {0,SX1302_REG_GPIO_BASE_ADDR+7,0,0,8,0,1,0}, // GPIO_GPIO_PD_L_PD_VALUE + {0,SX1302_REG_GPIO_BASE_ADDR+8,0,0,4,0,1,0}, // GPIO_GPIO_SEL_0_SELECTION + {0,SX1302_REG_GPIO_BASE_ADDR+9,0,0,4,0,1,0}, // GPIO_GPIO_SEL_1_SELECTION + {0,SX1302_REG_GPIO_BASE_ADDR+10,0,0,4,0,1,0}, // GPIO_GPIO_SEL_2_SELECTION + {0,SX1302_REG_GPIO_BASE_ADDR+11,0,0,4,0,1,0}, // GPIO_GPIO_SEL_3_SELECTION + {0,SX1302_REG_GPIO_BASE_ADDR+12,0,0,4,0,1,0}, // GPIO_GPIO_SEL_4_SELECTION + {0,SX1302_REG_GPIO_BASE_ADDR+13,0,0,4,0,1,0}, // GPIO_GPIO_SEL_5_SELECTION + {0,SX1302_REG_GPIO_BASE_ADDR+14,0,0,4,0,1,0}, // GPIO_GPIO_SEL_6_SELECTION + {0,SX1302_REG_GPIO_BASE_ADDR+15,0,0,4,0,1,0}, // GPIO_GPIO_SEL_7_SELECTION + {0,SX1302_REG_GPIO_BASE_ADDR+16,1,0,4,0,1,0}, // GPIO_GPIO_SEL_8_11_GPIO_11_9_SEL + {0,SX1302_REG_GPIO_BASE_ADDR+16,0,0,1,0,1,0}, // GPIO_GPIO_SEL_8_11_GPIO_8_SEL + {0,SX1302_REG_GPIO_BASE_ADDR+17,5,0,1,0,0,0}, // GPIO_HOST_IRQ_TX_TIMEOUT_B + {0,SX1302_REG_GPIO_BASE_ADDR+17,4,0,1,0,0,0}, // GPIO_HOST_IRQ_TX_TIMEOUT_A + {0,SX1302_REG_GPIO_BASE_ADDR+17,3,0,1,0,0,0}, // GPIO_HOST_IRQ_TX_DONE_B + {0,SX1302_REG_GPIO_BASE_ADDR+17,2,0,1,0,0,0}, // GPIO_HOST_IRQ_TX_DONE_A + {0,SX1302_REG_GPIO_BASE_ADDR+17,1,0,1,0,0,0}, // GPIO_HOST_IRQ_TIMESTAMP + {0,SX1302_REG_GPIO_BASE_ADDR+17,0,0,1,0,0,0}, // GPIO_HOST_IRQ_RX_BUFFER_WATERMARK + {0,SX1302_REG_GPIO_BASE_ADDR+18,5,0,1,0,1,0}, // GPIO_HOST_IRQ_EN_TX_TIMEOUT_B + {0,SX1302_REG_GPIO_BASE_ADDR+18,4,0,1,0,1,0}, // GPIO_HOST_IRQ_EN_TX_TIMEOUT_A + {0,SX1302_REG_GPIO_BASE_ADDR+18,3,0,1,0,1,0}, // GPIO_HOST_IRQ_EN_TX_DONE_B + {0,SX1302_REG_GPIO_BASE_ADDR+18,2,0,1,0,1,0}, // GPIO_HOST_IRQ_EN_TX_DONE_A + {0,SX1302_REG_GPIO_BASE_ADDR+18,1,0,1,0,1,0}, // GPIO_HOST_IRQ_EN_TIMESTAMP + {0,SX1302_REG_GPIO_BASE_ADDR+18,0,0,1,0,1,0}, // GPIO_HOST_IRQ_EN_RX_BUFFER_WATERMARK + {0,SX1302_REG_GPIO_BASE_ADDR+19,0,0,1,1,1,0}, // GPIO_DUMMY_DUMMY + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+0,1,0,1,0,1,0}, // TIMESTAMP_GPS_CTRL_GPS_POL + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+0,0,0,1,0,1,0}, // TIMESTAMP_GPS_CTRL_GPS_EN + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+1,0,0,8,1,1,0}, // TIMESTAMP_TIMESTAMP_PPS_MSB2_TIMESTAMP_PPS + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+2,0,0,8,1,1,0}, // TIMESTAMP_TIMESTAMP_PPS_MSB1_TIMESTAMP_PPS + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+3,0,0,8,1,1,0}, // TIMESTAMP_TIMESTAMP_PPS_LSB2_TIMESTAMP_PPS + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+4,0,0,8,1,1,0}, // TIMESTAMP_TIMESTAMP_PPS_LSB1_TIMESTAMP_PPS + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+5,0,0,8,1,1,0}, // TIMESTAMP_TIMESTAMP_MSB2_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+6,0,0,8,1,1,0}, // TIMESTAMP_TIMESTAMP_MSB1_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+7,0,0,8,1,1,0}, // TIMESTAMP_TIMESTAMP_LSB2_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+8,0,0,8,1,1,0}, // TIMESTAMP_TIMESTAMP_LSB1_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+9,0,0,8,0,1,0}, // TIMESTAMP_TIMESTAMP_SET3_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+10,0,0,8,0,1,0}, // TIMESTAMP_TIMESTAMP_SET2_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+11,0,0,8,0,1,0}, // TIMESTAMP_TIMESTAMP_SET1_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+12,0,0,8,0,1,0}, // TIMESTAMP_TIMESTAMP_SET0_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+13,0,0,8,0,1,0}, // TIMESTAMP_TIMESTAMP_IRQ_3_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+14,0,0,8,0,1,0}, // TIMESTAMP_TIMESTAMP_IRQ_2_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+15,0,0,8,0,1,0}, // TIMESTAMP_TIMESTAMP_IRQ_1_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+16,0,0,8,0,1,0}, // TIMESTAMP_TIMESTAMP_IRQ_0_TIMESTAMP + {0,SX1302_REG_TIMESTAMP_BASE_ADDR+17,0,0,1,1,1,0}, // TIMESTAMP_DUMMY_DUMMY + {0,SX1302_REG_RX_TOP_BASE_ADDR+0,0,0,5,0,1,0}, // RX_TOP_FREQ_0_MSB_IF_FREQ_0 + {0,SX1302_REG_RX_TOP_BASE_ADDR+1,0,0,8,0,1,128}, // RX_TOP_FREQ_0_LSB_IF_FREQ_0 + {0,SX1302_REG_RX_TOP_BASE_ADDR+2,0,0,5,0,1,1}, // RX_TOP_FREQ_1_MSB_IF_FREQ_1 + {0,SX1302_REG_RX_TOP_BASE_ADDR+3,0,0,8,0,1,128}, // RX_TOP_FREQ_1_LSB_IF_FREQ_1 + {0,SX1302_REG_RX_TOP_BASE_ADDR+4,0,0,5,0,1,30}, // RX_TOP_FREQ_2_MSB_IF_FREQ_2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+5,0,0,8,0,1,128}, // RX_TOP_FREQ_2_LSB_IF_FREQ_2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+6,0,0,5,0,1,0}, // RX_TOP_FREQ_3_MSB_IF_FREQ_3 + {0,SX1302_REG_RX_TOP_BASE_ADDR+7,0,0,8,0,1,128}, // RX_TOP_FREQ_3_LSB_IF_FREQ_3 + {0,SX1302_REG_RX_TOP_BASE_ADDR+8,0,0,5,0,1,0}, // RX_TOP_FREQ_4_MSB_IF_FREQ_4 + {0,SX1302_REG_RX_TOP_BASE_ADDR+9,0,0,8,0,1,50}, // RX_TOP_FREQ_4_LSB_IF_FREQ_4 + {0,SX1302_REG_RX_TOP_BASE_ADDR+10,0,0,5,0,1,0}, // RX_TOP_FREQ_5_MSB_IF_FREQ_5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+11,0,0,8,0,1,60}, // RX_TOP_FREQ_5_LSB_IF_FREQ_5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+12,0,0,5,0,1,0}, // RX_TOP_FREQ_6_MSB_IF_FREQ_6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+13,0,0,8,0,1,70}, // RX_TOP_FREQ_6_LSB_IF_FREQ_6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+14,0,0,5,0,1,0}, // RX_TOP_FREQ_7_MSB_IF_FREQ_7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+15,0,0,8,0,1,80}, // RX_TOP_FREQ_7_LSB_IF_FREQ_7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+16,0,0,8,0,1,0}, // RX_TOP_RADIO_SELECT_RADIO_SELECT + {0,SX1302_REG_RX_TOP_BASE_ADDR+17,3,0,5,0,1,7}, // RX_TOP_RSSI_CONTROL_RSSI_FILTER_ALPHA + {0,SX1302_REG_RX_TOP_BASE_ADDR+17,0,0,3,0,1,0}, // RX_TOP_RSSI_CONTROL_SELECT_RSSI + {0,SX1302_REG_RX_TOP_BASE_ADDR+18,0,0,8,0,1,0}, // RX_TOP_RSSI_DEF_VALUE_CHAN_RSSI_DEF_VALUE + {0,SX1302_REG_RX_TOP_BASE_ADDR+19,0,0,8,0,1,0}, // RX_TOP_CHANN_DAGC_CFG1_CHAN_DAGC_THRESHOLD_HIGH + {0,SX1302_REG_RX_TOP_BASE_ADDR+20,0,0,8,0,1,0}, // RX_TOP_CHANN_DAGC_CFG2_CHAN_DAGC_THRESHOLD_LOW + {0,SX1302_REG_RX_TOP_BASE_ADDR+21,4,0,4,0,1,15}, // RX_TOP_CHANN_DAGC_CFG3_CHAN_DAGC_MAX_ATTEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+21,0,0,4,0,1,0}, // RX_TOP_CHANN_DAGC_CFG3_CHAN_DAGC_MIN_ATTEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+22,0,0,4,0,1,0}, // RX_TOP_CHANN_DAGC_CFG4_CHAN_DAGC_STEP + {0,SX1302_REG_RX_TOP_BASE_ADDR+23,0,0,2,0,1,0}, // RX_TOP_CHANN_DAGC_CFG5_CHAN_DAGC_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+24,0,0,8,1,1,0}, // RX_TOP_RSSI_VALUE_CHAN_RSSI + {0,SX1302_REG_RX_TOP_BASE_ADDR+25,4,0,1,0,1,0}, // RX_TOP_GAIN_CONTROL_CHAN_GAIN_VALID + {0,SX1302_REG_RX_TOP_BASE_ADDR+25,0,0,4,0,1,0}, // RX_TOP_GAIN_CONTROL_CHAN_GAIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+26,0,0,1,0,1,1}, // RX_TOP_CLK_CONTROL_CHAN_CLK_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+27,0,0,1,1,1,0}, // RX_TOP_DUMMY0_DUMMY0 + {0,SX1302_REG_RX_TOP_BASE_ADDR+32,0,0,8,0,1,255}, // RX_TOP_CORR_CLOCK_ENABLE_CLK_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+33,0,0,8,0,1,0}, // RX_TOP_CORRELATOR_EN_CORR_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+34,0,0,8,0,1,255}, // RX_TOP_CORRELATOR_SF_EN_CORR_SF_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+35,0,0,8,0,1,255}, // RX_TOP_CORRELATOR_ENABLE_ONLY_FIRST_DET_EDGE_ENABLE_ONLY_FIRST_DET_EDGE + {0,SX1302_REG_RX_TOP_BASE_ADDR+36,0,0,8,0,1,255}, // RX_TOP_CORRELATOR_ENABLE_ACC_CLEAR_ENABLE_CORR_ACC_CLEAR + {0,SX1302_REG_RX_TOP_BASE_ADDR+37,6,0,2,0,1,2}, // RX_TOP_SF5_CFG1_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+37,5,0,1,0,1,1}, // RX_TOP_SF5_CFG1_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+37,4,0,1,0,1,1}, // RX_TOP_SF5_CFG1_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+37,2,0,2,0,1,2}, // RX_TOP_SF5_CFG1_ACC_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+37,1,0,1,0,1,1}, // RX_TOP_SF5_CFG1_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+37,0,0,1,0,1,1}, // RX_TOP_SF5_CFG1_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_BASE_ADDR+38,7,0,1,0,1,0}, // RX_TOP_SF5_CFG2_ACC_MIN2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+38,0,0,7,0,1,55}, // RX_TOP_SF5_CFG2_ACC_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+39,0,0,8,0,1,11}, // RX_TOP_SF5_CFG3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_BASE_ADDR+40,0,0,7,0,1,32}, // RX_TOP_SF5_CFG4_MSP_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+41,0,0,7,0,1,48}, // RX_TOP_SF5_CFG5_MSP2_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+42,3,0,3,0,1,5}, // RX_TOP_SF5_CFG6_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+42,1,0,2,0,1,1}, // RX_TOP_SF5_CFG6_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+42,0,0,1,0,1,1}, // RX_TOP_SF5_CFG6_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+43,2,0,3,0,1,5}, // RX_TOP_SF5_CFG7_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+43,0,0,2,0,1,2}, // RX_TOP_SF5_CFG7_NOISE_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+44,6,0,2,0,1,2}, // RX_TOP_SF6_CFG1_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+44,5,0,1,0,1,1}, // RX_TOP_SF6_CFG1_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+44,4,0,1,0,1,1}, // RX_TOP_SF6_CFG1_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+44,2,0,2,0,1,2}, // RX_TOP_SF6_CFG1_ACC_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+44,1,0,1,0,1,1}, // RX_TOP_SF6_CFG1_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+44,0,0,1,0,1,1}, // RX_TOP_SF6_CFG1_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_BASE_ADDR+45,7,0,1,0,1,0}, // RX_TOP_SF6_CFG2_ACC_MIN2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+45,0,0,7,0,1,55}, // RX_TOP_SF6_CFG2_ACC_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+46,0,0,8,0,1,11}, // RX_TOP_SF6_CFG3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_BASE_ADDR+47,0,0,7,0,1,32}, // RX_TOP_SF6_CFG4_MSP_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+48,0,0,7,0,1,48}, // RX_TOP_SF6_CFG5_MSP2_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+49,3,0,3,0,1,4}, // RX_TOP_SF6_CFG6_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+49,1,0,2,0,1,1}, // RX_TOP_SF6_CFG6_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+49,0,0,1,0,1,1}, // RX_TOP_SF6_CFG6_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+50,2,0,3,0,1,5}, // RX_TOP_SF6_CFG7_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+50,0,0,2,0,1,2}, // RX_TOP_SF6_CFG7_NOISE_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+51,6,0,2,0,1,2}, // RX_TOP_SF7_CFG1_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+51,5,0,1,0,1,1}, // RX_TOP_SF7_CFG1_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+51,4,0,1,0,1,1}, // RX_TOP_SF7_CFG1_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+51,2,0,2,0,1,2}, // RX_TOP_SF7_CFG1_ACC_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+51,1,0,1,0,1,1}, // RX_TOP_SF7_CFG1_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+51,0,0,1,0,1,1}, // RX_TOP_SF7_CFG1_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_BASE_ADDR+52,7,0,1,0,1,0}, // RX_TOP_SF7_CFG2_ACC_MIN2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+52,0,0,7,0,1,55}, // RX_TOP_SF7_CFG2_ACC_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+53,0,0,8,0,1,11}, // RX_TOP_SF7_CFG3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_BASE_ADDR+54,0,0,7,0,1,32}, // RX_TOP_SF7_CFG4_MSP_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+55,0,0,7,0,1,48}, // RX_TOP_SF7_CFG5_MSP2_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+56,3,0,3,0,1,3}, // RX_TOP_SF7_CFG6_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+56,1,0,2,0,1,1}, // RX_TOP_SF7_CFG6_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+56,0,0,1,0,1,1}, // RX_TOP_SF7_CFG6_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+57,2,0,3,0,1,5}, // RX_TOP_SF7_CFG7_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+57,0,0,2,0,1,2}, // RX_TOP_SF7_CFG7_NOISE_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+58,6,0,2,0,1,2}, // RX_TOP_SF8_CFG1_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+58,5,0,1,0,1,1}, // RX_TOP_SF8_CFG1_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+58,4,0,1,0,1,1}, // RX_TOP_SF8_CFG1_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+58,2,0,2,0,1,2}, // RX_TOP_SF8_CFG1_ACC_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+58,1,0,1,0,1,1}, // RX_TOP_SF8_CFG1_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+58,0,0,1,0,1,1}, // RX_TOP_SF8_CFG1_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_BASE_ADDR+59,7,0,1,0,1,0}, // RX_TOP_SF8_CFG2_ACC_MIN2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+59,0,0,7,0,1,56}, // RX_TOP_SF8_CFG2_ACC_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+60,0,0,8,0,1,11}, // RX_TOP_SF8_CFG3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_BASE_ADDR+61,0,0,7,0,1,32}, // RX_TOP_SF8_CFG4_MSP_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+62,0,0,7,0,1,48}, // RX_TOP_SF8_CFG5_MSP2_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+63,3,0,3,0,1,3}, // RX_TOP_SF8_CFG6_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+63,1,0,2,0,1,1}, // RX_TOP_SF8_CFG6_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+63,0,0,1,0,1,1}, // RX_TOP_SF8_CFG6_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+64,2,0,3,0,1,5}, // RX_TOP_SF8_CFG7_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+64,0,0,2,0,1,2}, // RX_TOP_SF8_CFG7_NOISE_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+65,6,0,2,0,1,2}, // RX_TOP_SF9_CFG1_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+65,5,0,1,0,1,1}, // RX_TOP_SF9_CFG1_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+65,4,0,1,0,1,1}, // RX_TOP_SF9_CFG1_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+65,2,0,2,0,1,2}, // RX_TOP_SF9_CFG1_ACC_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+65,1,0,1,0,1,1}, // RX_TOP_SF9_CFG1_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+65,0,0,1,0,1,1}, // RX_TOP_SF9_CFG1_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_BASE_ADDR+66,7,0,1,0,1,0}, // RX_TOP_SF9_CFG2_ACC_MIN2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+66,0,0,7,0,1,58}, // RX_TOP_SF9_CFG2_ACC_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+67,0,0,8,0,1,11}, // RX_TOP_SF9_CFG3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_BASE_ADDR+68,0,0,7,0,1,32}, // RX_TOP_SF9_CFG4_MSP_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+69,0,0,7,0,1,48}, // RX_TOP_SF9_CFG5_MSP2_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+70,3,0,3,0,1,3}, // RX_TOP_SF9_CFG6_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+70,1,0,2,0,1,1}, // RX_TOP_SF9_CFG6_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+70,0,0,1,0,1,1}, // RX_TOP_SF9_CFG6_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+71,2,0,3,0,1,5}, // RX_TOP_SF9_CFG7_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+71,0,0,2,0,1,2}, // RX_TOP_SF9_CFG7_NOISE_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+72,6,0,2,0,1,2}, // RX_TOP_SF10_CFG1_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+72,5,0,1,0,1,1}, // RX_TOP_SF10_CFG1_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+72,4,0,1,0,1,1}, // RX_TOP_SF10_CFG1_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+72,2,0,2,0,1,2}, // RX_TOP_SF10_CFG1_ACC_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+72,1,0,1,0,1,1}, // RX_TOP_SF10_CFG1_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+72,0,0,1,0,1,1}, // RX_TOP_SF10_CFG1_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_BASE_ADDR+73,7,0,1,0,1,0}, // RX_TOP_SF10_CFG2_ACC_MIN2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+73,0,0,7,0,1,60}, // RX_TOP_SF10_CFG2_ACC_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+74,0,0,8,0,1,11}, // RX_TOP_SF10_CFG3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_BASE_ADDR+75,0,0,7,0,1,32}, // RX_TOP_SF10_CFG4_MSP_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+76,0,0,7,0,1,48}, // RX_TOP_SF10_CFG5_MSP2_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+77,3,0,3,0,1,3}, // RX_TOP_SF10_CFG6_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+77,1,0,2,0,1,1}, // RX_TOP_SF10_CFG6_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+77,0,0,1,0,1,1}, // RX_TOP_SF10_CFG6_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+78,2,0,3,0,1,5}, // RX_TOP_SF10_CFG7_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+78,0,0,2,0,1,2}, // RX_TOP_SF10_CFG7_NOISE_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+79,6,0,2,0,1,2}, // RX_TOP_SF11_CFG1_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+79,5,0,1,0,1,1}, // RX_TOP_SF11_CFG1_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+79,4,0,1,0,1,1}, // RX_TOP_SF11_CFG1_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+79,2,0,2,0,1,2}, // RX_TOP_SF11_CFG1_ACC_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+79,1,0,1,0,1,1}, // RX_TOP_SF11_CFG1_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+79,0,0,1,0,1,1}, // RX_TOP_SF11_CFG1_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_BASE_ADDR+80,7,0,1,0,1,0}, // RX_TOP_SF11_CFG2_ACC_MIN2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+80,0,0,7,0,1,60}, // RX_TOP_SF11_CFG2_ACC_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+81,0,0,8,0,1,11}, // RX_TOP_SF11_CFG3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_BASE_ADDR+82,0,0,7,0,1,32}, // RX_TOP_SF11_CFG4_MSP_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+83,0,0,7,0,1,48}, // RX_TOP_SF11_CFG5_MSP2_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+84,3,0,3,0,1,3}, // RX_TOP_SF11_CFG6_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+84,1,0,2,0,1,1}, // RX_TOP_SF11_CFG6_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+84,0,0,1,0,1,1}, // RX_TOP_SF11_CFG6_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+85,2,0,3,0,1,5}, // RX_TOP_SF11_CFG7_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+85,0,0,2,0,1,2}, // RX_TOP_SF11_CFG7_NOISE_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+86,6,0,2,0,1,2}, // RX_TOP_SF12_CFG1_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+86,5,0,1,0,1,1}, // RX_TOP_SF12_CFG1_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+86,4,0,1,0,1,1}, // RX_TOP_SF12_CFG1_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+86,2,0,2,0,1,2}, // RX_TOP_SF12_CFG1_ACC_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+86,1,0,1,0,1,1}, // RX_TOP_SF12_CFG1_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+86,0,0,1,0,1,1}, // RX_TOP_SF12_CFG1_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_BASE_ADDR+87,7,0,1,0,1,0}, // RX_TOP_SF12_CFG2_ACC_MIN2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+87,0,0,7,0,1,60}, // RX_TOP_SF12_CFG2_ACC_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+88,0,0,8,0,1,11}, // RX_TOP_SF12_CFG3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_BASE_ADDR+89,0,0,7,0,1,32}, // RX_TOP_SF12_CFG4_MSP_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+90,0,0,7,0,1,48}, // RX_TOP_SF12_CFG5_MSP2_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+91,3,0,3,0,1,3}, // RX_TOP_SF12_CFG6_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+91,1,0,2,0,1,1}, // RX_TOP_SF12_CFG6_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+91,0,0,1,0,1,1}, // RX_TOP_SF12_CFG6_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+92,2,0,3,0,1,5}, // RX_TOP_SF12_CFG7_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+92,0,0,2,0,1,2}, // RX_TOP_SF12_CFG7_NOISE_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+93,0,0,1,1,1,0}, // RX_TOP_DUMMY1_DUMMY1 + {0,SX1302_REG_RX_TOP_BASE_ADDR+96,4,0,3,0,1,0}, // RX_TOP_DC_NOTCH_CFG1_BW_START + {0,SX1302_REG_RX_TOP_BASE_ADDR+96,3,0,1,0,1,1}, // RX_TOP_DC_NOTCH_CFG1_AUTO_BW_RED + {0,SX1302_REG_RX_TOP_BASE_ADDR+96,2,0,1,0,1,0}, // RX_TOP_DC_NOTCH_CFG1_NO_FAST_START + {0,SX1302_REG_RX_TOP_BASE_ADDR+96,1,0,1,0,1,0}, // RX_TOP_DC_NOTCH_CFG1_BYPASS + {0,SX1302_REG_RX_TOP_BASE_ADDR+96,0,0,1,0,1,0}, // RX_TOP_DC_NOTCH_CFG1_ENABLE + {0,SX1302_REG_RX_TOP_BASE_ADDR+97,3,0,3,0,1,1}, // RX_TOP_DC_NOTCH_CFG2_BW_LOCKED + {0,SX1302_REG_RX_TOP_BASE_ADDR+97,0,0,3,0,1,5}, // RX_TOP_DC_NOTCH_CFG2_BW + {0,SX1302_REG_RX_TOP_BASE_ADDR+98,0,0,3,0,1,0}, // RX_TOP_DC_NOTCH_CFG3_BW_RED + {0,SX1302_REG_RX_TOP_BASE_ADDR+99,0,0,8,0,1,0}, // RX_TOP_DC_NOTCH_CFG4_IIR_DCC_TIME + {0,SX1302_REG_RX_TOP_BASE_ADDR+100,0,1,8,0,1,2}, // RX_TOP_RX_DFE_FIR1_0_FIR1_COEFF_0 + {0,SX1302_REG_RX_TOP_BASE_ADDR+101,0,1,8,0,1,3}, // RX_TOP_RX_DFE_FIR1_1_FIR1_COEFF_1 + {0,SX1302_REG_RX_TOP_BASE_ADDR+102,0,1,8,0,1,2}, // RX_TOP_RX_DFE_FIR1_2_FIR1_COEFF_2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+103,0,1,8,0,1,3}, // RX_TOP_RX_DFE_FIR1_3_FIR1_COEFF_3 + {0,SX1302_REG_RX_TOP_BASE_ADDR+104,0,1,8,0,1,5}, // RX_TOP_RX_DFE_FIR1_4_FIR1_COEFF_4 + {0,SX1302_REG_RX_TOP_BASE_ADDR+105,0,1,8,0,1,8}, // RX_TOP_RX_DFE_FIR1_5_FIR1_COEFF_5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+106,0,1,8,0,1,6}, // RX_TOP_RX_DFE_FIR1_6_FIR1_COEFF_6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+107,0,1,8,0,1,4}, // RX_TOP_RX_DFE_FIR1_7_FIR1_COEFF_7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+108,0,1,8,0,1,2}, // RX_TOP_RX_DFE_FIR2_0_FIR2_COEFF_0 + {0,SX1302_REG_RX_TOP_BASE_ADDR+109,0,1,8,0,1,-2}, // RX_TOP_RX_DFE_FIR2_1_FIR2_COEFF_1 + {0,SX1302_REG_RX_TOP_BASE_ADDR+110,0,1,8,0,1,-4}, // RX_TOP_RX_DFE_FIR2_2_FIR2_COEFF_2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+111,0,1,8,0,1,-3}, // RX_TOP_RX_DFE_FIR2_3_FIR2_COEFF_3 + {0,SX1302_REG_RX_TOP_BASE_ADDR+112,0,1,8,0,1,3}, // RX_TOP_RX_DFE_FIR2_4_FIR2_COEFF_4 + {0,SX1302_REG_RX_TOP_BASE_ADDR+113,0,1,8,0,1,11}, // RX_TOP_RX_DFE_FIR2_5_FIR2_COEFF_5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+114,0,1,8,0,1,19}, // RX_TOP_RX_DFE_FIR2_6_FIR2_COEFF_6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+115,0,1,8,0,1,10}, // RX_TOP_RX_DFE_FIR2_7_FIR2_COEFF_7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+116,7,0,1,0,1,0}, // RX_TOP_RX_DFE_AGC0_RADIO_GAIN_RED_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+116,0,0,7,0,1,0}, // RX_TOP_RX_DFE_AGC0_RADIO_GAIN_RED_DB + {0,SX1302_REG_RX_TOP_BASE_ADDR+117,4,0,1,0,1,0}, // RX_TOP_RX_DFE_AGC1_DC_COMP_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+117,3,0,1,0,1,0}, // RX_TOP_RX_DFE_AGC1_FORCE_DEFAULT_FIR + {0,SX1302_REG_RX_TOP_BASE_ADDR+117,2,0,1,0,1,1}, // RX_TOP_RX_DFE_AGC1_RSSI_EARLY_LATCH + {0,SX1302_REG_RX_TOP_BASE_ADDR+117,0,0,2,0,1,3}, // RX_TOP_RX_DFE_AGC1_FREEZE_ON_SYNC + {0,SX1302_REG_RX_TOP_BASE_ADDR+118,6,0,1,0,1,0}, // RX_TOP_RX_DFE_AGC2_DAGC_IN_COMP + {0,SX1302_REG_RX_TOP_BASE_ADDR+118,5,0,1,0,1,1}, // RX_TOP_RX_DFE_AGC2_DAGC_FIR_HYST + {0,SX1302_REG_RX_TOP_BASE_ADDR+118,3,0,2,0,1,1}, // RX_TOP_RX_DFE_AGC2_RSSI_MAX_SAMPLE + {0,SX1302_REG_RX_TOP_BASE_ADDR+118,0,0,3,0,1,2}, // RX_TOP_RX_DFE_AGC2_RSSI_MIN_SAMPLE + {0,SX1302_REG_RX_TOP_BASE_ADDR+119,7,0,1,0,1,0}, // RX_TOP_RX_DFE_GAIN0_DAGC_FIR_FAST + {0,SX1302_REG_RX_TOP_BASE_ADDR+119,6,0,1,0,1,0}, // RX_TOP_RX_DFE_GAIN0_FORCE_GAIN_FIR + {0,SX1302_REG_RX_TOP_BASE_ADDR+119,4,0,2,0,1,3}, // RX_TOP_RX_DFE_GAIN0_GAIN_FIR1 + {0,SX1302_REG_RX_TOP_BASE_ADDR+119,0,0,3,0,1,1}, // RX_TOP_RX_DFE_GAIN0_GAIN_FIR2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+120,6,0,2,0,1,0}, // RX_TOP_DAGC_CFG_TARGET_LVL + {0,SX1302_REG_RX_TOP_BASE_ADDR+120,5,0,1,0,1,0}, // RX_TOP_DAGC_CFG_GAIN_INCR_STEP + {0,SX1302_REG_RX_TOP_BASE_ADDR+120,4,0,1,0,1,0}, // RX_TOP_DAGC_CFG_GAIN_DROP_COMP + {0,SX1302_REG_RX_TOP_BASE_ADDR+120,3,0,1,0,1,1}, // RX_TOP_DAGC_CFG_COMB_FILTER_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+120,2,0,1,0,1,0}, // RX_TOP_DAGC_CFG_NO_FREEZE_START + {0,SX1302_REG_RX_TOP_BASE_ADDR+120,0,0,2,0,1,3}, // RX_TOP_DAGC_CFG_FREEZE_ON_SYNC + {0,SX1302_REG_RX_TOP_BASE_ADDR+121,0,0,8,0,1,60}, // RX_TOP_DAGC_CNT0_SAMPLE + {0,SX1302_REG_RX_TOP_BASE_ADDR+122,0,0,8,0,1,6}, // RX_TOP_DAGC_CNT1_THR_M6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+123,0,0,8,0,1,25}, // RX_TOP_DAGC_CNT2_THR_M12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+124,0,0,8,0,1,42}, // RX_TOP_DAGC_CNT3_THR_M18 + {0,SX1302_REG_RX_TOP_BASE_ADDR+125,4,0,4,0,1,8}, // RX_TOP_DAGC_CNT4_GAIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+125,0,0,1,0,1,0}, // RX_TOP_DAGC_CNT4_FORCE_GAIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+126,6,0,2,0,1,2}, // RX_TOP_TXRX_CFG1_PPM_OFFSET_HDR_CTRL + {0,SX1302_REG_RX_TOP_BASE_ADDR+126,4,0,2,0,1,0}, // RX_TOP_TXRX_CFG1_PPM_OFFSET + {0,SX1302_REG_RX_TOP_BASE_ADDR+126,3,0,1,0,1,0}, // RX_TOP_TXRX_CFG1_MODEM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+126,0,0,3,0,1,2}, // RX_TOP_TXRX_CFG1_CODING_RATE + {0,SX1302_REG_RX_TOP_BASE_ADDR+127,4,0,1,0,0,0}, // RX_TOP_TXRX_CFG2_MODEM_START + {0,SX1302_REG_RX_TOP_BASE_ADDR+127,2,0,2,0,1,1}, // RX_TOP_TXRX_CFG2_CADRXTX + {0,SX1302_REG_RX_TOP_BASE_ADDR+127,1,0,1,0,1,0}, // RX_TOP_TXRX_CFG2_IMPLICIT_HEADER + {0,SX1302_REG_RX_TOP_BASE_ADDR+127,0,0,1,0,1,1}, // RX_TOP_TXRX_CFG2_CRC_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+128,0,0,8,0,1,12}, // RX_TOP_TXRX_CFG3_PAYLOAD_LENGTH + {0,SX1302_REG_RX_TOP_BASE_ADDR+129,7,0,1,0,1,0}, // RX_TOP_TXRX_CFG4_INT_STEP_ORIDE_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+129,0,0,6,0,1,0}, // RX_TOP_TXRX_CFG4_INT_STEP_ORIDE + {0,SX1302_REG_RX_TOP_BASE_ADDR+130,6,0,1,0,1,0}, // RX_TOP_TXRX_CFG5_HEADER_DIFF_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+130,0,0,6,0,1,0}, // RX_TOP_TXRX_CFG5_ZERO_PAD + {0,SX1302_REG_RX_TOP_BASE_ADDR+131,0,0,8,0,1,8}, // RX_TOP_TXRX_CFG6_PREAMBLE_SYMB_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+132,0,0,8,0,1,0}, // RX_TOP_TXRX_CFG7_PREAMBLE_SYMB_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+133,3,0,1,0,1,1}, // RX_TOP_TXRX_CFG8_AUTO_ACK_INT_DELAY + {0,SX1302_REG_RX_TOP_BASE_ADDR+133,2,0,1,0,1,0}, // RX_TOP_TXRX_CFG8_AUTO_ACK_RX + {0,SX1302_REG_RX_TOP_BASE_ADDR+133,1,0,1,0,1,0}, // RX_TOP_TXRX_CFG8_AUTO_ACK_TX + {0,SX1302_REG_RX_TOP_BASE_ADDR+133,0,0,1,0,1,0}, // RX_TOP_TXRX_CFG8_POST_PREAMBLE_GAP_LONG + {0,SX1302_REG_RX_TOP_BASE_ADDR+134,7,0,1,0,1,0}, // RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+134,6,0,1,0,1,0}, // RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF11 + {0,SX1302_REG_RX_TOP_BASE_ADDR+134,5,0,1,0,1,0}, // RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF10 + {0,SX1302_REG_RX_TOP_BASE_ADDR+134,4,0,1,0,1,0}, // RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF9 + {0,SX1302_REG_RX_TOP_BASE_ADDR+134,3,0,1,0,1,0}, // RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF8 + {0,SX1302_REG_RX_TOP_BASE_ADDR+134,2,0,1,0,1,0}, // RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+134,1,0,1,0,1,1}, // RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+134,0,0,1,0,1,1}, // RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+135,4,0,2,0,1,3}, // RX_TOP_RX_CFG0_DFT_PEAK_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+135,2,0,1,0,1,1}, // RX_TOP_RX_CFG0_CHIRP_INVERT + {0,SX1302_REG_RX_TOP_BASE_ADDR+135,1,0,1,0,1,0}, // RX_TOP_RX_CFG0_SWAP_IQ + {0,SX1302_REG_RX_TOP_BASE_ADDR+135,0,0,1,0,1,0}, // RX_TOP_RX_CFG0_CONTINUOUS + {0,SX1302_REG_RX_TOP_BASE_ADDR+136,0,0,8,0,1,0}, // RX_TOP_RX_CFG1_DETECT_TIMEOUT + {0,SX1302_REG_RX_TOP_BASE_ADDR+137,4,0,1,0,1,1}, // RX_TOP_RX_CFG2_CLK_EN_RESYNC_DIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+137,0,0,4,0,1,11}, // RX_TOP_RX_CFG2_LLR_SCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+138,0,1,5,0,1,2}, // RX_TOP_FRAME_SYNCH0_SF5_PEAK1_POS_SF5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+139,0,1,5,0,1,4}, // RX_TOP_FRAME_SYNCH1_SF5_PEAK2_POS_SF5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+140,0,1,5,0,1,2}, // RX_TOP_FRAME_SYNCH0_SF6_PEAK1_POS_SF6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+141,0,1,5,0,1,4}, // RX_TOP_FRAME_SYNCH1_SF6_PEAK2_POS_SF6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+142,0,1,5,0,1,2}, // RX_TOP_FRAME_SYNCH0_SF7TO12_PEAK1_POS_SF7TO12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+143,0,1,5,0,1,4}, // RX_TOP_FRAME_SYNCH1_SF7TO12_PEAK2_POS_SF7TO12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+144,5,0,1,0,1,0}, // RX_TOP_FRAME_SYNCH2_FINETIME_ON_LAST + {0,SX1302_REG_RX_TOP_BASE_ADDR+144,4,0,1,0,1,1}, // RX_TOP_FRAME_SYNCH2_AUTO_SCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+144,3,0,1,0,1,0}, // RX_TOP_FRAME_SYNCH2_DROP_ON_SYNCH + {0,SX1302_REG_RX_TOP_BASE_ADDR+144,2,0,1,0,1,1}, // RX_TOP_FRAME_SYNCH2_GAIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+144,0,0,2,0,1,3}, // RX_TOP_FRAME_SYNCH2_TIMEOUT_OPT + {0,SX1302_REG_RX_TOP_BASE_ADDR+145,7,0,1,0,1,1}, // RX_TOP_FINE_TIMING_A_0_GAIN_P_HDR_RED + {0,SX1302_REG_RX_TOP_BASE_ADDR+145,6,0,1,0,1,0}, // RX_TOP_FINE_TIMING_A_0_ROUNDING + {0,SX1302_REG_RX_TOP_BASE_ADDR+145,4,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_0_POS_LIMIT + {0,SX1302_REG_RX_TOP_BASE_ADDR+145,2,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_0_SUM_SIZE + {0,SX1302_REG_RX_TOP_BASE_ADDR+145,0,0,2,0,1,3}, // RX_TOP_FINE_TIMING_A_0_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+146,6,0,2,0,1,1}, // RX_TOP_FINE_TIMING_A_1_GAIN_P_AUTO + {0,SX1302_REG_RX_TOP_BASE_ADDR+146,3,0,3,0,1,2}, // RX_TOP_FINE_TIMING_A_1_GAIN_P_PAYLOAD + {0,SX1302_REG_RX_TOP_BASE_ADDR+146,0,0,3,0,1,6}, // RX_TOP_FINE_TIMING_A_1_GAIN_P_PREAMB + {0,SX1302_REG_RX_TOP_BASE_ADDR+147,6,0,2,0,1,3}, // RX_TOP_FINE_TIMING_A_2_GAIN_I_AUTO + {0,SX1302_REG_RX_TOP_BASE_ADDR+147,3,0,3,0,1,1}, // RX_TOP_FINE_TIMING_A_2_GAIN_I_PAYLOAD + {0,SX1302_REG_RX_TOP_BASE_ADDR+147,0,0,3,0,1,4}, // RX_TOP_FINE_TIMING_A_2_GAIN_I_PREAMB + {0,SX1302_REG_RX_TOP_BASE_ADDR+148,7,0,1,0,1,0}, // RX_TOP_FINE_TIMING_A_3_FINESYNCH_SUM + {0,SX1302_REG_RX_TOP_BASE_ADDR+148,4,0,3,0,1,5}, // RX_TOP_FINE_TIMING_A_3_FINESYNCH_GAIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+149,6,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_4_GAIN_I_EN_SF8 + {0,SX1302_REG_RX_TOP_BASE_ADDR+149,4,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_4_GAIN_I_EN_SF7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+149,2,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_4_GAIN_I_EN_SF6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+149,0,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_4_GAIN_I_EN_SF5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+150,6,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+150,4,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF11 + {0,SX1302_REG_RX_TOP_BASE_ADDR+150,2,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF10 + {0,SX1302_REG_RX_TOP_BASE_ADDR+150,0,0,2,0,1,0}, // RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF9 + {0,SX1302_REG_RX_TOP_BASE_ADDR+151,4,0,3,0,1,7}, // RX_TOP_FINE_TIMING_A_6_GAIN_P_PREAMB_SF12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+151,0,0,3,0,1,4}, // RX_TOP_FINE_TIMING_A_6_GAIN_P_PREAMB_SF5_6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+152,4,0,3,0,1,0}, // RX_TOP_FINE_TIMING_7_GAIN_I_AUTO_MAX + {0,SX1302_REG_RX_TOP_BASE_ADDR+152,0,0,3,0,1,0}, // RX_TOP_FINE_TIMING_7_GAIN_P_AUTO_MAX + {0,SX1302_REG_RX_TOP_BASE_ADDR+153,7,0,1,0,1,1}, // RX_TOP_FINE_TIMING_B_0_GAIN_P_HDR_RED + {0,SX1302_REG_RX_TOP_BASE_ADDR+153,6,0,1,0,1,0}, // RX_TOP_FINE_TIMING_B_0_ROUNDING + {0,SX1302_REG_RX_TOP_BASE_ADDR+153,4,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_0_POS_LIMIT + {0,SX1302_REG_RX_TOP_BASE_ADDR+153,2,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_0_SUM_SIZE + {0,SX1302_REG_RX_TOP_BASE_ADDR+153,0,0,2,0,1,3}, // RX_TOP_FINE_TIMING_B_0_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+154,6,0,2,0,1,1}, // RX_TOP_FINE_TIMING_B_1_GAIN_P_AUTO + {0,SX1302_REG_RX_TOP_BASE_ADDR+154,3,0,3,0,1,2}, // RX_TOP_FINE_TIMING_B_1_GAIN_P_PAYLOAD + {0,SX1302_REG_RX_TOP_BASE_ADDR+154,0,0,3,0,1,6}, // RX_TOP_FINE_TIMING_B_1_GAIN_P_PREAMB + {0,SX1302_REG_RX_TOP_BASE_ADDR+155,6,0,2,0,1,3}, // RX_TOP_FINE_TIMING_B_2_GAIN_I_AUTO + {0,SX1302_REG_RX_TOP_BASE_ADDR+155,3,0,3,0,1,1}, // RX_TOP_FINE_TIMING_B_2_GAIN_I_PAYLOAD + {0,SX1302_REG_RX_TOP_BASE_ADDR+155,0,0,3,0,1,4}, // RX_TOP_FINE_TIMING_B_2_GAIN_I_PREAMB + {0,SX1302_REG_RX_TOP_BASE_ADDR+156,7,0,1,0,1,0}, // RX_TOP_FINE_TIMING_B_3_FINESYNCH_SUM + {0,SX1302_REG_RX_TOP_BASE_ADDR+156,4,0,3,0,1,5}, // RX_TOP_FINE_TIMING_B_3_FINESYNCH_GAIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+157,6,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_4_GAIN_I_EN_SF8 + {0,SX1302_REG_RX_TOP_BASE_ADDR+157,4,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_4_GAIN_I_EN_SF7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+157,2,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_4_GAIN_I_EN_SF6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+157,0,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_4_GAIN_I_EN_SF5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+158,6,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+158,4,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF11 + {0,SX1302_REG_RX_TOP_BASE_ADDR+158,2,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF10 + {0,SX1302_REG_RX_TOP_BASE_ADDR+158,0,0,2,0,1,0}, // RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF9 + {0,SX1302_REG_RX_TOP_BASE_ADDR+159,4,0,3,0,1,7}, // RX_TOP_FINE_TIMING_B_6_GAIN_P_PREAMB_SF12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+159,0,0,3,0,1,4}, // RX_TOP_FINE_TIMING_B_6_GAIN_P_PREAMB_SF5_6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+160,0,0,4,0,1,9}, // RX_TOP_FREQ_TO_TIME0_FREQ_TO_TIME_DRIFT_MANT + {0,SX1302_REG_RX_TOP_BASE_ADDR+161,0,0,8,0,1,112}, // RX_TOP_FREQ_TO_TIME1_FREQ_TO_TIME_DRIFT_MANT + {0,SX1302_REG_RX_TOP_BASE_ADDR+162,0,0,3,0,1,3}, // RX_TOP_FREQ_TO_TIME2_FREQ_TO_TIME_DRIFT_EXP + {0,SX1302_REG_RX_TOP_BASE_ADDR+163,5,0,1,0,1,0}, // RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FREQ_DELTA + {0,SX1302_REG_RX_TOP_BASE_ADDR+163,4,0,1,0,1,0}, // RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FINE_DELTA + {0,SX1302_REG_RX_TOP_BASE_ADDR+163,3,0,1,0,1,1}, // RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FREQ_ERROR + {0,SX1302_REG_RX_TOP_BASE_ADDR+163,2,0,1,0,1,0}, // RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_SYMB + {0,SX1302_REG_RX_TOP_BASE_ADDR+163,1,0,1,0,1,0}, // RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_OFFSET + {0,SX1302_REG_RX_TOP_BASE_ADDR+163,0,0,1,0,1,1}, // RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_DETECT + {0,SX1302_REG_RX_TOP_BASE_ADDR+164,0,0,8,0,1,33}, // RX_TOP_FREQ_TO_TIME4_FREQ_TO_TIME_INVERT_RNG + {0,SX1302_REG_RX_TOP_BASE_ADDR+165,6,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF8 + {0,SX1302_REG_RX_TOP_BASE_ADDR+165,4,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+165,2,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+165,0,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+166,6,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+166,4,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF11 + {0,SX1302_REG_RX_TOP_BASE_ADDR+166,2,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF10 + {0,SX1302_REG_RX_TOP_BASE_ADDR+166,0,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF9 + {0,SX1302_REG_RX_TOP_BASE_ADDR+167,6,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF8 + {0,SX1302_REG_RX_TOP_BASE_ADDR+167,4,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+167,2,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+167,0,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+168,6,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+168,4,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF11 + {0,SX1302_REG_RX_TOP_BASE_ADDR+168,2,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF10 + {0,SX1302_REG_RX_TOP_BASE_ADDR+168,0,0,2,0,1,3}, // RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF9 + {0,SX1302_REG_RX_TOP_BASE_ADDR+169,7,0,1,0,1,0}, // RX_TOP_FREQ_TRACK2_FREQ_TRACK_FINE + {0,SX1302_REG_RX_TOP_BASE_ADDR+169,4,0,3,0,1,4}, // RX_TOP_FREQ_TRACK2_FREQ_TRACK_HDR_SKIP + {0,SX1302_REG_RX_TOP_BASE_ADDR+170,4,0,3,0,1,5}, // RX_TOP_FREQ_TRACK3_FREQ_SYNCH_GAIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+170,0,0,4,0,1,3}, // RX_TOP_FREQ_TRACK3_FREQ_TRACK_AUTO_THR + {0,SX1302_REG_RX_TOP_BASE_ADDR+171,5,0,2,0,1,1}, // RX_TOP_FREQ_TRACK4_SNR_MIN_WINDOW + {0,SX1302_REG_RX_TOP_BASE_ADDR+171,4,0,1,0,1,0}, // RX_TOP_FREQ_TRACK4_GAIN_AUTO_SNR_MIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+171,0,0,4,0,1,8}, // RX_TOP_FREQ_TRACK4_FREQ_SYNCH_THR + {0,SX1302_REG_RX_TOP_BASE_ADDR+172,0,0,7,0,1,32}, // RX_TOP_DETECT_MSP0_MSP_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+173,0,0,7,0,1,48}, // RX_TOP_DETECT_MSP1_MSP2_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+174,4,0,3,0,1,5}, // RX_TOP_DETECT_MSP2_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+174,0,0,3,0,1,3}, // RX_TOP_DETECT_MSP2_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_BASE_ADDR+175,6,0,1,0,1,0}, // RX_TOP_DETECT_MSP3_ACC_MIN2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+175,4,0,2,0,1,2}, // RX_TOP_DETECT_MSP3_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_BASE_ADDR+175,2,0,1,0,1,1}, // RX_TOP_DETECT_MSP3_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+175,0,0,2,0,1,1}, // RX_TOP_DETECT_MSP3_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+176,7,0,1,0,1,0}, // RX_TOP_DETECT_ACC1_USE_GAIN_SYMB + {0,SX1302_REG_RX_TOP_BASE_ADDR+176,0,0,7,0,1,64}, // RX_TOP_DETECT_ACC1_ACC_PNR + {0,SX1302_REG_RX_TOP_BASE_ADDR+177,6,0,2,0,1,2}, // RX_TOP_DETECT_ACC2_NOISE_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+177,4,0,2,0,1,2}, // RX_TOP_DETECT_ACC2_ACC_COEFF + {0,SX1302_REG_RX_TOP_BASE_ADDR+177,3,0,1,0,1,1}, // RX_TOP_DETECT_ACC2_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_BASE_ADDR+177,2,0,1,0,1,1}, // RX_TOP_DETECT_ACC2_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_BASE_ADDR+177,1,0,1,0,1,1}, // RX_TOP_DETECT_ACC2_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_BASE_ADDR+177,0,0,1,0,1,1}, // RX_TOP_DETECT_ACC2_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_BASE_ADDR+178,0,0,8,0,1,11}, // RX_TOP_DETECT_ACC3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_BASE_ADDR+179,4,0,1,0,1,0}, // RX_TOP_TIMESTAMP_SEL_SNR_MIN + {0,SX1302_REG_RX_TOP_BASE_ADDR+179,3,0,1,0,1,0}, // RX_TOP_TIMESTAMP_ENABLE + {0,SX1302_REG_RX_TOP_BASE_ADDR+179,0,0,3,0,1,7}, // RX_TOP_TIMESTAMP_NB_SYMB + {0,SX1302_REG_RX_TOP_BASE_ADDR+180,0,0,8,1,1,0}, // RX_TOP_MODEM_BUSY_MSB_RX_MODEM_BUSY + {0,SX1302_REG_RX_TOP_BASE_ADDR+181,0,0,8,1,1,0}, // RX_TOP_MODEM_BUSY_LSB_RX_MODEM_BUSY + {0,SX1302_REG_RX_TOP_BASE_ADDR+182,4,0,4,1,1,0}, // RX_TOP_MODEM_STATE_RX_MODEM_STS_SPARE + {0,SX1302_REG_RX_TOP_BASE_ADDR+182,0,0,4,1,1,0}, // RX_TOP_MODEM_STATE_RX_MODEM_STATE + {0,SX1302_REG_RX_TOP_BASE_ADDR+183,6,0,2,0,1,2}, // RX_TOP_MODEM_SYNC_DELTA_MSB_PEAK_POS_FINE_GAIN_H + {0,SX1302_REG_RX_TOP_BASE_ADDR+183,4,0,2,0,1,3}, // RX_TOP_MODEM_SYNC_DELTA_MSB_PEAK_POS_FINE_GAIN_L + {0,SX1302_REG_RX_TOP_BASE_ADDR+183,3,0,1,0,1,1}, // RX_TOP_MODEM_SYNC_DELTA_MSB_PEAK_POS_FINE_SIGN + {0,SX1302_REG_RX_TOP_BASE_ADDR+183,0,0,3,0,1,0}, // RX_TOP_MODEM_SYNC_DELTA_MSB_MODEM_SYNC_DELTA + {0,SX1302_REG_RX_TOP_BASE_ADDR+184,0,0,8,0,1,127}, // RX_TOP_MODEM_SYNC_DELTA_LSB_MODEM_SYNC_DELTA + {0,SX1302_REG_RX_TOP_BASE_ADDR+185,6,0,2,0,1,0}, // RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF8 + {0,SX1302_REG_RX_TOP_BASE_ADDR+185,4,0,2,0,1,0}, // RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF7 + {0,SX1302_REG_RX_TOP_BASE_ADDR+185,2,0,2,0,1,0}, // RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF6 + {0,SX1302_REG_RX_TOP_BASE_ADDR+185,0,0,2,0,1,0}, // RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF5 + {0,SX1302_REG_RX_TOP_BASE_ADDR+186,6,0,2,0,1,1}, // RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF12 + {0,SX1302_REG_RX_TOP_BASE_ADDR+186,4,0,2,0,1,1}, // RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF11 + {0,SX1302_REG_RX_TOP_BASE_ADDR+186,2,0,2,0,1,0}, // RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF10 + {0,SX1302_REG_RX_TOP_BASE_ADDR+186,0,0,2,0,1,0}, // RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF9 + {0,SX1302_REG_RX_TOP_BASE_ADDR+187,0,0,8,0,1,85}, // RX_TOP_MODEM_CLOCK_GATE_OVERRIDE_3_CLK_OVERRIDE + {0,SX1302_REG_RX_TOP_BASE_ADDR+188,0,0,8,0,1,85}, // RX_TOP_MODEM_CLOCK_GATE_OVERRIDE_2_CLK_OVERRIDE + {0,SX1302_REG_RX_TOP_BASE_ADDR+189,0,0,8,0,1,85}, // RX_TOP_MODEM_CLOCK_GATE_OVERRIDE_1_CLK_OVERRIDE + {0,SX1302_REG_RX_TOP_BASE_ADDR+190,0,0,8,0,1,85}, // RX_TOP_MODEM_CLOCK_GATE_OVERRIDE_0_CLK_OVERRIDE + {0,SX1302_REG_RX_TOP_BASE_ADDR+191,0,0,1,1,1,0}, // RX_TOP_DUMMY2_DUMMY2 + {0,SX1302_REG_RX_TOP_BASE_ADDR+192,4,0,1,0,1,0}, // RX_TOP_RX_BUFFER_DEBUG_MODE + {0,SX1302_REG_RX_TOP_BASE_ADDR+192,3,0,1,0,1,0}, // RX_TOP_RX_BUFFER_DIRECT_RAM_IF + {0,SX1302_REG_RX_TOP_BASE_ADDR+192,2,0,1,0,1,0}, // RX_TOP_RX_BUFFER_LEGACY_TIMESTAMP + {0,SX1302_REG_RX_TOP_BASE_ADDR+192,1,0,1,0,1,0}, // RX_TOP_RX_BUFFER_STORE_HEADER_ERR_META + {0,SX1302_REG_RX_TOP_BASE_ADDR+192,0,0,1,0,1,0}, // RX_TOP_RX_BUFFER_STORE_SYNC_FAIL_META + {0,SX1302_REG_RX_TOP_BASE_ADDR+193,0,0,8,0,1,255}, // RX_TOP_RX_BUFFER_TIMESTAMP_CFG_MAX_TS_METRICS + {0,SX1302_REG_RX_TOP_BASE_ADDR+194,0,0,5,0,1,0}, // RX_TOP_RX_BUFFER_IRQ_CTRL_MSB_RX_BUFFER_IRQ_THRESHOLD + {0,SX1302_REG_RX_TOP_BASE_ADDR+195,0,0,8,0,1,21}, // RX_TOP_RX_BUFFER_IRQ_CTRL_LSB_RX_BUFFER_IRQ_THRESHOLD + {0,SX1302_REG_RX_TOP_BASE_ADDR+196,0,0,4,1,1,0}, // RX_TOP_RX_BUFFER_LAST_ADDR_READ_MSB_LAST_ADDR_READ + {0,SX1302_REG_RX_TOP_BASE_ADDR+197,0,0,8,1,1,0}, // RX_TOP_RX_BUFFER_LAST_ADDR_READ_LSB_LAST_ADDR_READ + {0,SX1302_REG_RX_TOP_BASE_ADDR+198,0,0,4,1,1,0}, // RX_TOP_RX_BUFFER_LAST_ADDR_WRITE_MSB_LAST_ADDR_WRITE + {0,SX1302_REG_RX_TOP_BASE_ADDR+199,0,0,8,1,1,0}, // RX_TOP_RX_BUFFER_LAST_ADDR_WRITE_LSB_LAST_ADDR_WRITE + {0,SX1302_REG_RX_TOP_BASE_ADDR+200,0,0,5,1,1,0}, // RX_TOP_RX_BUFFER_NB_BYTES_MSB_RX_BUFFER_NB_BYTES + {0,SX1302_REG_RX_TOP_BASE_ADDR+201,0,0,8,1,1,0}, // RX_TOP_RX_BUFFER_NB_BYTES_LSB_RX_BUFFER_NB_BYTES + {0,SX1302_REG_RX_TOP_BASE_ADDR+202,0,0,8,1,1,0}, // RX_TOP_MULTI_SF_SYNC_ERR_PKT_CNT_MULTI_SF_SYNC_ERR_PKTS + {0,SX1302_REG_RX_TOP_BASE_ADDR+203,0,0,8,1,1,0}, // RX_TOP_MULTI_SF_PLD_ERR_PKT_CNT_MULTI_SF_PLD_ERR_PKTS + {0,SX1302_REG_RX_TOP_BASE_ADDR+204,0,0,8,1,1,0}, // RX_TOP_MULTI_SF_GOOD_PKT_CNT_MULTI_SF_GOOD_PKTS + {0,SX1302_REG_RX_TOP_BASE_ADDR+205,0,0,8,1,1,0}, // RX_TOP_SERV_MODEM_SYNC_ERR_PKT_CNT_SERV_MODEM_SYNC_ERR_PKTS + {0,SX1302_REG_RX_TOP_BASE_ADDR+206,0,0,8,1,1,0}, // RX_TOP_SERV_MODEM_PLD_ERR_PKT_CNT_SERV_MODEM_PLD_ERR_PKTS + {0,SX1302_REG_RX_TOP_BASE_ADDR+207,0,0,8,1,1,0}, // RX_TOP_SERV_MODEM_GOOD_PKT_CNT_SERV_MODEM_GOOD_PKTS + {0,SX1302_REG_RX_TOP_BASE_ADDR+208,0,0,8,1,1,0}, // RX_TOP_GFSK_MODEM_SYNC_ERR_PKT_CNT_GFSK_MODEM_SYNC_ERR_PKTS + {0,SX1302_REG_RX_TOP_BASE_ADDR+209,0,0,8,1,1,0}, // RX_TOP_GFSK_MODEM_PLD_ERR_PKT_CNT_GFSK_MODEM_PLD_ERR_PKTS + {0,SX1302_REG_RX_TOP_BASE_ADDR+210,0,0,8,1,1,0}, // RX_TOP_GFSK_MODEM_GOOD_PKT_CNT_GFSK_MODEM_GOOD_PKTS + {0,SX1302_REG_RX_TOP_BASE_ADDR+211,0,0,2,1,1,0}, // RX_TOP_BAD_MODEM_ID_WRITE_0_BAD_MODEM_ID_WRITE + {0,SX1302_REG_RX_TOP_BASE_ADDR+212,0,0,8,1,1,0}, // RX_TOP_BAD_MODEM_ID_WRITE_1_BAD_MODEM_ID_WRITE + {0,SX1302_REG_RX_TOP_BASE_ADDR+213,0,0,8,1,1,0}, // RX_TOP_BAD_MODEM_ID_WRITE_2_BAD_MODEM_ID_WRITE + {0,SX1302_REG_RX_TOP_BASE_ADDR+214,0,0,2,1,1,0}, // RX_TOP_BAD_MODEM_ID_READ_0_BAD_MODEM_ID_READ + {0,SX1302_REG_RX_TOP_BASE_ADDR+215,0,0,8,1,1,0}, // RX_TOP_BAD_MODEM_ID_READ_1_BAD_MODEM_ID_READ + {0,SX1302_REG_RX_TOP_BASE_ADDR+216,0,0,8,1,1,0}, // RX_TOP_BAD_MODEM_ID_READ_2_BAD_MODEM_ID_READ + {0,SX1302_REG_RX_TOP_BASE_ADDR+217,0,0,2,0,1,1}, // RX_TOP_CLOCK_GATE_OVERRIDE_0_CLK_OVERRIDE + {0,SX1302_REG_RX_TOP_BASE_ADDR+218,0,0,8,1,1,0}, // RX_TOP_SAMPLE_4_MSPS_LATCHED_125K_SAMPLE_4_MSPS_LATCHED_125K + {0,SX1302_REG_RX_TOP_BASE_ADDR+219,0,0,1,1,1,0}, // RX_TOP_DUMMY3_DUMMY3 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+0,5,0,1,0,1,1}, // ARB_MCU_CTRL_CLK_EN + {0,SX1302_REG_ARB_MCU_BASE_ADDR+0,4,0,1,0,1,0}, // ARB_MCU_CTRL_RADIO_RST + {0,SX1302_REG_ARB_MCU_BASE_ADDR+0,3,0,1,0,1,0}, // ARB_MCU_CTRL_FORCE_HOST_FE_CTRL + {0,SX1302_REG_ARB_MCU_BASE_ADDR+0,2,0,1,0,1,1}, // ARB_MCU_CTRL_MCU_CLEAR + {0,SX1302_REG_ARB_MCU_BASE_ADDR+0,1,0,1,0,1,0}, // ARB_MCU_CTRL_HOST_PROG + {0,SX1302_REG_ARB_MCU_BASE_ADDR+0,0,0,1,1,1,0}, // ARB_MCU_CTRL_PARITY_ERROR + {0,SX1302_REG_ARB_MCU_BASE_ADDR+1,0,0,8,1,1,0}, // ARB_MCU_MCU_ARB_STATUS_MCU_ARB_STATUS + {0,SX1302_REG_ARB_MCU_BASE_ADDR+7,5,0,1,0,1,0}, // ARB_MCU_UART_CFG_MSBF + {0,SX1302_REG_ARB_MCU_BASE_ADDR+7,4,0,1,0,1,0}, // ARB_MCU_UART_CFG_PAR_EN + {0,SX1302_REG_ARB_MCU_BASE_ADDR+7,3,0,1,0,1,0}, // ARB_MCU_UART_CFG_PAR_MODE + {0,SX1302_REG_ARB_MCU_BASE_ADDR+7,2,0,1,0,1,0}, // ARB_MCU_UART_CFG_START_LEN + {0,SX1302_REG_ARB_MCU_BASE_ADDR+7,1,0,1,0,1,0}, // ARB_MCU_UART_CFG_STOP_LEN + {0,SX1302_REG_ARB_MCU_BASE_ADDR+7,0,0,1,0,1,1}, // ARB_MCU_UART_CFG_WORD_LEN + {0,SX1302_REG_ARB_MCU_BASE_ADDR+8,0,0,8,0,1,0}, // ARB_MCU_UART_CFG2_BIT_RATE + {0,SX1302_REG_ARB_MCU_BASE_ADDR+9,0,0,8,0,1,0}, // ARB_MCU_ARB_DEBUG_CFG_0_ARB_DEBUG_CFG_0 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+10,0,0,8,0,1,0}, // ARB_MCU_ARB_DEBUG_CFG_1_ARB_DEBUG_CFG_1 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+11,0,0,8,0,1,0}, // ARB_MCU_ARB_DEBUG_CFG_2_ARB_DEBUG_CFG_2 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+12,0,0,8,0,1,0}, // ARB_MCU_ARB_DEBUG_CFG_3_ARB_DEBUG_CFG_3 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+13,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_0_ARB_DEBUG_STS_0 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+14,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_1_ARB_DEBUG_STS_1 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+15,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_2_ARB_DEBUG_STS_2 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+16,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_3_ARB_DEBUG_STS_3 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+17,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_4_ARB_DEBUG_STS_4 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+18,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_5_ARB_DEBUG_STS_5 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+19,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_6_ARB_DEBUG_STS_6 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+20,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_7_ARB_DEBUG_STS_7 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+21,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_8_ARB_DEBUG_STS_8 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+22,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_9_ARB_DEBUG_STS_9 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+23,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_10_ARB_DEBUG_STS_10 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+24,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_11_ARB_DEBUG_STS_11 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+25,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_12_ARB_DEBUG_STS_12 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+26,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_13_ARB_DEBUG_STS_13 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+27,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_14_ARB_DEBUG_STS_14 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+28,0,0,8,1,1,0}, // ARB_MCU_ARB_DEBUG_STS_15_ARB_DEBUG_STS_15 + {0,SX1302_REG_ARB_MCU_BASE_ADDR+29,4,0,4,0,1,0}, // ARB_MCU_CHANNEL_SYNC_OFFSET_01_CHANNEL_1_OFFSET + {0,SX1302_REG_ARB_MCU_BASE_ADDR+29,0,0,4,0,1,0}, // ARB_MCU_CHANNEL_SYNC_OFFSET_01_CHANNEL_0_OFFSET + {0,SX1302_REG_ARB_MCU_BASE_ADDR+30,4,0,4,0,1,0}, // ARB_MCU_CHANNEL_SYNC_OFFSET_23_CHANNEL_3_OFFSET + {0,SX1302_REG_ARB_MCU_BASE_ADDR+30,0,0,4,0,1,0}, // ARB_MCU_CHANNEL_SYNC_OFFSET_23_CHANNEL_2_OFFSET + {0,SX1302_REG_ARB_MCU_BASE_ADDR+31,4,0,4,0,1,0}, // ARB_MCU_CHANNEL_SYNC_OFFSET_45_CHANNEL_5_OFFSET + {0,SX1302_REG_ARB_MCU_BASE_ADDR+31,0,0,4,0,1,0}, // ARB_MCU_CHANNEL_SYNC_OFFSET_45_CHANNEL_4_OFFSET + {0,SX1302_REG_ARB_MCU_BASE_ADDR+32,4,0,4,0,1,0}, // ARB_MCU_CHANNEL_SYNC_OFFSET_67_CHANNEL_7_OFFSET + {0,SX1302_REG_ARB_MCU_BASE_ADDR+32,0,0,4,0,1,0}, // ARB_MCU_CHANNEL_SYNC_OFFSET_67_CHANNEL_6_OFFSET + {0,SX1302_REG_ARB_MCU_BASE_ADDR+33,0,0,1,1,1,0}, // ARB_MCU_DUMMY_DUMMY3 + {0,SX1302_REG_RADIO_FE_BASE_ADDR+0,1,0,1,0,1,0}, // RADIO_FE_GLBL_CTRL_DECIM_B_CLR + {0,SX1302_REG_RADIO_FE_BASE_ADDR+0,0,0,1,0,1,0}, // RADIO_FE_GLBL_CTRL_DECIM_A_CLR + {0,SX1302_REG_RADIO_FE_BASE_ADDR+1,5,0,1,0,1,0}, // RADIO_FE_CTRL0_RADIO_A_DC_NOTCH_EN + {0,SX1302_REG_RADIO_FE_BASE_ADDR+1,4,0,1,0,1,0}, // RADIO_FE_CTRL0_RADIO_A_FORCE_HOST_FILTER_GAIN + {0,SX1302_REG_RADIO_FE_BASE_ADDR+1,0,0,4,0,1,0}, // RADIO_FE_CTRL0_RADIO_A_HOST_FILTER_GAIN + {0,SX1302_REG_RADIO_FE_BASE_ADDR+2,0,0,8,0,1,0}, // RADIO_FE_RSSI_DB_DEF_RADIO_A_RSSI_DB_DEFAULT_VALUE + {0,SX1302_REG_RADIO_FE_BASE_ADDR+3,0,0,8,0,1,0}, // RADIO_FE_RSSI_DEC_DEF_RADIO_A_RSSI_DEC_DEFAULT_VALUE + {0,SX1302_REG_RADIO_FE_BASE_ADDR+4,0,0,8,1,1,0}, // RADIO_FE_RSSI_DEC_RD_RADIO_A_RSSI_DEC_OUT + {0,SX1302_REG_RADIO_FE_BASE_ADDR+5,0,0,8,1,1,0}, // RADIO_FE_RSSI_BB_RD_RADIO_A_RSSI_BB_OUT + {0,SX1302_REG_RADIO_FE_BASE_ADDR+6,0,0,4,1,1,0}, // RADIO_FE_DEC_FILTER_RD_RADIO_A_DEC_FILTER_GAIN + {0,SX1302_REG_RADIO_FE_BASE_ADDR+7,0,0,5,0,1,0}, // RADIO_FE_RSSI_BB_FILTER_ALPHA_RADIO_A_RSSI_BB_FILTER_ALPHA + {0,SX1302_REG_RADIO_FE_BASE_ADDR+8,0,0,5,0,1,0}, // RADIO_FE_RSSI_DEC_FILTER_ALPHA_RADIO_A_RSSI_DEC_FILTER_ALPHA + {0,SX1302_REG_RADIO_FE_BASE_ADDR+9,0,0,6,0,1,0}, // RADIO_FE_IQ_COMP_AMP_COEFF_RADIO_A_AMP_COEFF + {0,SX1302_REG_RADIO_FE_BASE_ADDR+10,0,0,6,0,1,0}, // RADIO_FE_IQ_COMP_PHI_COEFF_RADIO_A_PHI_COEFF + {0,SX1302_REG_RADIO_FE_BASE_ADDR+11,0,0,6,0,1,0}, // RADIO_FE_RADIO_DIO_TEST_MODE_RADIO_A_DIO_TEST_MODE + {0,SX1302_REG_RADIO_FE_BASE_ADDR+12,0,0,6,0,1,0}, // RADIO_FE_RADIO_DIO_TEST_DIR_RADIO_A_DIO_TEST_DIR + {0,SX1302_REG_RADIO_FE_BASE_ADDR+13,0,0,6,1,1,0}, // RADIO_FE_RADIO_DIO_DIR_RADIO_A_DIO_DIR + {0,SX1302_REG_RADIO_FE_BASE_ADDR+14,5,0,1,0,1,0}, // RADIO_FE_CTRL0_RADIO_B_DC_NOTCH_EN + {0,SX1302_REG_RADIO_FE_BASE_ADDR+14,4,0,1,0,1,0}, // RADIO_FE_CTRL0_RADIO_B_FORCE_HOST_FILTER_GAIN + {0,SX1302_REG_RADIO_FE_BASE_ADDR+14,0,0,4,0,1,0}, // RADIO_FE_CTRL0_RADIO_B_HOST_FILTER_GAIN + {0,SX1302_REG_RADIO_FE_BASE_ADDR+15,0,0,8,0,1,0}, // RADIO_FE_RSSI_DB_DEF_RADIO_B_RSSI_DB_DEFAULT_VALUE + {0,SX1302_REG_RADIO_FE_BASE_ADDR+16,0,0,8,0,1,0}, // RADIO_FE_RSSI_DEC_DEF_RADIO_B_RSSI_DEC_DEFAULT_VALUE + {0,SX1302_REG_RADIO_FE_BASE_ADDR+17,0,0,8,1,1,0}, // RADIO_FE_RSSI_DEC_RD_RADIO_B_RSSI_DEC_OUT + {0,SX1302_REG_RADIO_FE_BASE_ADDR+18,0,0,8,1,1,0}, // RADIO_FE_RSSI_BB_RD_RADIO_B_RSSI_BB_OUT + {0,SX1302_REG_RADIO_FE_BASE_ADDR+19,0,0,4,1,1,0}, // RADIO_FE_DEC_FILTER_RD_RADIO_B_DEC_FILTER_GAIN + {0,SX1302_REG_RADIO_FE_BASE_ADDR+20,0,0,5,0,1,0}, // RADIO_FE_RSSI_BB_FILTER_ALPHA_RADIO_B_RSSI_BB_FILTER_ALPHA + {0,SX1302_REG_RADIO_FE_BASE_ADDR+21,0,0,5,0,1,0}, // RADIO_FE_RSSI_DEC_FILTER_ALPHA_RADIO_B_RSSI_DEC_FILTER_ALPHA + {0,SX1302_REG_RADIO_FE_BASE_ADDR+22,0,0,6,0,1,0}, // RADIO_FE_IQ_COMP_AMP_COEFF_RADIO_B_AMP_COEFF + {0,SX1302_REG_RADIO_FE_BASE_ADDR+23,0,0,6,0,1,0}, // RADIO_FE_IQ_COMP_PHI_COEFF_RADIO_B_PHI_COEFF + {0,SX1302_REG_RADIO_FE_BASE_ADDR+24,0,0,6,0,1,0}, // RADIO_FE_RADIO_DIO_TEST_MODE_RADIO_B_DIO_TEST_MODE + {0,SX1302_REG_RADIO_FE_BASE_ADDR+25,0,0,6,0,1,0}, // RADIO_FE_RADIO_DIO_TEST_DIR_RADIO_B_DIO_TEST_DIR + {0,SX1302_REG_RADIO_FE_BASE_ADDR+26,0,0,6,1,1,0}, // RADIO_FE_RADIO_DIO_DIR_RADIO_B_DIO_DIR + {0,SX1302_REG_RADIO_FE_BASE_ADDR+27,7,0,1,1,1,0}, // RADIO_FE_SIG_ANA_CFG_VALID + {0,SX1302_REG_RADIO_FE_BASE_ADDR+27,6,0,1,1,1,0}, // RADIO_FE_SIG_ANA_CFG_BUSY + {0,SX1302_REG_RADIO_FE_BASE_ADDR+27,4,0,2,0,1,0}, // RADIO_FE_SIG_ANA_CFG_DURATION + {0,SX1302_REG_RADIO_FE_BASE_ADDR+27,3,0,1,0,1,0}, // RADIO_FE_SIG_ANA_CFG_FORCE_HAL_CTRL + {0,SX1302_REG_RADIO_FE_BASE_ADDR+27,2,0,1,0,1,0}, // RADIO_FE_SIG_ANA_CFG_START + {0,SX1302_REG_RADIO_FE_BASE_ADDR+27,1,0,1,0,1,0}, // RADIO_FE_SIG_ANA_CFG_RADIO_SEL + {0,SX1302_REG_RADIO_FE_BASE_ADDR+27,0,0,1,0,1,0}, // RADIO_FE_SIG_ANA_CFG_EN + {0,SX1302_REG_RADIO_FE_BASE_ADDR+28,0,0,8,0,1,0}, // RADIO_FE_SIG_ANA_FREQ_FREQ + {0,SX1302_REG_RADIO_FE_BASE_ADDR+29,0,0,8,1,1,0}, // RADIO_FE_SIG_ANA_ABS_MSB_CORR_ABS_OUT + {0,SX1302_REG_RADIO_FE_BASE_ADDR+30,0,0,8,1,1,0}, // RADIO_FE_SIG_ANA_ABS_LSB_CORR_ABS_OUT + {0,SX1302_REG_RADIO_FE_BASE_ADDR+31,0,0,1,1,1,0}, // RADIO_FE_DUMMY_DUMMY + {0,SX1302_REG_OTP_BASE_ADDR+0,0,0,8,0,1,0}, // OTP_BYTE_ADDR_ADDR + {0,SX1302_REG_OTP_BASE_ADDR+1,0,0,8,1,1,0}, // OTP_RD_DATA_RD_DATA + {0,SX1302_REG_OTP_BASE_ADDR+2,4,0,4,1,1,0}, // OTP_STATUS_CHECKSUM_STATUS + {0,SX1302_REG_OTP_BASE_ADDR+2,0,0,1,1,1,0}, // OTP_STATUS_FSM_READY + {0,SX1302_REG_OTP_BASE_ADDR+3,0,0,2,0,1,0}, // OTP_CFG_ACCESS_MODE + {0,SX1302_REG_OTP_BASE_ADDR+4,0,0,3,0,1,0}, // OTP_BIT_POS_POS + {0,SX1302_REG_OTP_BASE_ADDR+5,4,0,4,0,1,0}, // OTP_PIN_CTRL_0_TM + {0,SX1302_REG_OTP_BASE_ADDR+5,3,0,1,0,1,0}, // OTP_PIN_CTRL_0_STROBE + {0,SX1302_REG_OTP_BASE_ADDR+5,2,0,1,0,1,0}, // OTP_PIN_CTRL_0_PGENB + {0,SX1302_REG_OTP_BASE_ADDR+5,1,0,1,0,1,0}, // OTP_PIN_CTRL_0_LOAD + {0,SX1302_REG_OTP_BASE_ADDR+5,0,0,1,0,1,0}, // OTP_PIN_CTRL_0_CSB + {0,SX1302_REG_OTP_BASE_ADDR+6,2,0,1,0,1,0}, // OTP_PIN_CTRL_1_FSCK + {0,SX1302_REG_OTP_BASE_ADDR+6,1,0,1,0,1,0}, // OTP_PIN_CTRL_1_FSI + {0,SX1302_REG_OTP_BASE_ADDR+6,0,0,1,0,1,0}, // OTP_PIN_CTRL_1_FRST + {0,SX1302_REG_OTP_BASE_ADDR+7,0,0,1,1,1,0}, // OTP_PIN_STATUS_FSO + {0,SX1302_REG_OTP_BASE_ADDR+8,0,0,8,0,1,255}, // OTP_MODEM_EN_0_MODEM_EN + {0,SX1302_REG_OTP_BASE_ADDR+9,0,0,8,0,1,255}, // OTP_MODEM_EN_1_MODEM_EN + {0,SX1302_REG_OTP_BASE_ADDR+10,0,0,8,0,1,255}, // OTP_MODEM_SF_EN_SF_EN + {0,SX1302_REG_OTP_BASE_ADDR+11,0,0,1,0,1,1}, // OTP_TIMESTAMP_EN_TIMESTAMP_EN + {0,SX1302_REG_OTP_BASE_ADDR+12,0,0,1,1,1,0}, // OTP_DUMMY_DUMMY + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+0,0,0,5,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_LORA_SERVICE_FREQ_MSB_IF_FREQ_0 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+1,0,0,8,0,1,128}, // RX_TOP_LORA_SERVICE_FSK_LORA_SERVICE_FREQ_LSB_IF_FREQ_0 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+2,0,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_LORA_SERVICE_RADIO_SEL_RADIO_SELECT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+3,4,0,3,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_BW_START + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+3,3,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_AUTO_BW_RED + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+3,2,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_NO_FAST_START + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+3,1,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_BYPASS + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+3,0,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_ENABLE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+4,3,0,3,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG2_BW_LOCKED + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+4,0,0,3,0,1,5}, // RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG2_BW + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+5,0,0,3,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG3_BW_RED + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+6,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG4_IIR_DCC_TIME + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+7,0,1,8,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_0_FIR1_COEFF_0 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+8,0,1,8,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_1_FIR1_COEFF_1 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+9,0,1,8,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_2_FIR1_COEFF_2 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+10,0,1,8,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_3_FIR1_COEFF_3 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+11,0,1,8,0,1,5}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_4_FIR1_COEFF_4 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+12,0,1,8,0,1,8}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_5_FIR1_COEFF_5 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+13,0,1,8,0,1,6}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_6_FIR1_COEFF_6 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+14,0,1,8,0,1,4}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_7_FIR1_COEFF_7 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+15,0,1,8,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_0_FIR2_COEFF_0 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+16,0,1,8,0,1,-2}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_1_FIR2_COEFF_1 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+17,0,1,8,0,1,-4}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_2_FIR2_COEFF_2 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+18,0,1,8,0,1,-3}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_3_FIR2_COEFF_3 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+19,0,1,8,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_4_FIR2_COEFF_4 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+20,0,1,8,0,1,11}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_5_FIR2_COEFF_5 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+21,0,1,8,0,1,19}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_6_FIR2_COEFF_6 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+22,0,1,8,0,1,10}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_7_FIR2_COEFF_7 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+23,7,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC0_RADIO_GAIN_RED_SEL + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+23,0,0,7,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC0_RADIO_GAIN_RED_DB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+24,4,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC1_DC_COMP_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+24,3,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC1_FORCE_DEFAULT_FIR + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+24,2,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC1_RSSI_EARLY_LATCH + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+24,0,0,2,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC1_FREEZE_ON_SYNC + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+25,6,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC2_DAGC_IN_COMP + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+25,5,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC2_DAGC_FIR_HYST + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+25,3,0,2,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC2_RSSI_MAX_SAMPLE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+25,0,0,3,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC2_RSSI_MIN_SAMPLE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+26,7,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_GAIN0_DAGC_FIR_FAST + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+26,6,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_GAIN0_FORCE_GAIN_FIR + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+26,4,0,2,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_GAIN0_GAIN_FIR1 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+26,0,0,3,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_RX_DFE_GAIN0_GAIN_FIR2 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+27,6,0,2,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_TARGET_LVL + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+27,5,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_GAIN_INCR_STEP + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+27,4,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_GAIN_DROP_COMP + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+27,3,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_COMB_FILTER_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+27,2,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_NO_FREEZE_START + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+27,0,0,2,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_FREEZE_ON_SYNC + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+28,0,0,8,0,1,60}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CNT0_SAMPLE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+29,0,0,8,0,1,6}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CNT1_THR_M6 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+30,0,0,8,0,1,25}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CNT2_THR_M12 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+31,0,0,8,0,1,42}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CNT3_THR_M18 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+32,4,0,4,0,1,8}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CNT4_GAIN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+32,0,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DAGC_CNT4_FORCE_GAIN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+33,4,0,4,0,1,4}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG0_MODEM_BW + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+33,0,0,4,0,1,7}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG0_MODEM_SF + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+34,6,0,2,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_PPM_OFFSET_HDR_CTRL + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+34,4,0,2,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_PPM_OFFSET + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+34,3,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_MODEM_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+34,0,0,3,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_CODING_RATE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+35,5,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+35,4,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_MODEM_START + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+35,2,0,2,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_CADRXTX + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+35,1,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_IMPLICIT_HEADER + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+35,0,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_CRC_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+36,0,0,8,0,1,12}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG3_PAYLOAD_LENGTH + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+37,7,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG4_INT_STEP_ORIDE_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+37,0,0,6,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG4_INT_STEP_ORIDE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+38,6,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG5_HEADER_DIFF_MODE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+38,0,0,6,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG5_ZERO_PAD + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+39,0,0,8,0,1,8}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG6_PREAMBLE_SYMB_NB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+40,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG7_PREAMBLE_SYMB_NB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+41,3,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG8_AUTO_ACK_INT_DELAY + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+41,2,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG8_AUTO_ACK_RX + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+41,1,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG8_AUTO_ACK_TX + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+41,0,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TXRX_CFG8_POST_PREAMBLE_GAP_LONG + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+42,4,0,2,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG0_DFT_PEAK_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+42,2,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG0_CHIRP_INVERT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+42,1,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG0_SWAP_IQ + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+42,0,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG0_CONTINUOUS + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+43,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG1_DETECT_TIMEOUT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+44,5,0,2,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG2_AUTO_ACK_RANGE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+44,0,0,5,0,1,22}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG2_AUTO_ACK_DELAY + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+45,5,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG3_RESTART_ON_HDR_ERR + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+45,4,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG3_CLK_EN_RESYNC_DIN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+45,0,0,4,0,1,11}, // RX_TOP_LORA_SERVICE_FSK_RX_CFG3_LLR_SCALE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+46,0,1,5,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH0_PEAK1_POS + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+47,0,1,5,0,1,4}, // RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH1_PEAK2_POS + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+48,5,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_FINETIME_ON_LAST + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+48,4,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_AUTO_SCALE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+48,3,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_DROP_ON_SYNCH + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+48,2,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_GAIN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+48,0,0,2,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_TIMEOUT_OPT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+49,7,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_GAIN_P_HDR_RED + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+49,6,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_ROUNDING + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+49,4,0,2,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_POS_LIMIT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+49,2,0,2,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_SUM_SIZE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+49,0,0,2,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_MODE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+50,6,0,2,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_AUTO + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+50,3,0,3,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_PAYLOAD + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+50,0,0,3,0,1,4}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_PREAMB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+51,6,0,2,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+51,3,0,3,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_PAYLOAD + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+51,0,0,3,0,1,4}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_PREAMB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+52,7,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING3_FINESYNCH_SUM + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+52,4,0,3,0,1,5}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING3_FINESYNCH_GAIN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+52,0,0,2,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING3_GAIN_I_AUTO + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+53,4,0,3,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING4_GAIN_I_AUTO_MAX + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+53,0,0,3,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FINE_TIMING4_GAIN_P_AUTO_MAX + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+54,0,0,4,0,1,9}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME0_FREQ_TO_TIME_DRIFT_MANT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+55,0,0,8,0,1,112}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME1_FREQ_TO_TIME_DRIFT_MANT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+56,0,0,3,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME2_FREQ_TO_TIME_DRIFT_EXP + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+57,5,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FREQ_DELTA + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+57,4,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FINE_DELTA + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+57,3,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FREQ_ERROR + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+57,2,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_SYMB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+57,1,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_OFFSET + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+57,0,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_DETECT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+58,0,0,8,0,1,33}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME4_FREQ_TO_TIME_INVERT_RNG + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+59,7,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK0_FREQ_TRACK_FINE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+59,4,0,3,0,1,4}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK0_FREQ_TRACK_HDR_SKIP + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+59,0,0,2,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK0_FREQ_TRACK_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+60,4,0,3,0,1,5}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK1_FREQ_SYNCH_GAIN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+60,0,0,4,0,1,3}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK1_FREQ_TRACK_AUTO_THR + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+61,5,0,2,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK2_SNR_MIN_WINDOW + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+61,4,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK2_GAIN_AUTO_SNR_MIN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+61,0,0,4,0,1,8}, // RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK2_FREQ_SYNCH_THR + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+62,0,0,7,0,1,24}, // RX_TOP_LORA_SERVICE_FSK_DETECT_MSP0_MSP_PNR + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+63,0,0,7,0,1,48}, // RX_TOP_LORA_SERVICE_FSK_DETECT_MSP1_MSP2_PNR + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+64,4,0,3,0,1,7}, // RX_TOP_LORA_SERVICE_FSK_DETECT_MSP2_MSP2_PEAK_NB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+64,0,0,3,0,1,7}, // RX_TOP_LORA_SERVICE_FSK_DETECT_MSP2_MSP_PEAK_NB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+65,7,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DETECT_MSP3_ACC_MIN2 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+65,4,0,2,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_DETECT_MSP3_ACC_WIN_LEN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+65,2,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_DETECT_MSP3_MSP_POS_SEL + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+65,0,0,2,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_DETECT_MSP3_MSP_CNT_MODE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+66,7,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_USE_GAIN_SYMB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+66,0,0,7,0,1,55}, // RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+67,6,0,2,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_NOISE_COEFF + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+67,4,0,2,0,1,2}, // RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_COEFF + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+67,3,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_2_SAME_PEAKS + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+67,2,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_AUTO_RESCALE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+67,1,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_PEAK_POS_SEL + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+67,0,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_PEAK_SUM_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+68,0,0,8,0,1,11}, // RX_TOP_LORA_SERVICE_FSK_DETECT_ACC3_MIN_SINGLE_PEAK + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+69,4,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TIMESTAMP_SEL_SNR_MIN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+69,3,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_TIMESTAMP_ENABLE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+69,0,0,3,0,1,7}, // RX_TOP_LORA_SERVICE_FSK_TIMESTAMP_NB_SYMB + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+70,6,0,2,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_CLOCK_GATE_OVERRIDE_FSK_TRANSPOSE_CLK_OVERRIDE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+70,4,0,2,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_CLOCK_GATE_OVERRIDE_FSK_MODEM_CLK_OVERRIDE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+70,2,0,2,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_CLOCK_GATE_OVERRIDE_TRANSPOSE_CLK_OVERRIDE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+70,0,0,2,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_CLOCK_GATE_OVERRIDE_MODEM_CLK_OVERRIDE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+71,0,0,1,1,1,0}, // RX_TOP_LORA_SERVICE_FSK_DUMMY0_DUMMY0 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+80,0,0,5,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_FREQ_MSB_IF_FREQ_0 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+81,0,0,8,0,1,128}, // RX_TOP_LORA_SERVICE_FSK_FSK_FREQ_LSB_IF_FREQ_0 + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+82,4,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_CRC_IBM + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+82,2,0,2,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_DCFREE_ENC + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+82,1,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_CRC_EN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+82,0,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_PKT_MODE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+83,6,0,2,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_1_ADRS_COMP + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+83,3,0,3,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_1_PSIZE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+83,0,0,3,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_1_CH_BW_EXPO + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+84,3,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_MODEM_INVERT_IQ + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+84,2,0,1,0,1,1}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_AUTO_AFC + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+84,1,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_RADIO_SELECT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+84,0,0,1,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_RX_INVERT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+85,5,0,3,0,1,4}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_4_RSSI_LENGTH + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+85,0,0,5,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_CFG_4_ERROR_OSR_TOL + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+86,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_NODE_ADRS_NODE_ADRS + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+87,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_BROADCAST_BROADCAST + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+88,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_PKT_LENGTH_PKT_LENGTH + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+89,0,0,2,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_TIMEOUT_MSB_TIMEOUT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+90,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_TIMEOUT_LSB_TIMEOUT + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+91,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_BIT_RATE_MSB_BIT_RATE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+92,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_BIT_RATE_LSB_BIT_RATE + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+93,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+94,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+95,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+96,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+97,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+98,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+99,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+100,0,0,8,0,1,0}, // RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+101,0,0,4,0,1,4}, // RX_TOP_LORA_SERVICE_FSK_FSK_RSSI_FILTER_ALPHA_FSK_RSSI_FILTER_ALPHA + {0,SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BASE_ADDR+102,0,0,1,1,1,0}, // RX_TOP_LORA_SERVICE_FSK_DUMMY1_DUMMY1 + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+0,4,0,1,0,1,0}, // CAPTURE_RAM_CAPTURE_CFG_ENABLE + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+0,3,0,1,0,1,0}, // CAPTURE_RAM_CAPTURE_CFG_CAPTUREWRAP + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+0,2,0,1,0,1,0}, // CAPTURE_RAM_CAPTURE_CFG_CAPTUREFORCETRIGGER + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+0,1,0,1,0,1,0}, // CAPTURE_RAM_CAPTURE_CFG_CAPTURESTART + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+0,0,0,1,0,1,0}, // CAPTURE_RAM_CAPTURE_CFG_RAMCONFIG + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+1,0,0,5,0,1,0}, // CAPTURE_RAM_CAPTURE_SOURCE_A_SOURCEMUX + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+2,0,0,5,0,1,0}, // CAPTURE_RAM_CAPTURE_SOURCE_B_SOURCEMUX + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+3,0,0,8,0,1,0}, // CAPTURE_RAM_CAPTURE_PERIOD_0_CAPTUREPERIOD + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+4,0,0,8,0,1,0}, // CAPTURE_RAM_CAPTURE_PERIOD_1_CAPTUREPERIOD + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+5,0,0,1,1,1,0}, // CAPTURE_RAM_STATUS_CAPCOMPLETE + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+6,0,0,8,1,1,0}, // CAPTURE_RAM_LAST_RAM_ADDR_0_LASTRAMADDR + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+7,0,0,4,1,1,0}, // CAPTURE_RAM_LAST_RAM_ADDR_1_LASTRAMADDR + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+8,0,0,2,0,1,2}, // CAPTURE_RAM_CLOCK_GATE_OVERRIDE_CLK_OVERRIDE + {0,SX1302_REG_CAPTURE_RAM_BASE_ADDR+9,0,0,1,1,1,0}, // CAPTURE_RAM_DUMMY0_DUMMY0 + {0,0,0,0,0,0,0,0} +}; + +/* -------------------------------------------------------------------------- */ +/* --- PRIVATE VARIABLES ---------------------------------------------------- */ + +/* -------------------------------------------------------------------------- */ +/* --- INTERNAL SHARED VARIABLES -------------------------------------------- */ + +void *lgw_spi_target = NULL; /*! generic pointer to the SPI device */ + +/* -------------------------------------------------------------------------- */ +/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */ + +int reg_w_align32(void *spi_target, uint8_t spi_mux_target, struct lgw_reg_s r, int32_t reg_value) { + int spi_stat = LGW_REG_SUCCESS; + int i, size_byte; + uint8_t buf[4] = "\x00\x00\x00\x00"; + + if ((r.leng == 8) && (r.offs == 0)) { + /* direct write */ + spi_stat += lgw_spi_w(spi_target, spi_mux_target, r.addr, (uint8_t)reg_value); + } else if ((r.offs + r.leng) <= 8) { + /* single-byte read-modify-write, offs:[0-7], leng:[1-7] */ + spi_stat += lgw_spi_r(spi_target, spi_mux_target, r.addr, &buf[0]); + buf[1] = ((1 << r.leng) - 1) << r.offs; /* bit mask */ + buf[2] = ((uint8_t)reg_value) << r.offs; /* new data offsetted */ + buf[3] = (~buf[1] & buf[0]) | (buf[1] & buf[2]); /* mixing old & new data */ + spi_stat += lgw_spi_w(spi_target, spi_mux_target, r.addr, buf[3]); + } else if ((r.offs == 0) && (r.leng > 0) && (r.leng <= 32)) { + /* multi-byte direct write routine */ + size_byte = (r.leng + 7) / 8; /* add a byte if it's not an exact multiple of 8 */ + for (i=0; i> 8); + } + spi_stat += lgw_spi_wb(spi_target, spi_mux_target, r.addr, buf, size_byte); /* write the register in one burst */ + } else { + /* register spanning multiple memory bytes but with an offset */ + DEBUG_MSG("ERROR: REGISTER SIZE AND OFFSET ARE NOT SUPPORTED\n"); + return LGW_REG_ERROR; + } + + return spi_stat; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int reg_r_align32(void *spi_target, uint8_t spi_mux_target, struct lgw_reg_s r, int32_t *reg_value) { + int spi_stat = LGW_SPI_SUCCESS; + uint8_t bufu[4] = "\x00\x00\x00\x00"; + int8_t *bufs = (int8_t *)bufu; + int i, size_byte; + uint32_t u = 0; + + if ((r.offs + r.leng) <= 8) { + /* read one byte, then shift and mask bits to get reg value with sign extension if needed */ + spi_stat += lgw_spi_r(spi_target, spi_mux_target, r.addr, &bufu[0]); + bufu[1] = bufu[0] << (8 - r.leng - r.offs); /* left-align the data */ + if (r.sign == true) { + bufs[2] = bufs[1] >> (8 - r.leng); /* right align the data with sign extension (ARITHMETIC right shift) */ + *reg_value = (int32_t)bufs[2]; /* signed pointer -> 32b sign extension */ + } else { + bufu[2] = bufu[1] >> (8 - r.leng); /* right align the data, no sign extension */ + *reg_value = (int32_t)bufu[2]; /* unsigned pointer -> no sign extension */ + } + } else if ((r.offs == 0) && (r.leng > 0) && (r.leng <= 32)) { + size_byte = (r.leng + 7) / 8; /* add a byte if it's not an exact multiple of 8 */ + spi_stat += lgw_spi_rb(spi_target, spi_mux_target, r.addr, bufu, size_byte); + u = 0; + for (i=(size_byte-1); i>=0; --i) { + u = (uint32_t)bufu[i] + (u << 8); /* transform a 4-byte array into a 32 bit word */ + } + if (r.sign == true) { + u = u << (32 - r.leng); /* left-align the data */ + *reg_value = (int32_t)u >> (32 - r.leng); /* right-align the data with sign extension (ARITHMETIC right shift) */ + } else { + *reg_value = (int32_t)u; /* unsigned value -> return 'as is' */ + } + } else { + /* register spanning multiple memory bytes but with an offset */ + DEBUG_MSG("ERROR: REGISTER SIZE AND OFFSET ARE NOT SUPPORTED\n"); + return LGW_REG_ERROR; + } + + return spi_stat; +} + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */ + +/* Concentrator connect */ +int lgw_connect(const char * spidev_path) { + int spi_stat = LGW_SPI_SUCCESS; + uint8_t u = 0; + + /* check SPI link status */ + if (spidev_path == NULL) { + DEBUG_MSG("ERROR: SPIDEV PATH IS NOT SET\n"); + return LGW_REG_ERROR; + } + + if (lgw_spi_target != NULL) { + DEBUG_MSG("WARNING: concentrator was already connected\n"); + lgw_spi_close(lgw_spi_target); + } + + /* open the SPI link */ + spi_stat = lgw_spi_open(spidev_path, &lgw_spi_target); + if (spi_stat != LGW_SPI_SUCCESS) { + DEBUG_MSG("ERROR CONNECTING CONCENTRATOR\n"); + return LGW_REG_ERROR; + } + + /* check SX1302 version */ + spi_stat = lgw_spi_r(lgw_spi_target, LGW_SPI_MUX_TARGET_SX1302, loregs[SX1302_REG_COMMON_VERSION_VERSION].addr, &u); + if (spi_stat != LGW_SPI_SUCCESS) { + DEBUG_MSG("ERROR READING CHIP VERSION REGISTER\n"); + return LGW_REG_ERROR; + } + + if (u != loregs[SX1302_REG_COMMON_VERSION_VERSION].dflt) { + DEBUG_PRINTF("ERROR: NOT EXPECTED CHIP VERSION (v%u)\n", u); + return LGW_REG_ERROR; + } + + DEBUG_PRINTF("Note: chip version is 0x%02X (v%u.%u)\n", u, (u >> 4) & 0x0F, u & 0x0F) ; + + DEBUG_MSG("Note: success connecting the concentrator\n"); + + return LGW_REG_SUCCESS; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* Concentrator disconnect */ +int lgw_disconnect(void) { + if (lgw_spi_target != NULL) { + lgw_spi_close(lgw_spi_target); + lgw_spi_target = NULL; + DEBUG_MSG("Note: success disconnecting the concentrator\n"); + return LGW_REG_SUCCESS; + } else { + DEBUG_MSG("WARNING: concentrator was already disconnected\n"); + return LGW_REG_ERROR; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* Write to a register addressed by name */ +int lgw_reg_w(uint16_t register_id, int32_t reg_value) { + int spi_stat = LGW_SPI_SUCCESS; + struct lgw_reg_s r; + + /* check input parameters */ + if (register_id >= LGW_TOTALREGS) { + DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n"); + return LGW_REG_ERROR; + } + + /* check if SPI is initialised */ + if (lgw_spi_target == NULL) { + DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n"); + return LGW_REG_ERROR; + } + + /* get register struct from the struct array */ + r = loregs[register_id]; + + /* reject write to read-only registers */ + if (r.rdon == 1){ + DEBUG_MSG("ERROR: TRYING TO WRITE A READ-ONLY REGISTER\n"); + return LGW_REG_ERROR; + } + + spi_stat += reg_w_align32(lgw_spi_target, LGW_SPI_MUX_TARGET_SX1302, r, reg_value); + + if (spi_stat != LGW_SPI_SUCCESS) { + DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER WRITE\n"); + return LGW_REG_ERROR; + } else { + return LGW_REG_SUCCESS; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* Read to a register addressed by name */ +int lgw_reg_r(uint16_t register_id, int32_t *reg_value) { + int spi_stat = LGW_SPI_SUCCESS; + struct lgw_reg_s r; + + /* check input parameters */ + CHECK_NULL(reg_value); + if (register_id >= LGW_TOTALREGS) { + DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n"); + return LGW_REG_ERROR; + } + + /* check if SPI is initialised */ + if (lgw_spi_target == NULL) { + DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n"); + return LGW_REG_ERROR; + } + + /* get register struct from the struct array */ + r = loregs[register_id]; + + spi_stat += reg_r_align32(lgw_spi_target, LGW_SPI_MUX_TARGET_SX1302, r, reg_value); + + if (spi_stat != LGW_SPI_SUCCESS) { + DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER WRITE\n"); + return LGW_REG_ERROR; + } else { + return LGW_REG_SUCCESS; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* Point to a register by name and do a burst write */ +int lgw_reg_wb(uint16_t register_id, uint8_t *data, uint16_t size) { + int spi_stat = LGW_SPI_SUCCESS; + struct lgw_reg_s r; + + /* check input parameters */ + CHECK_NULL(data); + if (size == 0) { + DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n"); + return LGW_REG_ERROR; + } + if (register_id >= LGW_TOTALREGS) { + DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n"); + return LGW_REG_ERROR; + } + + /* check if SPI is initialised */ + if (lgw_spi_target == NULL) { + DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n"); + return LGW_REG_ERROR; + } + + /* get register struct from the struct array */ + r = loregs[register_id]; + + /* reject write to read-only registers */ + if (r.rdon == 1){ + DEBUG_MSG("ERROR: TRYING TO BURST WRITE A READ-ONLY REGISTER\n"); + return LGW_REG_ERROR; + } + + /* do the burst write */ + spi_stat += lgw_spi_wb(lgw_spi_target, LGW_SPI_MUX_TARGET_SX1302, r.addr, data, size); + + if (spi_stat != LGW_SPI_SUCCESS) { + DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER BURST WRITE\n"); + return LGW_REG_ERROR; + } else { + return LGW_REG_SUCCESS; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +/* Point to a register by name and do a burst read */ +int lgw_reg_rb(uint16_t register_id, uint8_t *data, uint16_t size) { + int spi_stat = LGW_SPI_SUCCESS; + struct lgw_reg_s r; + + /* check input parameters */ + CHECK_NULL(data); + if (size == 0) { + DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n"); + return LGW_REG_ERROR; + } + if (register_id >= LGW_TOTALREGS) { + DEBUG_MSG("ERROR: REGISTER NUMBER OUT OF DEFINED RANGE\n"); + return LGW_REG_ERROR; + } + + /* check if SPI is initialised */ + if (lgw_spi_target == NULL) { + DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n"); + return LGW_REG_ERROR; + } + + /* get register struct from the struct array */ + r = loregs[register_id]; + + /* do the burst read */ + spi_stat += lgw_spi_rb(lgw_spi_target, LGW_SPI_MUX_TARGET_SX1302, r.addr, data, size); + + if (spi_stat != LGW_SPI_SUCCESS) { + DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER BURST READ\n"); + return LGW_REG_ERROR; + } else { + return LGW_REG_SUCCESS; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int lgw_mem_wb(uint16_t mem_addr, const uint8_t *data, uint16_t size) { + int spi_stat = LGW_SPI_SUCCESS; + int chunk_cnt = 0; + uint16_t addr = mem_addr; + uint16_t sz_todo = size; + uint16_t chunk_size; + const uint16_t CHUNK_SIZE_MAX = 1024; + + /* check input parameters */ + CHECK_NULL(data); + if (size == 0) { + DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n"); + return LGW_REG_ERROR; + } + + /* check if SPI is initialised */ + if (lgw_spi_target == NULL) { + DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n"); + return LGW_REG_ERROR; + } + + /* write memory by chunks */ + while (sz_todo > 0) { + /* full or partial chunk ? */ + chunk_size = (sz_todo > CHUNK_SIZE_MAX) ? CHUNK_SIZE_MAX : sz_todo; + + /* do the burst write */ + spi_stat += lgw_spi_wb(lgw_spi_target, LGW_SPI_MUX_TARGET_SX1302, addr, &data[chunk_cnt * CHUNK_SIZE_MAX], chunk_size); + + /* prepare for next write */ + addr += chunk_size; + sz_todo -= chunk_size; + chunk_cnt += 1; + } + + if (spi_stat != LGW_SPI_SUCCESS) { + DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER BURST WRITE\n"); + return LGW_REG_ERROR; + } else { + return LGW_REG_SUCCESS; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +int lgw_mem_rb(uint16_t mem_addr, uint8_t *data, uint16_t size, bool fifo_mode) { + int spi_stat = LGW_SPI_SUCCESS; + int chunk_cnt = 0; + uint16_t addr = mem_addr; + uint16_t sz_todo = size; + uint16_t chunk_size; + const uint16_t CHUNK_SIZE_MAX = 1024; + + /* check input parameters */ + CHECK_NULL(data); + if (size == 0) { + DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n"); + return LGW_REG_ERROR; + } + + /* check if SPI is initialised */ + if (lgw_spi_target == NULL) { + DEBUG_MSG("ERROR: CONCENTRATOR UNCONNECTED\n"); + return LGW_REG_ERROR; + } + + /* read memory by chunks */ + while (sz_todo > 0) { + /* full or partial chunk ? */ + chunk_size = (sz_todo > CHUNK_SIZE_MAX) ? CHUNK_SIZE_MAX : sz_todo; + + /* do the burst read */ + spi_stat += lgw_spi_rb(lgw_spi_target, LGW_SPI_MUX_TARGET_SX1302, addr, &data[chunk_cnt * CHUNK_SIZE_MAX], chunk_size); + + /* do not increment the address when the target memory is in FIFO mode (auto-increment) */ + if (fifo_mode == false) { + addr += chunk_size; + } + + /* prepare for next read */ + sz_todo -= chunk_size; + chunk_cnt += 1; + } + + if (spi_stat != LGW_SPI_SUCCESS) { + DEBUG_MSG("ERROR: SPI ERROR DURING REGISTER BURST READ\n"); + return LGW_REG_ERROR; + } else { + return LGW_REG_SUCCESS; + } +} + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_reg.h b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_reg.h new file mode 100644 index 0000000..655616c --- /dev/null +++ b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_reg.h @@ -0,0 +1,1516 @@ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2019 Semtech + +Description: + Functions used to handle a single LoRa SX1302 concentrator. + Registers are addressed by name. + Multi-bytes registers are handled automatically. + Read-modify-write is handled automatically. + +License: Revised BSD License, see LICENSE.TXT file include in the project +*/ + + +#ifndef _LORAGW_REG_H +#define _LORAGW_REG_H + +/* -------------------------------------------------------------------------- */ +/* --- DEPENDANCIES --------------------------------------------------------- */ + +#include /* C99 types */ +#include /* bool type */ + + +/* -------------------------------------------------------------------------- */ +/* --- INTERNAL SHARED TYPES ------------------------------------------------ */ + +struct lgw_reg_s { + int8_t page; /*!< page containing the register (-1 for all pages) */ + uint16_t addr; /*!< base address of the register (15 bit) */ + uint8_t offs; /*!< position of the register LSB (between 0 to 7) */ + bool sign; /*!< 1 indicates the register is signed (2 complem.) */ + uint8_t leng; /*!< number of bits in the register */ + bool rdon; /*!< 1 indicates a read-only register */ + bool chck; /*!< register can be checked or not: (pulse, w0clr, w1clr) */ + int32_t dflt; /*!< register default value */ +}; + +/* -------------------------------------------------------------------------- */ +/* --- INTERNAL SHARED FUNCTIONS -------------------------------------------- */ + +int reg_w_align32(void *spi_target, uint8_t spi_mux_target, struct lgw_reg_s r, int32_t reg_value); +int reg_r_align32(void *spi_target, uint8_t spi_mux_target, struct lgw_reg_s r, int32_t *reg_value); + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC CONSTANTS ----------------------------------------------------- */ + +#define LGW_REG_SUCCESS 0 +#define LGW_REG_ERROR -1 + +#define SX1302_REG_COMMON_PAGE_PAGE 0 +#define SX1302_REG_COMMON_CTRL0_CLK32_RIF_CTRL 1 +#define SX1302_REG_COMMON_CTRL0_HOST_RADIO_CTRL 2 +#define SX1302_REG_COMMON_CTRL0_RADIO_MISC_EN 3 +#define SX1302_REG_COMMON_CTRL0_SX1261_MODE_RADIO_B 4 +#define SX1302_REG_COMMON_CTRL0_SX1261_MODE_RADIO_A 5 +#define SX1302_REG_COMMON_CTRL1_SWAP_IQ_RADIO_B 6 +#define SX1302_REG_COMMON_CTRL1_SAMPLING_EDGE_RADIO_B 7 +#define SX1302_REG_COMMON_CTRL1_SWAP_IQ_RADIO_A 8 +#define SX1302_REG_COMMON_CTRL1_SAMPLING_EDGE_RADIO_A 9 +#define SX1302_REG_COMMON_SPI_DIV_RATIO_SPI_HALF_PERIOD 10 +#define SX1302_REG_COMMON_RADIO_SELECT_RADIO_SELECT 11 +#define SX1302_REG_COMMON_GEN_GLOBAL_EN 12 +#define SX1302_REG_COMMON_GEN_FSK_MODEM_ENABLE 13 +#define SX1302_REG_COMMON_GEN_CONCENTRATOR_MODEM_ENABLE 14 +#define SX1302_REG_COMMON_GEN_MBWSSF_MODEM_ENABLE 15 +#define SX1302_REG_COMMON_VERSION_VERSION 16 +#define SX1302_REG_COMMON_DUMMY_DUMMY 17 +#define SX1302_REG_AGC_MCU_CTRL_CLK_EN 18 +#define SX1302_REG_AGC_MCU_CTRL_FORCE_HOST_FE_CTRL 19 +#define SX1302_REG_AGC_MCU_CTRL_MCU_CLEAR 20 +#define SX1302_REG_AGC_MCU_CTRL_HOST_PROG 21 +#define SX1302_REG_AGC_MCU_CTRL_PARITY_ERROR 22 +#define SX1302_REG_AGC_MCU_MCU_AGC_STATUS_MCU_AGC_STATUS 23 +#define SX1302_REG_AGC_MCU_PA_GAIN_PA_B_GAIN 24 +#define SX1302_REG_AGC_MCU_PA_GAIN_PA_A_GAIN 25 +#define SX1302_REG_AGC_MCU_RF_EN_A_RADIO_RST 26 +#define SX1302_REG_AGC_MCU_RF_EN_A_RADIO_EN 27 +#define SX1302_REG_AGC_MCU_RF_EN_A_PA_EN 28 +#define SX1302_REG_AGC_MCU_RF_EN_A_LNA_EN 29 +#define SX1302_REG_AGC_MCU_RF_EN_B_RADIO_RST 30 +#define SX1302_REG_AGC_MCU_RF_EN_B_RADIO_EN 31 +#define SX1302_REG_AGC_MCU_RF_EN_B_PA_EN 32 +#define SX1302_REG_AGC_MCU_RF_EN_B_LNA_EN 33 +#define SX1302_REG_AGC_MCU_LUT_TABLE_A_PA_LUT 34 +#define SX1302_REG_AGC_MCU_LUT_TABLE_A_LNA_LUT 35 +#define SX1302_REG_AGC_MCU_LUT_TABLE_B_PA_LUT 36 +#define SX1302_REG_AGC_MCU_LUT_TABLE_B_LNA_LUT 37 +#define SX1302_REG_AGC_MCU_UART_CFG_MSBF 38 +#define SX1302_REG_AGC_MCU_UART_CFG_PAR_EN 39 +#define SX1302_REG_AGC_MCU_UART_CFG_PAR_MODE 40 +#define SX1302_REG_AGC_MCU_UART_CFG_START_LEN 41 +#define SX1302_REG_AGC_MCU_UART_CFG_STOP_LEN 42 +#define SX1302_REG_AGC_MCU_UART_CFG_WORD_LEN 43 +#define SX1302_REG_AGC_MCU_UART_CFG2_BIT_RATE 44 +#define SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE3_MCU_MAIL_BOX_WR_DATA 45 +#define SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE2_MCU_MAIL_BOX_WR_DATA 46 +#define SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE1_MCU_MAIL_BOX_WR_DATA 47 +#define SX1302_REG_AGC_MCU_MCU_MAIL_BOX_WR_DATA_BYTE0_MCU_MAIL_BOX_WR_DATA 48 +#define SX1302_REG_AGC_MCU_MCU_MAIL_BOX_RD_DATA_BYTE3_MCU_MAIL_BOX_RD_DATA 49 +#define SX1302_REG_AGC_MCU_MCU_MAIL_BOX_RD_DATA_BYTE2_MCU_MAIL_BOX_RD_DATA 50 +#define SX1302_REG_AGC_MCU_MCU_MAIL_BOX_RD_DATA_BYTE1_MCU_MAIL_BOX_RD_DATA 51 +#define SX1302_REG_AGC_MCU_MCU_MAIL_BOX_RD_DATA_BYTE0_MCU_MAIL_BOX_RD_DATA 52 +#define SX1302_REG_AGC_MCU_DUMMY_DUMMY3 53 +#define SX1302_REG_CLK_CTRL_CLK_SEL_CLKDIV_EN 54 +#define SX1302_REG_CLK_CTRL_CLK_SEL_CLK_RADIO_B_SEL 55 +#define SX1302_REG_CLK_CTRL_CLK_SEL_CLK_RADIO_A_SEL 56 +#define SX1302_REG_CLK_CTRL_DUMMY_DUMMY 57 +#define SX1302_REG_TX_TOP_A_TX_TRIG_TX_FSM_CLR 58 +#define SX1302_REG_TX_TOP_A_TX_TRIG_TX_TRIG_GPS 59 +#define SX1302_REG_TX_TOP_A_TX_TRIG_TX_TRIG_DELAYED 60 +#define SX1302_REG_TX_TOP_A_TX_TRIG_TX_TRIG_IMMEDIATE 61 +#define SX1302_REG_TX_TOP_A_TIMER_TRIG_BYTE3_TIMER_DELAYED_TRIG 62 +#define SX1302_REG_TX_TOP_A_TIMER_TRIG_BYTE2_TIMER_DELAYED_TRIG 63 +#define SX1302_REG_TX_TOP_A_TIMER_TRIG_BYTE1_TIMER_DELAYED_TRIG 64 +#define SX1302_REG_TX_TOP_A_TIMER_TRIG_BYTE0_TIMER_DELAYED_TRIG 65 +#define SX1302_REG_TX_TOP_A_TX_START_DELAY_MSB_TX_START_DELAY 66 +#define SX1302_REG_TX_TOP_A_TX_START_DELAY_LSB_TX_START_DELAY 67 +#define SX1302_REG_TX_TOP_A_TX_CTRL_WRITE_BUFFER 68 +#define SX1302_REG_TX_TOP_A_TX_RAMP_DURATION_TX_RAMP_DURATION 69 +#define SX1302_REG_TX_TOP_A_GEN_CFG_0_MODULATION_TYPE 70 +#define SX1302_REG_TX_TOP_A_TEST_0_TX_ACTIVE_CTRL 71 +#define SX1302_REG_TX_TOP_A_TEST_0_TX_ACTIVE_SEL 72 +#define SX1302_REG_TX_TOP_A_TX_FLAG_TX_TIMEOUT 73 +#define SX1302_REG_TX_TOP_A_TX_FLAG_PKT_DONE 74 +#define SX1302_REG_TX_TOP_A_AGC_TX_BW_AGC_TX_BW 75 +#define SX1302_REG_TX_TOP_A_AGC_TX_PWR_AGC_TX_PWR 76 +#define SX1302_REG_TX_TOP_A_TIMEOUT_CNT_BYTE_2_TIMEOUT_CNT 77 +#define SX1302_REG_TX_TOP_A_TIMEOUT_CNT_BYTE_1_TIMEOUT_CNT 78 +#define SX1302_REG_TX_TOP_A_TIMEOUT_CNT_BYTE_0_TIMEOUT_CNT 79 +#define SX1302_REG_TX_TOP_A_TX_FSM_STATUS_TX_STATUS 80 +#define SX1302_REG_TX_TOP_A_DUMMY_CONTROL_DUMMY 81 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_PLL_DIV_CTRL 82 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_CLK_EDGE 83 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_MODE 84 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_IF_DST 85 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_IF_SRC 86 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL2_SX125X_IQ_INVERT 87 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL2_PLL_DIV_CTRL_AGC 88 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_IQ_GAIN_IQ_GAIN 89 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_I_OFFSET_I_OFFSET 90 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_Q_OFFSET_Q_OFFSET 91 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_RF_H_FREQ_RF 92 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_RF_M_FREQ_RF 93 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_RF_L_FREQ_RF 94 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV 95 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV 96 +#define SX1302_REG_TX_TOP_A_TX_RFFE_IF_TEST_MOD_FREQ 97 +#define SX1302_REG_TX_TOP_A_DUMMY_MODULATOR_DUMMY 98 +#define SX1302_REG_TX_TOP_A_FSK_PKT_LEN_PKT_LENGTH 99 +#define SX1302_REG_TX_TOP_A_FSK_CFG_0_TX_CONT 100 +#define SX1302_REG_TX_TOP_A_FSK_CFG_0_CRC_IBM 101 +#define SX1302_REG_TX_TOP_A_FSK_CFG_0_DCFREE_ENC 102 +#define SX1302_REG_TX_TOP_A_FSK_CFG_0_CRC_EN 103 +#define SX1302_REG_TX_TOP_A_FSK_CFG_0_PKT_MODE 104 +#define SX1302_REG_TX_TOP_A_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE 105 +#define SX1302_REG_TX_TOP_A_FSK_PREAMBLE_SIZE_LSB_PREAMBLE_SIZE 106 +#define SX1302_REG_TX_TOP_A_FSK_BIT_RATE_MSB_BIT_RATE 107 +#define SX1302_REG_TX_TOP_A_FSK_BIT_RATE_LSB_BIT_RATE 108 +#define SX1302_REG_TX_TOP_A_FSK_MOD_FSK_REF_PATTERN_SIZE 109 +#define SX1302_REG_TX_TOP_A_FSK_MOD_FSK_PREAMBLE_SEQ 110 +#define SX1302_REG_TX_TOP_A_FSK_MOD_FSK_REF_PATTERN_EN 111 +#define SX1302_REG_TX_TOP_A_FSK_MOD_FSK_GAUSSIAN_SELECT_BT 112 +#define SX1302_REG_TX_TOP_A_FSK_MOD_FSK_GAUSSIAN_EN 113 +#define SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN 114 +#define SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN 115 +#define SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN 116 +#define SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN 117 +#define SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN 118 +#define SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN 119 +#define SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN 120 +#define SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN 121 +#define SX1302_REG_TX_TOP_A_DUMMY_GSFK_DUMMY 122 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_0_MODEM_BW 123 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_0_MODEM_SF 124 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_1_PPM_OFFSET_HDR_CTRL 125 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_1_PPM_OFFSET 126 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_1_POST_PREAMBLE_GAP_LONG 127 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_1_CODING_RATE 128 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_2_FINE_SYNCH_EN 129 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_2_MODEM_EN 130 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_2_CADRXTX 131 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_2_IMPLICIT_HEADER 132 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_2_CRC_EN 133 +#define SX1302_REG_TX_TOP_A_TXRX_CFG0_3_PAYLOAD_LENGTH 134 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_0_INT_STEP_ORIDE_EN 135 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_0_INT_STEP_ORIDE 136 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_1_MODEM_START 137 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_1_HEADER_DIFF_MODE 138 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_1_ZERO_PAD 139 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_2_PREAMBLE_SYMB_NB 140 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_3_PREAMBLE_SYMB_NB 141 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_4_AUTO_ACK_INT_DELAY 142 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_4_AUTO_ACK_RX 143 +#define SX1302_REG_TX_TOP_A_TXRX_CFG1_4_AUTO_ACK_TX 144 +#define SX1302_REG_TX_TOP_A_TX_CFG0_0_CHIRP_LOWPASS 145 +#define SX1302_REG_TX_TOP_A_TX_CFG0_0_PPM_OFFSET_SIG 146 +#define SX1302_REG_TX_TOP_A_TX_CFG0_0_CONTCHIRP 147 +#define SX1302_REG_TX_TOP_A_TX_CFG0_0_CHIRP_INVERT 148 +#define SX1302_REG_TX_TOP_A_TX_CFG0_0_CONTINUOUS 149 +#define SX1302_REG_TX_TOP_A_TX_CFG0_1_POWER_RANGING 150 +#define SX1302_REG_TX_TOP_A_TX_CFG1_0_FRAME_NB 151 +#define SX1302_REG_TX_TOP_A_TX_CFG1_1_HOP_CTRL 152 +#define SX1302_REG_TX_TOP_A_TX_CFG1_1_IFS 153 +#define SX1302_REG_TX_TOP_A_FRAME_SYNCH_0_AUTO_SCALE 154 +#define SX1302_REG_TX_TOP_A_FRAME_SYNCH_0_DROP_ON_SYNCH 155 +#define SX1302_REG_TX_TOP_A_FRAME_SYNCH_0_GAIN 156 +#define SX1302_REG_TX_TOP_A_FRAME_SYNCH_0_PEAK1_POS 157 +#define SX1302_REG_TX_TOP_A_FRAME_SYNCH_1_FINETIME_ON_LAST 158 +#define SX1302_REG_TX_TOP_A_FRAME_SYNCH_1_TIMEOUT_OPT 159 +#define SX1302_REG_TX_TOP_A_FRAME_SYNCH_1_PEAK2_POS 160 +#define SX1302_REG_TX_TOP_A_LORA_TX_STATE_STATUS 161 +#define SX1302_REG_TX_TOP_A_LORA_TX_FLAG_FRAME_DONE 162 +#define SX1302_REG_TX_TOP_A_LORA_TX_FLAG_CONT_DONE 163 +#define SX1302_REG_TX_TOP_A_LORA_TX_FLAG_PLD_DONE 164 +#define SX1302_REG_TX_TOP_A_DUMMY_LORA_DUMMY 165 +#define SX1302_REG_TX_TOP_B_TX_TRIG_TX_FSM_CLR 166 +#define SX1302_REG_TX_TOP_B_TX_TRIG_TX_TRIG_GPS 167 +#define SX1302_REG_TX_TOP_B_TX_TRIG_TX_TRIG_DELAYED 168 +#define SX1302_REG_TX_TOP_B_TX_TRIG_TX_TRIG_IMMEDIATE 169 +#define SX1302_REG_TX_TOP_B_TIMER_TRIG_BYTE3_TIMER_DELAYED_TRIG 170 +#define SX1302_REG_TX_TOP_B_TIMER_TRIG_BYTE2_TIMER_DELAYED_TRIG 171 +#define SX1302_REG_TX_TOP_B_TIMER_TRIG_BYTE1_TIMER_DELAYED_TRIG 172 +#define SX1302_REG_TX_TOP_B_TIMER_TRIG_BYTE0_TIMER_DELAYED_TRIG 173 +#define SX1302_REG_TX_TOP_B_TX_START_DELAY_MSB_TX_START_DELAY 174 +#define SX1302_REG_TX_TOP_B_TX_START_DELAY_LSB_TX_START_DELAY 175 +#define SX1302_REG_TX_TOP_B_TX_CTRL_WRITE_BUFFER 176 +#define SX1302_REG_TX_TOP_B_TX_RAMP_DURATION_TX_RAMP_DURATION 177 +#define SX1302_REG_TX_TOP_B_GEN_CFG_0_MODULATION_TYPE 178 +#define SX1302_REG_TX_TOP_B_TEST_0_TX_ACTIVE_CTRL 179 +#define SX1302_REG_TX_TOP_B_TEST_0_TX_ACTIVE_SEL 180 +#define SX1302_REG_TX_TOP_B_TX_FLAG_TX_TIMEOUT 181 +#define SX1302_REG_TX_TOP_B_TX_FLAG_PKT_DONE 182 +#define SX1302_REG_TX_TOP_B_AGC_TX_BW_AGC_TX_BW 183 +#define SX1302_REG_TX_TOP_B_AGC_TX_PWR_AGC_TX_PWR 184 +#define SX1302_REG_TX_TOP_B_TIMEOUT_CNT_BYTE_2_TIMEOUT_CNT 185 +#define SX1302_REG_TX_TOP_B_TIMEOUT_CNT_BYTE_1_TIMEOUT_CNT 186 +#define SX1302_REG_TX_TOP_B_TIMEOUT_CNT_BYTE_0_TIMEOUT_CNT 187 +#define SX1302_REG_TX_TOP_B_TX_FSM_STATUS_TX_STATUS 188 +#define SX1302_REG_TX_TOP_B_DUMMY_CONTROL_DUMMY 189 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_PLL_DIV_CTRL 190 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_CLK_EDGE 191 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_MODE 192 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_IF_DST 193 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_IF_SRC 194 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL2_SX125X_IQ_INVERT 195 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL2_PLL_DIV_CTRL_AGC 196 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_IQ_GAIN_IQ_GAIN 197 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_I_OFFSET_I_OFFSET 198 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_Q_OFFSET_Q_OFFSET 199 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_RF_H_FREQ_RF 200 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_RF_M_FREQ_RF 201 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_RF_L_FREQ_RF 202 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV 203 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV 204 +#define SX1302_REG_TX_TOP_B_TX_RFFE_IF_TEST_MOD_FREQ 205 +#define SX1302_REG_TX_TOP_B_DUMMY_MODULATOR_DUMMY 206 +#define SX1302_REG_TX_TOP_B_FSK_PKT_LEN_PKT_LENGTH 207 +#define SX1302_REG_TX_TOP_B_FSK_CFG_0_TX_CONT 208 +#define SX1302_REG_TX_TOP_B_FSK_CFG_0_CRC_IBM 209 +#define SX1302_REG_TX_TOP_B_FSK_CFG_0_DCFREE_ENC 210 +#define SX1302_REG_TX_TOP_B_FSK_CFG_0_CRC_EN 211 +#define SX1302_REG_TX_TOP_B_FSK_CFG_0_PKT_MODE 212 +#define SX1302_REG_TX_TOP_B_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE 213 +#define SX1302_REG_TX_TOP_B_FSK_PREAMBLE_SIZE_LSB_PREAMBLE_SIZE 214 +#define SX1302_REG_TX_TOP_B_FSK_BIT_RATE_MSB_BIT_RATE 215 +#define SX1302_REG_TX_TOP_B_FSK_BIT_RATE_LSB_BIT_RATE 216 +#define SX1302_REG_TX_TOP_B_FSK_MOD_FSK_REF_PATTERN_SIZE 217 +#define SX1302_REG_TX_TOP_B_FSK_MOD_FSK_PREAMBLE_SEQ 218 +#define SX1302_REG_TX_TOP_B_FSK_MOD_FSK_REF_PATTERN_EN 219 +#define SX1302_REG_TX_TOP_B_FSK_MOD_FSK_GAUSSIAN_SELECT_BT 220 +#define SX1302_REG_TX_TOP_B_FSK_MOD_FSK_GAUSSIAN_EN 221 +#define SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN 222 +#define SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN 223 +#define SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN 224 +#define SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN 225 +#define SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN 226 +#define SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN 227 +#define SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN 228 +#define SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN 229 +#define SX1302_REG_TX_TOP_B_DUMMY_GSFK_DUMMY 230 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_0_MODEM_BW 231 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_0_MODEM_SF 232 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_1_PPM_OFFSET_HDR_CTRL 233 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_1_PPM_OFFSET 234 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_1_POST_PREAMBLE_GAP_LONG 235 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_1_CODING_RATE 236 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_2_FINE_SYNCH_EN 237 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_2_MODEM_EN 238 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_2_CADRXTX 239 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_2_IMPLICIT_HEADER 240 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_2_CRC_EN 241 +#define SX1302_REG_TX_TOP_B_TXRX_CFG0_3_PAYLOAD_LENGTH 242 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_0_INT_STEP_ORIDE_EN 243 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_0_INT_STEP_ORIDE 244 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_1_MODEM_START 245 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_1_HEADER_DIFF_MODE 246 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_1_ZERO_PAD 247 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_2_PREAMBLE_SYMB_NB 248 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_3_PREAMBLE_SYMB_NB 249 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_4_AUTO_ACK_INT_DELAY 250 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_4_AUTO_ACK_RX 251 +#define SX1302_REG_TX_TOP_B_TXRX_CFG1_4_AUTO_ACK_TX 252 +#define SX1302_REG_TX_TOP_B_TX_CFG0_0_CHIRP_LOWPASS 253 +#define SX1302_REG_TX_TOP_B_TX_CFG0_0_PPM_OFFSET_SIG 254 +#define SX1302_REG_TX_TOP_B_TX_CFG0_0_CONTCHIRP 255 +#define SX1302_REG_TX_TOP_B_TX_CFG0_0_CHIRP_INVERT 256 +#define SX1302_REG_TX_TOP_B_TX_CFG0_0_CONTINUOUS 257 +#define SX1302_REG_TX_TOP_B_TX_CFG0_1_POWER_RANGING 258 +#define SX1302_REG_TX_TOP_B_TX_CFG1_0_FRAME_NB 259 +#define SX1302_REG_TX_TOP_B_TX_CFG1_1_HOP_CTRL 260 +#define SX1302_REG_TX_TOP_B_TX_CFG1_1_IFS 261 +#define SX1302_REG_TX_TOP_B_FRAME_SYNCH_0_AUTO_SCALE 262 +#define SX1302_REG_TX_TOP_B_FRAME_SYNCH_0_DROP_ON_SYNCH 263 +#define SX1302_REG_TX_TOP_B_FRAME_SYNCH_0_GAIN 264 +#define SX1302_REG_TX_TOP_B_FRAME_SYNCH_0_PEAK1_POS 265 +#define SX1302_REG_TX_TOP_B_FRAME_SYNCH_1_FINETIME_ON_LAST 266 +#define SX1302_REG_TX_TOP_B_FRAME_SYNCH_1_TIMEOUT_OPT 267 +#define SX1302_REG_TX_TOP_B_FRAME_SYNCH_1_PEAK2_POS 268 +#define SX1302_REG_TX_TOP_B_LORA_TX_STATE_STATUS 269 +#define SX1302_REG_TX_TOP_B_LORA_TX_FLAG_FRAME_DONE 270 +#define SX1302_REG_TX_TOP_B_LORA_TX_FLAG_CONT_DONE 271 +#define SX1302_REG_TX_TOP_B_LORA_TX_FLAG_PLD_DONE 272 +#define SX1302_REG_TX_TOP_B_DUMMY_LORA_DUMMY 273 +#define SX1302_REG_GPIO_GPIO_DIR_H_DIRECTION 274 +#define SX1302_REG_GPIO_GPIO_DIR_L_DIRECTION 275 +#define SX1302_REG_GPIO_GPIO_OUT_H_OUT_VALUE 276 +#define SX1302_REG_GPIO_GPIO_OUT_L_OUT_VALUE 277 +#define SX1302_REG_GPIO_GPIO_IN_H_IN_VALUE 278 +#define SX1302_REG_GPIO_GPIO_IN_L_IN_VALUE 279 +#define SX1302_REG_GPIO_GPIO_PD_H_PD_VALUE 280 +#define SX1302_REG_GPIO_GPIO_PD_L_PD_VALUE 281 +#define SX1302_REG_GPIO_GPIO_SEL_0_SELECTION 282 +#define SX1302_REG_GPIO_GPIO_SEL_1_SELECTION 283 +#define SX1302_REG_GPIO_GPIO_SEL_2_SELECTION 284 +#define SX1302_REG_GPIO_GPIO_SEL_3_SELECTION 285 +#define SX1302_REG_GPIO_GPIO_SEL_4_SELECTION 286 +#define SX1302_REG_GPIO_GPIO_SEL_5_SELECTION 287 +#define SX1302_REG_GPIO_GPIO_SEL_6_SELECTION 288 +#define SX1302_REG_GPIO_GPIO_SEL_7_SELECTION 289 +#define SX1302_REG_GPIO_GPIO_SEL_8_11_GPIO_11_9_SEL 290 +#define SX1302_REG_GPIO_GPIO_SEL_8_11_GPIO_8_SEL 291 +#define SX1302_REG_GPIO_HOST_IRQ_TX_TIMEOUT_B 292 +#define SX1302_REG_GPIO_HOST_IRQ_TX_TIMEOUT_A 293 +#define SX1302_REG_GPIO_HOST_IRQ_TX_DONE_B 294 +#define SX1302_REG_GPIO_HOST_IRQ_TX_DONE_A 295 +#define SX1302_REG_GPIO_HOST_IRQ_TIMESTAMP 296 +#define SX1302_REG_GPIO_HOST_IRQ_RX_BUFFER_WATERMARK 297 +#define SX1302_REG_GPIO_HOST_IRQ_EN_TX_TIMEOUT_B 298 +#define SX1302_REG_GPIO_HOST_IRQ_EN_TX_TIMEOUT_A 299 +#define SX1302_REG_GPIO_HOST_IRQ_EN_TX_DONE_B 300 +#define SX1302_REG_GPIO_HOST_IRQ_EN_TX_DONE_A 301 +#define SX1302_REG_GPIO_HOST_IRQ_EN_TIMESTAMP 302 +#define SX1302_REG_GPIO_HOST_IRQ_EN_RX_BUFFER_WATERMARK 303 +#define SX1302_REG_GPIO_DUMMY_DUMMY 304 +#define SX1302_REG_TIMESTAMP_GPS_CTRL_GPS_POL 305 +#define SX1302_REG_TIMESTAMP_GPS_CTRL_GPS_EN 306 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_PPS_MSB2_TIMESTAMP_PPS 307 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_PPS_MSB1_TIMESTAMP_PPS 308 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_PPS_LSB2_TIMESTAMP_PPS 309 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_PPS_LSB1_TIMESTAMP_PPS 310 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_MSB2_TIMESTAMP 311 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_MSB1_TIMESTAMP 312 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_LSB2_TIMESTAMP 313 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_LSB1_TIMESTAMP 314 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_SET3_TIMESTAMP 315 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_SET2_TIMESTAMP 316 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_SET1_TIMESTAMP 317 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_SET0_TIMESTAMP 318 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_IRQ_3_TIMESTAMP 319 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_IRQ_2_TIMESTAMP 320 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_IRQ_1_TIMESTAMP 321 +#define SX1302_REG_TIMESTAMP_TIMESTAMP_IRQ_0_TIMESTAMP 322 +#define SX1302_REG_TIMESTAMP_DUMMY_DUMMY 323 +#define SX1302_REG_RX_TOP_FREQ_0_MSB_IF_FREQ_0 324 +#define SX1302_REG_RX_TOP_FREQ_0_LSB_IF_FREQ_0 325 +#define SX1302_REG_RX_TOP_FREQ_1_MSB_IF_FREQ_1 326 +#define SX1302_REG_RX_TOP_FREQ_1_LSB_IF_FREQ_1 327 +#define SX1302_REG_RX_TOP_FREQ_2_MSB_IF_FREQ_2 328 +#define SX1302_REG_RX_TOP_FREQ_2_LSB_IF_FREQ_2 329 +#define SX1302_REG_RX_TOP_FREQ_3_MSB_IF_FREQ_3 330 +#define SX1302_REG_RX_TOP_FREQ_3_LSB_IF_FREQ_3 331 +#define SX1302_REG_RX_TOP_FREQ_4_MSB_IF_FREQ_4 332 +#define SX1302_REG_RX_TOP_FREQ_4_LSB_IF_FREQ_4 333 +#define SX1302_REG_RX_TOP_FREQ_5_MSB_IF_FREQ_5 334 +#define SX1302_REG_RX_TOP_FREQ_5_LSB_IF_FREQ_5 335 +#define SX1302_REG_RX_TOP_FREQ_6_MSB_IF_FREQ_6 336 +#define SX1302_REG_RX_TOP_FREQ_6_LSB_IF_FREQ_6 337 +#define SX1302_REG_RX_TOP_FREQ_7_MSB_IF_FREQ_7 338 +#define SX1302_REG_RX_TOP_FREQ_7_LSB_IF_FREQ_7 339 +#define SX1302_REG_RX_TOP_RADIO_SELECT_RADIO_SELECT 340 +#define SX1302_REG_RX_TOP_RSSI_CONTROL_RSSI_FILTER_ALPHA 341 +#define SX1302_REG_RX_TOP_RSSI_CONTROL_SELECT_RSSI 342 +#define SX1302_REG_RX_TOP_RSSI_DEF_VALUE_CHAN_RSSI_DEF_VALUE 343 +#define SX1302_REG_RX_TOP_CHANN_DAGC_CFG1_CHAN_DAGC_THRESHOLD_HIGH 344 +#define SX1302_REG_RX_TOP_CHANN_DAGC_CFG2_CHAN_DAGC_THRESHOLD_LOW 345 +#define SX1302_REG_RX_TOP_CHANN_DAGC_CFG3_CHAN_DAGC_MAX_ATTEN 346 +#define SX1302_REG_RX_TOP_CHANN_DAGC_CFG3_CHAN_DAGC_MIN_ATTEN 347 +#define SX1302_REG_RX_TOP_CHANN_DAGC_CFG4_CHAN_DAGC_STEP 348 +#define SX1302_REG_RX_TOP_CHANN_DAGC_CFG5_CHAN_DAGC_MODE 349 +#define SX1302_REG_RX_TOP_RSSI_VALUE_CHAN_RSSI 350 +#define SX1302_REG_RX_TOP_GAIN_CONTROL_CHAN_GAIN_VALID 351 +#define SX1302_REG_RX_TOP_GAIN_CONTROL_CHAN_GAIN 352 +#define SX1302_REG_RX_TOP_CLK_CONTROL_CHAN_CLK_EN 353 +#define SX1302_REG_RX_TOP_DUMMY0_DUMMY0 354 +#define SX1302_REG_RX_TOP_CORR_CLOCK_ENABLE_CLK_EN 355 +#define SX1302_REG_RX_TOP_CORRELATOR_EN_CORR_EN 356 +#define SX1302_REG_RX_TOP_CORRELATOR_SF_EN_CORR_SF_EN 357 +#define SX1302_REG_RX_TOP_CORRELATOR_ENABLE_ONLY_FIRST_DET_EDGE_ENABLE_ONLY_FIRST_DET_EDGE 358 +#define SX1302_REG_RX_TOP_CORRELATOR_ENABLE_ACC_CLEAR_ENABLE_CORR_ACC_CLEAR 359 +#define SX1302_REG_RX_TOP_SF5_CFG1_ACC_WIN_LEN 360 +#define SX1302_REG_RX_TOP_SF5_CFG1_ACC_PEAK_SUM_EN 361 +#define SX1302_REG_RX_TOP_SF5_CFG1_ACC_PEAK_POS_SEL 362 +#define SX1302_REG_RX_TOP_SF5_CFG1_ACC_COEFF 363 +#define SX1302_REG_RX_TOP_SF5_CFG1_ACC_AUTO_RESCALE 364 +#define SX1302_REG_RX_TOP_SF5_CFG1_ACC_2_SAME_PEAKS 365 +#define SX1302_REG_RX_TOP_SF5_CFG2_ACC_MIN2 366 +#define SX1302_REG_RX_TOP_SF5_CFG2_ACC_PNR 367 +#define SX1302_REG_RX_TOP_SF5_CFG3_MIN_SINGLE_PEAK 368 +#define SX1302_REG_RX_TOP_SF5_CFG4_MSP_PNR 369 +#define SX1302_REG_RX_TOP_SF5_CFG5_MSP2_PNR 370 +#define SX1302_REG_RX_TOP_SF5_CFG6_MSP_PEAK_NB 371 +#define SX1302_REG_RX_TOP_SF5_CFG6_MSP_CNT_MODE 372 +#define SX1302_REG_RX_TOP_SF5_CFG6_MSP_POS_SEL 373 +#define SX1302_REG_RX_TOP_SF5_CFG7_MSP2_PEAK_NB 374 +#define SX1302_REG_RX_TOP_SF5_CFG7_NOISE_COEFF 375 +#define SX1302_REG_RX_TOP_SF6_CFG1_ACC_WIN_LEN 376 +#define SX1302_REG_RX_TOP_SF6_CFG1_ACC_PEAK_SUM_EN 377 +#define SX1302_REG_RX_TOP_SF6_CFG1_ACC_PEAK_POS_SEL 378 +#define SX1302_REG_RX_TOP_SF6_CFG1_ACC_COEFF 379 +#define SX1302_REG_RX_TOP_SF6_CFG1_ACC_AUTO_RESCALE 380 +#define SX1302_REG_RX_TOP_SF6_CFG1_ACC_2_SAME_PEAKS 381 +#define SX1302_REG_RX_TOP_SF6_CFG2_ACC_MIN2 382 +#define SX1302_REG_RX_TOP_SF6_CFG2_ACC_PNR 383 +#define SX1302_REG_RX_TOP_SF6_CFG3_MIN_SINGLE_PEAK 384 +#define SX1302_REG_RX_TOP_SF6_CFG4_MSP_PNR 385 +#define SX1302_REG_RX_TOP_SF6_CFG5_MSP2_PNR 386 +#define SX1302_REG_RX_TOP_SF6_CFG6_MSP_PEAK_NB 387 +#define SX1302_REG_RX_TOP_SF6_CFG6_MSP_CNT_MODE 388 +#define SX1302_REG_RX_TOP_SF6_CFG6_MSP_POS_SEL 389 +#define SX1302_REG_RX_TOP_SF6_CFG7_MSP2_PEAK_NB 390 +#define SX1302_REG_RX_TOP_SF6_CFG7_NOISE_COEFF 391 +#define SX1302_REG_RX_TOP_SF7_CFG1_ACC_WIN_LEN 392 +#define SX1302_REG_RX_TOP_SF7_CFG1_ACC_PEAK_SUM_EN 393 +#define SX1302_REG_RX_TOP_SF7_CFG1_ACC_PEAK_POS_SEL 394 +#define SX1302_REG_RX_TOP_SF7_CFG1_ACC_COEFF 395 +#define SX1302_REG_RX_TOP_SF7_CFG1_ACC_AUTO_RESCALE 396 +#define SX1302_REG_RX_TOP_SF7_CFG1_ACC_2_SAME_PEAKS 397 +#define SX1302_REG_RX_TOP_SF7_CFG2_ACC_MIN2 398 +#define SX1302_REG_RX_TOP_SF7_CFG2_ACC_PNR 399 +#define SX1302_REG_RX_TOP_SF7_CFG3_MIN_SINGLE_PEAK 400 +#define SX1302_REG_RX_TOP_SF7_CFG4_MSP_PNR 401 +#define SX1302_REG_RX_TOP_SF7_CFG5_MSP2_PNR 402 +#define SX1302_REG_RX_TOP_SF7_CFG6_MSP_PEAK_NB 403 +#define SX1302_REG_RX_TOP_SF7_CFG6_MSP_CNT_MODE 404 +#define SX1302_REG_RX_TOP_SF7_CFG6_MSP_POS_SEL 405 +#define SX1302_REG_RX_TOP_SF7_CFG7_MSP2_PEAK_NB 406 +#define SX1302_REG_RX_TOP_SF7_CFG7_NOISE_COEFF 407 +#define SX1302_REG_RX_TOP_SF8_CFG1_ACC_WIN_LEN 408 +#define SX1302_REG_RX_TOP_SF8_CFG1_ACC_PEAK_SUM_EN 409 +#define SX1302_REG_RX_TOP_SF8_CFG1_ACC_PEAK_POS_SEL 410 +#define SX1302_REG_RX_TOP_SF8_CFG1_ACC_COEFF 411 +#define SX1302_REG_RX_TOP_SF8_CFG1_ACC_AUTO_RESCALE 412 +#define SX1302_REG_RX_TOP_SF8_CFG1_ACC_2_SAME_PEAKS 413 +#define SX1302_REG_RX_TOP_SF8_CFG2_ACC_MIN2 414 +#define SX1302_REG_RX_TOP_SF8_CFG2_ACC_PNR 415 +#define SX1302_REG_RX_TOP_SF8_CFG3_MIN_SINGLE_PEAK 416 +#define SX1302_REG_RX_TOP_SF8_CFG4_MSP_PNR 417 +#define SX1302_REG_RX_TOP_SF8_CFG5_MSP2_PNR 418 +#define SX1302_REG_RX_TOP_SF8_CFG6_MSP_PEAK_NB 419 +#define SX1302_REG_RX_TOP_SF8_CFG6_MSP_CNT_MODE 420 +#define SX1302_REG_RX_TOP_SF8_CFG6_MSP_POS_SEL 421 +#define SX1302_REG_RX_TOP_SF8_CFG7_MSP2_PEAK_NB 422 +#define SX1302_REG_RX_TOP_SF8_CFG7_NOISE_COEFF 423 +#define SX1302_REG_RX_TOP_SF9_CFG1_ACC_WIN_LEN 424 +#define SX1302_REG_RX_TOP_SF9_CFG1_ACC_PEAK_SUM_EN 425 +#define SX1302_REG_RX_TOP_SF9_CFG1_ACC_PEAK_POS_SEL 426 +#define SX1302_REG_RX_TOP_SF9_CFG1_ACC_COEFF 427 +#define SX1302_REG_RX_TOP_SF9_CFG1_ACC_AUTO_RESCALE 428 +#define SX1302_REG_RX_TOP_SF9_CFG1_ACC_2_SAME_PEAKS 429 +#define SX1302_REG_RX_TOP_SF9_CFG2_ACC_MIN2 430 +#define SX1302_REG_RX_TOP_SF9_CFG2_ACC_PNR 431 +#define SX1302_REG_RX_TOP_SF9_CFG3_MIN_SINGLE_PEAK 432 +#define SX1302_REG_RX_TOP_SF9_CFG4_MSP_PNR 433 +#define SX1302_REG_RX_TOP_SF9_CFG5_MSP2_PNR 434 +#define SX1302_REG_RX_TOP_SF9_CFG6_MSP_PEAK_NB 435 +#define SX1302_REG_RX_TOP_SF9_CFG6_MSP_CNT_MODE 436 +#define SX1302_REG_RX_TOP_SF9_CFG6_MSP_POS_SEL 437 +#define SX1302_REG_RX_TOP_SF9_CFG7_MSP2_PEAK_NB 438 +#define SX1302_REG_RX_TOP_SF9_CFG7_NOISE_COEFF 439 +#define SX1302_REG_RX_TOP_SF10_CFG1_ACC_WIN_LEN 440 +#define SX1302_REG_RX_TOP_SF10_CFG1_ACC_PEAK_SUM_EN 441 +#define SX1302_REG_RX_TOP_SF10_CFG1_ACC_PEAK_POS_SEL 442 +#define SX1302_REG_RX_TOP_SF10_CFG1_ACC_COEFF 443 +#define SX1302_REG_RX_TOP_SF10_CFG1_ACC_AUTO_RESCALE 444 +#define SX1302_REG_RX_TOP_SF10_CFG1_ACC_2_SAME_PEAKS 445 +#define SX1302_REG_RX_TOP_SF10_CFG2_ACC_MIN2 446 +#define SX1302_REG_RX_TOP_SF10_CFG2_ACC_PNR 447 +#define SX1302_REG_RX_TOP_SF10_CFG3_MIN_SINGLE_PEAK 448 +#define SX1302_REG_RX_TOP_SF10_CFG4_MSP_PNR 449 +#define SX1302_REG_RX_TOP_SF10_CFG5_MSP2_PNR 450 +#define SX1302_REG_RX_TOP_SF10_CFG6_MSP_PEAK_NB 451 +#define SX1302_REG_RX_TOP_SF10_CFG6_MSP_CNT_MODE 452 +#define SX1302_REG_RX_TOP_SF10_CFG6_MSP_POS_SEL 453 +#define SX1302_REG_RX_TOP_SF10_CFG7_MSP2_PEAK_NB 454 +#define SX1302_REG_RX_TOP_SF10_CFG7_NOISE_COEFF 455 +#define SX1302_REG_RX_TOP_SF11_CFG1_ACC_WIN_LEN 456 +#define SX1302_REG_RX_TOP_SF11_CFG1_ACC_PEAK_SUM_EN 457 +#define SX1302_REG_RX_TOP_SF11_CFG1_ACC_PEAK_POS_SEL 458 +#define SX1302_REG_RX_TOP_SF11_CFG1_ACC_COEFF 459 +#define SX1302_REG_RX_TOP_SF11_CFG1_ACC_AUTO_RESCALE 460 +#define SX1302_REG_RX_TOP_SF11_CFG1_ACC_2_SAME_PEAKS 461 +#define SX1302_REG_RX_TOP_SF11_CFG2_ACC_MIN2 462 +#define SX1302_REG_RX_TOP_SF11_CFG2_ACC_PNR 463 +#define SX1302_REG_RX_TOP_SF11_CFG3_MIN_SINGLE_PEAK 464 +#define SX1302_REG_RX_TOP_SF11_CFG4_MSP_PNR 465 +#define SX1302_REG_RX_TOP_SF11_CFG5_MSP2_PNR 466 +#define SX1302_REG_RX_TOP_SF11_CFG6_MSP_PEAK_NB 467 +#define SX1302_REG_RX_TOP_SF11_CFG6_MSP_CNT_MODE 468 +#define SX1302_REG_RX_TOP_SF11_CFG6_MSP_POS_SEL 469 +#define SX1302_REG_RX_TOP_SF11_CFG7_MSP2_PEAK_NB 470 +#define SX1302_REG_RX_TOP_SF11_CFG7_NOISE_COEFF 471 +#define SX1302_REG_RX_TOP_SF12_CFG1_ACC_WIN_LEN 472 +#define SX1302_REG_RX_TOP_SF12_CFG1_ACC_PEAK_SUM_EN 473 +#define SX1302_REG_RX_TOP_SF12_CFG1_ACC_PEAK_POS_SEL 474 +#define SX1302_REG_RX_TOP_SF12_CFG1_ACC_COEFF 475 +#define SX1302_REG_RX_TOP_SF12_CFG1_ACC_AUTO_RESCALE 476 +#define SX1302_REG_RX_TOP_SF12_CFG1_ACC_2_SAME_PEAKS 477 +#define SX1302_REG_RX_TOP_SF12_CFG2_ACC_MIN2 478 +#define SX1302_REG_RX_TOP_SF12_CFG2_ACC_PNR 479 +#define SX1302_REG_RX_TOP_SF12_CFG3_MIN_SINGLE_PEAK 480 +#define SX1302_REG_RX_TOP_SF12_CFG4_MSP_PNR 481 +#define SX1302_REG_RX_TOP_SF12_CFG5_MSP2_PNR 482 +#define SX1302_REG_RX_TOP_SF12_CFG6_MSP_PEAK_NB 483 +#define SX1302_REG_RX_TOP_SF12_CFG6_MSP_CNT_MODE 484 +#define SX1302_REG_RX_TOP_SF12_CFG6_MSP_POS_SEL 485 +#define SX1302_REG_RX_TOP_SF12_CFG7_MSP2_PEAK_NB 486 +#define SX1302_REG_RX_TOP_SF12_CFG7_NOISE_COEFF 487 +#define SX1302_REG_RX_TOP_DUMMY1_DUMMY1 488 +#define SX1302_REG_RX_TOP_DC_NOTCH_CFG1_BW_START 489 +#define SX1302_REG_RX_TOP_DC_NOTCH_CFG1_AUTO_BW_RED 490 +#define SX1302_REG_RX_TOP_DC_NOTCH_CFG1_NO_FAST_START 491 +#define SX1302_REG_RX_TOP_DC_NOTCH_CFG1_BYPASS 492 +#define SX1302_REG_RX_TOP_DC_NOTCH_CFG1_ENABLE 493 +#define SX1302_REG_RX_TOP_DC_NOTCH_CFG2_BW_LOCKED 494 +#define SX1302_REG_RX_TOP_DC_NOTCH_CFG2_BW 495 +#define SX1302_REG_RX_TOP_DC_NOTCH_CFG3_BW_RED 496 +#define SX1302_REG_RX_TOP_DC_NOTCH_CFG4_IIR_DCC_TIME 497 +#define SX1302_REG_RX_TOP_RX_DFE_FIR1_0_FIR1_COEFF_0 498 +#define SX1302_REG_RX_TOP_RX_DFE_FIR1_1_FIR1_COEFF_1 499 +#define SX1302_REG_RX_TOP_RX_DFE_FIR1_2_FIR1_COEFF_2 500 +#define SX1302_REG_RX_TOP_RX_DFE_FIR1_3_FIR1_COEFF_3 501 +#define SX1302_REG_RX_TOP_RX_DFE_FIR1_4_FIR1_COEFF_4 502 +#define SX1302_REG_RX_TOP_RX_DFE_FIR1_5_FIR1_COEFF_5 503 +#define SX1302_REG_RX_TOP_RX_DFE_FIR1_6_FIR1_COEFF_6 504 +#define SX1302_REG_RX_TOP_RX_DFE_FIR1_7_FIR1_COEFF_7 505 +#define SX1302_REG_RX_TOP_RX_DFE_FIR2_0_FIR2_COEFF_0 506 +#define SX1302_REG_RX_TOP_RX_DFE_FIR2_1_FIR2_COEFF_1 507 +#define SX1302_REG_RX_TOP_RX_DFE_FIR2_2_FIR2_COEFF_2 508 +#define SX1302_REG_RX_TOP_RX_DFE_FIR2_3_FIR2_COEFF_3 509 +#define SX1302_REG_RX_TOP_RX_DFE_FIR2_4_FIR2_COEFF_4 510 +#define SX1302_REG_RX_TOP_RX_DFE_FIR2_5_FIR2_COEFF_5 511 +#define SX1302_REG_RX_TOP_RX_DFE_FIR2_6_FIR2_COEFF_6 512 +#define SX1302_REG_RX_TOP_RX_DFE_FIR2_7_FIR2_COEFF_7 513 +#define SX1302_REG_RX_TOP_RX_DFE_AGC0_RADIO_GAIN_RED_SEL 514 +#define SX1302_REG_RX_TOP_RX_DFE_AGC0_RADIO_GAIN_RED_DB 515 +#define SX1302_REG_RX_TOP_RX_DFE_AGC1_DC_COMP_EN 516 +#define SX1302_REG_RX_TOP_RX_DFE_AGC1_FORCE_DEFAULT_FIR 517 +#define SX1302_REG_RX_TOP_RX_DFE_AGC1_RSSI_EARLY_LATCH 518 +#define SX1302_REG_RX_TOP_RX_DFE_AGC1_FREEZE_ON_SYNC 519 +#define SX1302_REG_RX_TOP_RX_DFE_AGC2_DAGC_IN_COMP 520 +#define SX1302_REG_RX_TOP_RX_DFE_AGC2_DAGC_FIR_HYST 521 +#define SX1302_REG_RX_TOP_RX_DFE_AGC2_RSSI_MAX_SAMPLE 522 +#define SX1302_REG_RX_TOP_RX_DFE_AGC2_RSSI_MIN_SAMPLE 523 +#define SX1302_REG_RX_TOP_RX_DFE_GAIN0_DAGC_FIR_FAST 524 +#define SX1302_REG_RX_TOP_RX_DFE_GAIN0_FORCE_GAIN_FIR 525 +#define SX1302_REG_RX_TOP_RX_DFE_GAIN0_GAIN_FIR1 526 +#define SX1302_REG_RX_TOP_RX_DFE_GAIN0_GAIN_FIR2 527 +#define SX1302_REG_RX_TOP_DAGC_CFG_TARGET_LVL 528 +#define SX1302_REG_RX_TOP_DAGC_CFG_GAIN_INCR_STEP 529 +#define SX1302_REG_RX_TOP_DAGC_CFG_GAIN_DROP_COMP 530 +#define SX1302_REG_RX_TOP_DAGC_CFG_COMB_FILTER_EN 531 +#define SX1302_REG_RX_TOP_DAGC_CFG_NO_FREEZE_START 532 +#define SX1302_REG_RX_TOP_DAGC_CFG_FREEZE_ON_SYNC 533 +#define SX1302_REG_RX_TOP_DAGC_CNT0_SAMPLE 534 +#define SX1302_REG_RX_TOP_DAGC_CNT1_THR_M6 535 +#define SX1302_REG_RX_TOP_DAGC_CNT2_THR_M12 536 +#define SX1302_REG_RX_TOP_DAGC_CNT3_THR_M18 537 +#define SX1302_REG_RX_TOP_DAGC_CNT4_GAIN 538 +#define SX1302_REG_RX_TOP_DAGC_CNT4_FORCE_GAIN 539 +#define SX1302_REG_RX_TOP_TXRX_CFG1_PPM_OFFSET_HDR_CTRL 540 +#define SX1302_REG_RX_TOP_TXRX_CFG1_PPM_OFFSET 541 +#define SX1302_REG_RX_TOP_TXRX_CFG1_MODEM_EN 542 +#define SX1302_REG_RX_TOP_TXRX_CFG1_CODING_RATE 543 +#define SX1302_REG_RX_TOP_TXRX_CFG2_MODEM_START 544 +#define SX1302_REG_RX_TOP_TXRX_CFG2_CADRXTX 545 +#define SX1302_REG_RX_TOP_TXRX_CFG2_IMPLICIT_HEADER 546 +#define SX1302_REG_RX_TOP_TXRX_CFG2_CRC_EN 547 +#define SX1302_REG_RX_TOP_TXRX_CFG3_PAYLOAD_LENGTH 548 +#define SX1302_REG_RX_TOP_TXRX_CFG4_INT_STEP_ORIDE_EN 549 +#define SX1302_REG_RX_TOP_TXRX_CFG4_INT_STEP_ORIDE 550 +#define SX1302_REG_RX_TOP_TXRX_CFG5_HEADER_DIFF_MODE 551 +#define SX1302_REG_RX_TOP_TXRX_CFG5_ZERO_PAD 552 +#define SX1302_REG_RX_TOP_TXRX_CFG6_PREAMBLE_SYMB_NB 553 +#define SX1302_REG_RX_TOP_TXRX_CFG7_PREAMBLE_SYMB_NB 554 +#define SX1302_REG_RX_TOP_TXRX_CFG8_AUTO_ACK_INT_DELAY 555 +#define SX1302_REG_RX_TOP_TXRX_CFG8_AUTO_ACK_RX 556 +#define SX1302_REG_RX_TOP_TXRX_CFG8_AUTO_ACK_TX 557 +#define SX1302_REG_RX_TOP_TXRX_CFG8_POST_PREAMBLE_GAP_LONG 558 +#define SX1302_REG_RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF12 559 +#define SX1302_REG_RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF11 560 +#define SX1302_REG_RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF10 561 +#define SX1302_REG_RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF9 562 +#define SX1302_REG_RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF8 563 +#define SX1302_REG_RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF7 564 +#define SX1302_REG_RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF6 565 +#define SX1302_REG_RX_TOP_TXRX_CFG9_FINE_SYNCH_EN_SF5 566 +#define SX1302_REG_RX_TOP_RX_CFG0_DFT_PEAK_EN 567 +#define SX1302_REG_RX_TOP_RX_CFG0_CHIRP_INVERT 568 +#define SX1302_REG_RX_TOP_RX_CFG0_SWAP_IQ 569 +#define SX1302_REG_RX_TOP_RX_CFG0_CONTINUOUS 570 +#define SX1302_REG_RX_TOP_RX_CFG1_DETECT_TIMEOUT 571 +#define SX1302_REG_RX_TOP_RX_CFG2_CLK_EN_RESYNC_DIN 572 +#define SX1302_REG_RX_TOP_RX_CFG2_LLR_SCALE 573 +#define SX1302_REG_RX_TOP_FRAME_SYNCH0_SF5_PEAK1_POS_SF5 574 +#define SX1302_REG_RX_TOP_FRAME_SYNCH1_SF5_PEAK2_POS_SF5 575 +#define SX1302_REG_RX_TOP_FRAME_SYNCH0_SF6_PEAK1_POS_SF6 576 +#define SX1302_REG_RX_TOP_FRAME_SYNCH1_SF6_PEAK2_POS_SF6 577 +#define SX1302_REG_RX_TOP_FRAME_SYNCH0_SF7TO12_PEAK1_POS_SF7TO12 578 +#define SX1302_REG_RX_TOP_FRAME_SYNCH1_SF7TO12_PEAK2_POS_SF7TO12 579 +#define SX1302_REG_RX_TOP_FRAME_SYNCH2_FINETIME_ON_LAST 580 +#define SX1302_REG_RX_TOP_FRAME_SYNCH2_AUTO_SCALE 581 +#define SX1302_REG_RX_TOP_FRAME_SYNCH2_DROP_ON_SYNCH 582 +#define SX1302_REG_RX_TOP_FRAME_SYNCH2_GAIN 583 +#define SX1302_REG_RX_TOP_FRAME_SYNCH2_TIMEOUT_OPT 584 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_0_GAIN_P_HDR_RED 585 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_0_ROUNDING 586 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_0_POS_LIMIT 587 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_0_SUM_SIZE 588 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_0_MODE 589 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_1_GAIN_P_AUTO 590 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_1_GAIN_P_PAYLOAD 591 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_1_GAIN_P_PREAMB 592 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_2_GAIN_I_AUTO 593 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_2_GAIN_I_PAYLOAD 594 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_2_GAIN_I_PREAMB 595 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_3_FINESYNCH_SUM 596 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_3_FINESYNCH_GAIN 597 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_4_GAIN_I_EN_SF8 598 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_4_GAIN_I_EN_SF7 599 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_4_GAIN_I_EN_SF6 600 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_4_GAIN_I_EN_SF5 601 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF12 602 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF11 603 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF10 604 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_5_GAIN_I_EN_SF9 605 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_6_GAIN_P_PREAMB_SF12 606 +#define SX1302_REG_RX_TOP_FINE_TIMING_A_6_GAIN_P_PREAMB_SF5_6 607 +#define SX1302_REG_RX_TOP_FINE_TIMING_7_GAIN_I_AUTO_MAX 608 +#define SX1302_REG_RX_TOP_FINE_TIMING_7_GAIN_P_AUTO_MAX 609 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_0_GAIN_P_HDR_RED 610 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_0_ROUNDING 611 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_0_POS_LIMIT 612 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_0_SUM_SIZE 613 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_0_MODE 614 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_1_GAIN_P_AUTO 615 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_1_GAIN_P_PAYLOAD 616 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_1_GAIN_P_PREAMB 617 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_2_GAIN_I_AUTO 618 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_2_GAIN_I_PAYLOAD 619 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_2_GAIN_I_PREAMB 620 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_3_FINESYNCH_SUM 621 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_3_FINESYNCH_GAIN 622 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_4_GAIN_I_EN_SF8 623 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_4_GAIN_I_EN_SF7 624 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_4_GAIN_I_EN_SF6 625 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_4_GAIN_I_EN_SF5 626 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF12 627 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF11 628 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF10 629 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_5_GAIN_I_EN_SF9 630 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_6_GAIN_P_PREAMB_SF12 631 +#define SX1302_REG_RX_TOP_FINE_TIMING_B_6_GAIN_P_PREAMB_SF5_6 632 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME0_FREQ_TO_TIME_DRIFT_MANT 633 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME1_FREQ_TO_TIME_DRIFT_MANT 634 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME2_FREQ_TO_TIME_DRIFT_EXP 635 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FREQ_DELTA 636 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FINE_DELTA 637 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FREQ_ERROR 638 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_SYMB 639 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_OFFSET 640 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_DETECT 641 +#define SX1302_REG_RX_TOP_FREQ_TO_TIME4_FREQ_TO_TIME_INVERT_RNG 642 +#define SX1302_REG_RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF8 643 +#define SX1302_REG_RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF7 644 +#define SX1302_REG_RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF6 645 +#define SX1302_REG_RX_TOP_FREQ_TRACK_A_0_FREQ_TRACK_EN_SF5 646 +#define SX1302_REG_RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF12 647 +#define SX1302_REG_RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF11 648 +#define SX1302_REG_RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF10 649 +#define SX1302_REG_RX_TOP_FREQ_TRACK_A_1_FREQ_TRACK_EN_SF9 650 +#define SX1302_REG_RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF8 651 +#define SX1302_REG_RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF7 652 +#define SX1302_REG_RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF6 653 +#define SX1302_REG_RX_TOP_FREQ_TRACK_B_0_FREQ_TRACK_EN_SF5 654 +#define SX1302_REG_RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF12 655 +#define SX1302_REG_RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF11 656 +#define SX1302_REG_RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF10 657 +#define SX1302_REG_RX_TOP_FREQ_TRACK_B_1_FREQ_TRACK_EN_SF9 658 +#define SX1302_REG_RX_TOP_FREQ_TRACK2_FREQ_TRACK_FINE 659 +#define SX1302_REG_RX_TOP_FREQ_TRACK2_FREQ_TRACK_HDR_SKIP 660 +#define SX1302_REG_RX_TOP_FREQ_TRACK3_FREQ_SYNCH_GAIN 661 +#define SX1302_REG_RX_TOP_FREQ_TRACK3_FREQ_TRACK_AUTO_THR 662 +#define SX1302_REG_RX_TOP_FREQ_TRACK4_SNR_MIN_WINDOW 663 +#define SX1302_REG_RX_TOP_FREQ_TRACK4_GAIN_AUTO_SNR_MIN 664 +#define SX1302_REG_RX_TOP_FREQ_TRACK4_FREQ_SYNCH_THR 665 +#define SX1302_REG_RX_TOP_DETECT_MSP0_MSP_PNR 666 +#define SX1302_REG_RX_TOP_DETECT_MSP1_MSP2_PNR 667 +#define SX1302_REG_RX_TOP_DETECT_MSP2_MSP2_PEAK_NB 668 +#define SX1302_REG_RX_TOP_DETECT_MSP2_MSP_PEAK_NB 669 +#define SX1302_REG_RX_TOP_DETECT_MSP3_ACC_MIN2 670 +#define SX1302_REG_RX_TOP_DETECT_MSP3_ACC_WIN_LEN 671 +#define SX1302_REG_RX_TOP_DETECT_MSP3_MSP_POS_SEL 672 +#define SX1302_REG_RX_TOP_DETECT_MSP3_MSP_CNT_MODE 673 +#define SX1302_REG_RX_TOP_DETECT_ACC1_USE_GAIN_SYMB 674 +#define SX1302_REG_RX_TOP_DETECT_ACC1_ACC_PNR 675 +#define SX1302_REG_RX_TOP_DETECT_ACC2_NOISE_COEFF 676 +#define SX1302_REG_RX_TOP_DETECT_ACC2_ACC_COEFF 677 +#define SX1302_REG_RX_TOP_DETECT_ACC2_ACC_2_SAME_PEAKS 678 +#define SX1302_REG_RX_TOP_DETECT_ACC2_ACC_AUTO_RESCALE 679 +#define SX1302_REG_RX_TOP_DETECT_ACC2_ACC_PEAK_POS_SEL 680 +#define SX1302_REG_RX_TOP_DETECT_ACC2_ACC_PEAK_SUM_EN 681 +#define SX1302_REG_RX_TOP_DETECT_ACC3_MIN_SINGLE_PEAK 682 +#define SX1302_REG_RX_TOP_TIMESTAMP_SEL_SNR_MIN 683 +#define SX1302_REG_RX_TOP_TIMESTAMP_ENABLE 684 +#define SX1302_REG_RX_TOP_TIMESTAMP_NB_SYMB 685 +#define SX1302_REG_RX_TOP_MODEM_BUSY_MSB_RX_MODEM_BUSY 686 +#define SX1302_REG_RX_TOP_MODEM_BUSY_LSB_RX_MODEM_BUSY 687 +#define SX1302_REG_RX_TOP_MODEM_STATE_RX_MODEM_STS_SPARE 688 +#define SX1302_REG_RX_TOP_MODEM_STATE_RX_MODEM_STATE 689 +#define SX1302_REG_RX_TOP_MODEM_SYNC_DELTA_MSB_PEAK_POS_FINE_GAIN_H 690 +#define SX1302_REG_RX_TOP_MODEM_SYNC_DELTA_MSB_PEAK_POS_FINE_GAIN_L 691 +#define SX1302_REG_RX_TOP_MODEM_SYNC_DELTA_MSB_PEAK_POS_FINE_SIGN 692 +#define SX1302_REG_RX_TOP_MODEM_SYNC_DELTA_MSB_MODEM_SYNC_DELTA 693 +#define SX1302_REG_RX_TOP_MODEM_SYNC_DELTA_LSB_MODEM_SYNC_DELTA 694 +#define SX1302_REG_RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF8 695 +#define SX1302_REG_RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF7 696 +#define SX1302_REG_RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF6 697 +#define SX1302_REG_RX_TOP_MODEM_PPM_OFFSET1_PPM_OFFSET_SF5 698 +#define SX1302_REG_RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF12 699 +#define SX1302_REG_RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF11 700 +#define SX1302_REG_RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF10 701 +#define SX1302_REG_RX_TOP_MODEM_PPM_OFFSET2_PPM_OFFSET_SF9 702 +#define SX1302_REG_RX_TOP_MODEM_CLOCK_GATE_OVERRIDE_3_CLK_OVERRIDE 703 +#define SX1302_REG_RX_TOP_MODEM_CLOCK_GATE_OVERRIDE_2_CLK_OVERRIDE 704 +#define SX1302_REG_RX_TOP_MODEM_CLOCK_GATE_OVERRIDE_1_CLK_OVERRIDE 705 +#define SX1302_REG_RX_TOP_MODEM_CLOCK_GATE_OVERRIDE_0_CLK_OVERRIDE 706 +#define SX1302_REG_RX_TOP_DUMMY2_DUMMY2 707 +#define SX1302_REG_RX_TOP_RX_BUFFER_DEBUG_MODE 708 +#define SX1302_REG_RX_TOP_RX_BUFFER_DIRECT_RAM_IF 709 +#define SX1302_REG_RX_TOP_RX_BUFFER_LEGACY_TIMESTAMP 710 +#define SX1302_REG_RX_TOP_RX_BUFFER_STORE_HEADER_ERR_META 711 +#define SX1302_REG_RX_TOP_RX_BUFFER_STORE_SYNC_FAIL_META 712 +#define SX1302_REG_RX_TOP_RX_BUFFER_TIMESTAMP_CFG_MAX_TS_METRICS 713 +#define SX1302_REG_RX_TOP_RX_BUFFER_IRQ_CTRL_MSB_RX_BUFFER_IRQ_THRESHOLD 714 +#define SX1302_REG_RX_TOP_RX_BUFFER_IRQ_CTRL_LSB_RX_BUFFER_IRQ_THRESHOLD 715 +#define SX1302_REG_RX_TOP_RX_BUFFER_LAST_ADDR_READ_MSB_LAST_ADDR_READ 716 +#define SX1302_REG_RX_TOP_RX_BUFFER_LAST_ADDR_READ_LSB_LAST_ADDR_READ 717 +#define SX1302_REG_RX_TOP_RX_BUFFER_LAST_ADDR_WRITE_MSB_LAST_ADDR_WRITE 718 +#define SX1302_REG_RX_TOP_RX_BUFFER_LAST_ADDR_WRITE_LSB_LAST_ADDR_WRITE 719 +#define SX1302_REG_RX_TOP_RX_BUFFER_NB_BYTES_MSB_RX_BUFFER_NB_BYTES 720 +#define SX1302_REG_RX_TOP_RX_BUFFER_NB_BYTES_LSB_RX_BUFFER_NB_BYTES 721 +#define SX1302_REG_RX_TOP_MULTI_SF_SYNC_ERR_PKT_CNT_MULTI_SF_SYNC_ERR_PKTS 722 +#define SX1302_REG_RX_TOP_MULTI_SF_PLD_ERR_PKT_CNT_MULTI_SF_PLD_ERR_PKTS 723 +#define SX1302_REG_RX_TOP_MULTI_SF_GOOD_PKT_CNT_MULTI_SF_GOOD_PKTS 724 +#define SX1302_REG_RX_TOP_SERV_MODEM_SYNC_ERR_PKT_CNT_SERV_MODEM_SYNC_ERR_PKTS 725 +#define SX1302_REG_RX_TOP_SERV_MODEM_PLD_ERR_PKT_CNT_SERV_MODEM_PLD_ERR_PKTS 726 +#define SX1302_REG_RX_TOP_SERV_MODEM_GOOD_PKT_CNT_SERV_MODEM_GOOD_PKTS 727 +#define SX1302_REG_RX_TOP_GFSK_MODEM_SYNC_ERR_PKT_CNT_GFSK_MODEM_SYNC_ERR_PKTS 728 +#define SX1302_REG_RX_TOP_GFSK_MODEM_PLD_ERR_PKT_CNT_GFSK_MODEM_PLD_ERR_PKTS 729 +#define SX1302_REG_RX_TOP_GFSK_MODEM_GOOD_PKT_CNT_GFSK_MODEM_GOOD_PKTS 730 +#define SX1302_REG_RX_TOP_BAD_MODEM_ID_WRITE_0_BAD_MODEM_ID_WRITE 731 +#define SX1302_REG_RX_TOP_BAD_MODEM_ID_WRITE_1_BAD_MODEM_ID_WRITE 732 +#define SX1302_REG_RX_TOP_BAD_MODEM_ID_WRITE_2_BAD_MODEM_ID_WRITE 733 +#define SX1302_REG_RX_TOP_BAD_MODEM_ID_READ_0_BAD_MODEM_ID_READ 734 +#define SX1302_REG_RX_TOP_BAD_MODEM_ID_READ_1_BAD_MODEM_ID_READ 735 +#define SX1302_REG_RX_TOP_BAD_MODEM_ID_READ_2_BAD_MODEM_ID_READ 736 +#define SX1302_REG_RX_TOP_CLOCK_GATE_OVERRIDE_0_CLK_OVERRIDE 737 +#define SX1302_REG_RX_TOP_SAMPLE_4_MSPS_LATCHED_125K_SAMPLE_4_MSPS_LATCHED_125K 738 +#define SX1302_REG_RX_TOP_DUMMY3_DUMMY3 739 +#define SX1302_REG_ARB_MCU_CTRL_CLK_EN 740 +#define SX1302_REG_ARB_MCU_CTRL_RADIO_RST 741 +#define SX1302_REG_ARB_MCU_CTRL_FORCE_HOST_FE_CTRL 742 +#define SX1302_REG_ARB_MCU_CTRL_MCU_CLEAR 743 +#define SX1302_REG_ARB_MCU_CTRL_HOST_PROG 744 +#define SX1302_REG_ARB_MCU_CTRL_PARITY_ERROR 745 +#define SX1302_REG_ARB_MCU_MCU_ARB_STATUS_MCU_ARB_STATUS 746 +#define SX1302_REG_ARB_MCU_UART_CFG_MSBF 747 +#define SX1302_REG_ARB_MCU_UART_CFG_PAR_EN 748 +#define SX1302_REG_ARB_MCU_UART_CFG_PAR_MODE 749 +#define SX1302_REG_ARB_MCU_UART_CFG_START_LEN 750 +#define SX1302_REG_ARB_MCU_UART_CFG_STOP_LEN 751 +#define SX1302_REG_ARB_MCU_UART_CFG_WORD_LEN 752 +#define SX1302_REG_ARB_MCU_UART_CFG2_BIT_RATE 753 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_CFG_0_ARB_DEBUG_CFG_0 754 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_CFG_1_ARB_DEBUG_CFG_1 755 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_CFG_2_ARB_DEBUG_CFG_2 756 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_CFG_3_ARB_DEBUG_CFG_3 757 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_0_ARB_DEBUG_STS_0 758 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_1_ARB_DEBUG_STS_1 759 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_2_ARB_DEBUG_STS_2 760 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_3_ARB_DEBUG_STS_3 761 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_4_ARB_DEBUG_STS_4 762 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_5_ARB_DEBUG_STS_5 763 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_6_ARB_DEBUG_STS_6 764 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_7_ARB_DEBUG_STS_7 765 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_8_ARB_DEBUG_STS_8 766 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_9_ARB_DEBUG_STS_9 767 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_10_ARB_DEBUG_STS_10 768 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_11_ARB_DEBUG_STS_11 769 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_12_ARB_DEBUG_STS_12 770 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_13_ARB_DEBUG_STS_13 771 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_14_ARB_DEBUG_STS_14 772 +#define SX1302_REG_ARB_MCU_ARB_DEBUG_STS_15_ARB_DEBUG_STS_15 773 +#define SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_01_CHANNEL_1_OFFSET 774 +#define SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_01_CHANNEL_0_OFFSET 775 +#define SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_23_CHANNEL_3_OFFSET 776 +#define SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_23_CHANNEL_2_OFFSET 777 +#define SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_45_CHANNEL_5_OFFSET 778 +#define SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_45_CHANNEL_4_OFFSET 779 +#define SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_67_CHANNEL_7_OFFSET 780 +#define SX1302_REG_ARB_MCU_CHANNEL_SYNC_OFFSET_67_CHANNEL_6_OFFSET 781 +#define SX1302_REG_ARB_MCU_DUMMY_DUMMY3 782 +#define SX1302_REG_RADIO_FE_GLBL_CTRL_DECIM_B_CLR 783 +#define SX1302_REG_RADIO_FE_GLBL_CTRL_DECIM_A_CLR 784 +#define SX1302_REG_RADIO_FE_CTRL0_RADIO_A_DC_NOTCH_EN 785 +#define SX1302_REG_RADIO_FE_CTRL0_RADIO_A_FORCE_HOST_FILTER_GAIN 786 +#define SX1302_REG_RADIO_FE_CTRL0_RADIO_A_HOST_FILTER_GAIN 787 +#define SX1302_REG_RADIO_FE_RSSI_DB_DEF_RADIO_A_RSSI_DB_DEFAULT_VALUE 788 +#define SX1302_REG_RADIO_FE_RSSI_DEC_DEF_RADIO_A_RSSI_DEC_DEFAULT_VALUE 789 +#define SX1302_REG_RADIO_FE_RSSI_DEC_RD_RADIO_A_RSSI_DEC_OUT 790 +#define SX1302_REG_RADIO_FE_RSSI_BB_RD_RADIO_A_RSSI_BB_OUT 791 +#define SX1302_REG_RADIO_FE_DEC_FILTER_RD_RADIO_A_DEC_FILTER_GAIN 792 +#define SX1302_REG_RADIO_FE_RSSI_BB_FILTER_ALPHA_RADIO_A_RSSI_BB_FILTER_ALPHA 793 +#define SX1302_REG_RADIO_FE_RSSI_DEC_FILTER_ALPHA_RADIO_A_RSSI_DEC_FILTER_ALPHA 794 +#define SX1302_REG_RADIO_FE_IQ_COMP_AMP_COEFF_RADIO_A_AMP_COEFF 795 +#define SX1302_REG_RADIO_FE_IQ_COMP_PHI_COEFF_RADIO_A_PHI_COEFF 796 +#define SX1302_REG_RADIO_FE_RADIO_DIO_TEST_MODE_RADIO_A_DIO_TEST_MODE 797 +#define SX1302_REG_RADIO_FE_RADIO_DIO_TEST_DIR_RADIO_A_DIO_TEST_DIR 798 +#define SX1302_REG_RADIO_FE_RADIO_DIO_DIR_RADIO_A_DIO_DIR 799 +#define SX1302_REG_RADIO_FE_CTRL0_RADIO_B_DC_NOTCH_EN 800 +#define SX1302_REG_RADIO_FE_CTRL0_RADIO_B_FORCE_HOST_FILTER_GAIN 801 +#define SX1302_REG_RADIO_FE_CTRL0_RADIO_B_HOST_FILTER_GAIN 802 +#define SX1302_REG_RADIO_FE_RSSI_DB_DEF_RADIO_B_RSSI_DB_DEFAULT_VALUE 803 +#define SX1302_REG_RADIO_FE_RSSI_DEC_DEF_RADIO_B_RSSI_DEC_DEFAULT_VALUE 804 +#define SX1302_REG_RADIO_FE_RSSI_DEC_RD_RADIO_B_RSSI_DEC_OUT 805 +#define SX1302_REG_RADIO_FE_RSSI_BB_RD_RADIO_B_RSSI_BB_OUT 806 +#define SX1302_REG_RADIO_FE_DEC_FILTER_RD_RADIO_B_DEC_FILTER_GAIN 807 +#define SX1302_REG_RADIO_FE_RSSI_BB_FILTER_ALPHA_RADIO_B_RSSI_BB_FILTER_ALPHA 808 +#define SX1302_REG_RADIO_FE_RSSI_DEC_FILTER_ALPHA_RADIO_B_RSSI_DEC_FILTER_ALPHA 809 +#define SX1302_REG_RADIO_FE_IQ_COMP_AMP_COEFF_RADIO_B_AMP_COEFF 810 +#define SX1302_REG_RADIO_FE_IQ_COMP_PHI_COEFF_RADIO_B_PHI_COEFF 811 +#define SX1302_REG_RADIO_FE_RADIO_DIO_TEST_MODE_RADIO_B_DIO_TEST_MODE 812 +#define SX1302_REG_RADIO_FE_RADIO_DIO_TEST_DIR_RADIO_B_DIO_TEST_DIR 813 +#define SX1302_REG_RADIO_FE_RADIO_DIO_DIR_RADIO_B_DIO_DIR 814 +#define SX1302_REG_RADIO_FE_SIG_ANA_CFG_VALID 815 +#define SX1302_REG_RADIO_FE_SIG_ANA_CFG_BUSY 816 +#define SX1302_REG_RADIO_FE_SIG_ANA_CFG_DURATION 817 +#define SX1302_REG_RADIO_FE_SIG_ANA_CFG_FORCE_HAL_CTRL 818 +#define SX1302_REG_RADIO_FE_SIG_ANA_CFG_START 819 +#define SX1302_REG_RADIO_FE_SIG_ANA_CFG_RADIO_SEL 820 +#define SX1302_REG_RADIO_FE_SIG_ANA_CFG_EN 821 +#define SX1302_REG_RADIO_FE_SIG_ANA_FREQ_FREQ 822 +#define SX1302_REG_RADIO_FE_SIG_ANA_ABS_MSB_CORR_ABS_OUT 823 +#define SX1302_REG_RADIO_FE_SIG_ANA_ABS_LSB_CORR_ABS_OUT 824 +#define SX1302_REG_RADIO_FE_DUMMY_DUMMY 825 +#define SX1302_REG_OTP_BYTE_ADDR_ADDR 826 +#define SX1302_REG_OTP_RD_DATA_RD_DATA 827 +#define SX1302_REG_OTP_STATUS_CHECKSUM_STATUS 828 +#define SX1302_REG_OTP_STATUS_FSM_READY 829 +#define SX1302_REG_OTP_CFG_ACCESS_MODE 830 +#define SX1302_REG_OTP_BIT_POS_POS 831 +#define SX1302_REG_OTP_PIN_CTRL_0_TM 832 +#define SX1302_REG_OTP_PIN_CTRL_0_STROBE 833 +#define SX1302_REG_OTP_PIN_CTRL_0_PGENB 834 +#define SX1302_REG_OTP_PIN_CTRL_0_LOAD 835 +#define SX1302_REG_OTP_PIN_CTRL_0_CSB 836 +#define SX1302_REG_OTP_PIN_CTRL_1_FSCK 837 +#define SX1302_REG_OTP_PIN_CTRL_1_FSI 838 +#define SX1302_REG_OTP_PIN_CTRL_1_FRST 839 +#define SX1302_REG_OTP_PIN_STATUS_FSO 840 +#define SX1302_REG_OTP_MODEM_EN_0_MODEM_EN 841 +#define SX1302_REG_OTP_MODEM_EN_1_MODEM_EN 842 +#define SX1302_REG_OTP_MODEM_SF_EN_SF_EN 843 +#define SX1302_REG_OTP_TIMESTAMP_EN_TIMESTAMP_EN 844 +#define SX1302_REG_OTP_DUMMY_DUMMY 845 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_LORA_SERVICE_FREQ_MSB_IF_FREQ_0 846 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_LORA_SERVICE_FREQ_LSB_IF_FREQ_0 847 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_LORA_SERVICE_RADIO_SEL_RADIO_SELECT 848 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_BW_START 849 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_AUTO_BW_RED 850 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_NO_FAST_START 851 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_BYPASS 852 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG1_ENABLE 853 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG2_BW_LOCKED 854 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG2_BW 855 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG3_BW_RED 856 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DC_NOTCH_CFG4_IIR_DCC_TIME 857 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_0_FIR1_COEFF_0 858 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_1_FIR1_COEFF_1 859 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_2_FIR1_COEFF_2 860 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_3_FIR1_COEFF_3 861 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_4_FIR1_COEFF_4 862 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_5_FIR1_COEFF_5 863 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_6_FIR1_COEFF_6 864 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR1_7_FIR1_COEFF_7 865 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_0_FIR2_COEFF_0 866 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_1_FIR2_COEFF_1 867 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_2_FIR2_COEFF_2 868 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_3_FIR2_COEFF_3 869 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_4_FIR2_COEFF_4 870 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_5_FIR2_COEFF_5 871 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_6_FIR2_COEFF_6 872 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_FIR2_7_FIR2_COEFF_7 873 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC0_RADIO_GAIN_RED_SEL 874 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC0_RADIO_GAIN_RED_DB 875 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC1_DC_COMP_EN 876 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC1_FORCE_DEFAULT_FIR 877 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC1_RSSI_EARLY_LATCH 878 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC1_FREEZE_ON_SYNC 879 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC2_DAGC_IN_COMP 880 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC2_DAGC_FIR_HYST 881 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC2_RSSI_MAX_SAMPLE 882 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_AGC2_RSSI_MIN_SAMPLE 883 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_GAIN0_DAGC_FIR_FAST 884 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_GAIN0_FORCE_GAIN_FIR 885 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_GAIN0_GAIN_FIR1 886 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_DFE_GAIN0_GAIN_FIR2 887 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_TARGET_LVL 888 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_GAIN_INCR_STEP 889 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_GAIN_DROP_COMP 890 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_COMB_FILTER_EN 891 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_NO_FREEZE_START 892 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CFG_FREEZE_ON_SYNC 893 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CNT0_SAMPLE 894 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CNT1_THR_M6 895 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CNT2_THR_M12 896 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CNT3_THR_M18 897 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CNT4_GAIN 898 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DAGC_CNT4_FORCE_GAIN 899 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG0_MODEM_BW 900 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG0_MODEM_SF 901 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_PPM_OFFSET_HDR_CTRL 902 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_PPM_OFFSET 903 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_MODEM_EN 904 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG1_CODING_RATE 905 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_FINE_SYNCH_EN 906 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_MODEM_START 907 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_CADRXTX 908 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_IMPLICIT_HEADER 909 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG2_CRC_EN 910 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG3_PAYLOAD_LENGTH 911 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG4_INT_STEP_ORIDE_EN 912 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG4_INT_STEP_ORIDE 913 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG5_HEADER_DIFF_MODE 914 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG5_ZERO_PAD 915 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG6_PREAMBLE_SYMB_NB 916 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG7_PREAMBLE_SYMB_NB 917 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG8_AUTO_ACK_INT_DELAY 918 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG8_AUTO_ACK_RX 919 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG8_AUTO_ACK_TX 920 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TXRX_CFG8_POST_PREAMBLE_GAP_LONG 921 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG0_DFT_PEAK_EN 922 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG0_CHIRP_INVERT 923 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG0_SWAP_IQ 924 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG0_CONTINUOUS 925 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG1_DETECT_TIMEOUT 926 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG2_AUTO_ACK_RANGE 927 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG2_AUTO_ACK_DELAY 928 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG3_RESTART_ON_HDR_ERR 929 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG3_CLK_EN_RESYNC_DIN 930 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_RX_CFG3_LLR_SCALE 931 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH0_PEAK1_POS 932 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH1_PEAK2_POS 933 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_FINETIME_ON_LAST 934 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_AUTO_SCALE 935 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_DROP_ON_SYNCH 936 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_GAIN 937 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FRAME_SYNCH2_TIMEOUT_OPT 938 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_GAIN_P_HDR_RED 939 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_ROUNDING 940 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_POS_LIMIT 941 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_SUM_SIZE 942 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING0_MODE 943 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_AUTO 944 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_PAYLOAD 945 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING1_GAIN_P_PREAMB 946 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_EN 947 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_PAYLOAD 948 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING2_GAIN_I_PREAMB 949 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING3_FINESYNCH_SUM 950 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING3_FINESYNCH_GAIN 951 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING3_GAIN_I_AUTO 952 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING4_GAIN_I_AUTO_MAX 953 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FINE_TIMING4_GAIN_P_AUTO_MAX 954 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME0_FREQ_TO_TIME_DRIFT_MANT 955 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME1_FREQ_TO_TIME_DRIFT_MANT 956 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME2_FREQ_TO_TIME_DRIFT_EXP 957 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FREQ_DELTA 958 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FINE_DELTA 959 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_FREQ_ERROR 960 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_SYMB 961 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_TIME_OFFSET 962 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME3_FREQ_TO_TIME_INVERT_DETECT 963 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TO_TIME4_FREQ_TO_TIME_INVERT_RNG 964 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK0_FREQ_TRACK_FINE 965 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK0_FREQ_TRACK_HDR_SKIP 966 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK0_FREQ_TRACK_EN 967 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK1_FREQ_SYNCH_GAIN 968 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK1_FREQ_TRACK_AUTO_THR 969 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK2_SNR_MIN_WINDOW 970 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK2_GAIN_AUTO_SNR_MIN 971 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FREQ_TRACK2_FREQ_SYNCH_THR 972 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP0_MSP_PNR 973 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP1_MSP2_PNR 974 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP2_MSP2_PEAK_NB 975 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP2_MSP_PEAK_NB 976 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP3_ACC_MIN2 977 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP3_ACC_WIN_LEN 978 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP3_MSP_POS_SEL 979 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_MSP3_MSP_CNT_MODE 980 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_USE_GAIN_SYMB 981 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC1_ACC_PNR 982 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_NOISE_COEFF 983 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_COEFF 984 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_2_SAME_PEAKS 985 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_AUTO_RESCALE 986 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_PEAK_POS_SEL 987 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC2_ACC_PEAK_SUM_EN 988 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DETECT_ACC3_MIN_SINGLE_PEAK 989 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TIMESTAMP_SEL_SNR_MIN 990 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TIMESTAMP_ENABLE 991 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_TIMESTAMP_NB_SYMB 992 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_CLOCK_GATE_OVERRIDE_FSK_TRANSPOSE_CLK_OVERRIDE 993 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_CLOCK_GATE_OVERRIDE_FSK_MODEM_CLK_OVERRIDE 994 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_CLOCK_GATE_OVERRIDE_TRANSPOSE_CLK_OVERRIDE 995 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_CLOCK_GATE_OVERRIDE_MODEM_CLK_OVERRIDE 996 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DUMMY0_DUMMY0 997 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_FREQ_MSB_IF_FREQ_0 998 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_FREQ_LSB_IF_FREQ_0 999 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_CRC_IBM 1000 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_DCFREE_ENC 1001 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_CRC_EN 1002 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_0_PKT_MODE 1003 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_1_ADRS_COMP 1004 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_1_PSIZE 1005 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_1_CH_BW_EXPO 1006 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_MODEM_INVERT_IQ 1007 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_AUTO_AFC 1008 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_RADIO_SELECT 1009 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_3_RX_INVERT 1010 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_4_RSSI_LENGTH 1011 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_CFG_4_ERROR_OSR_TOL 1012 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_NODE_ADRS_NODE_ADRS 1013 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_BROADCAST_BROADCAST 1014 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_PKT_LENGTH_PKT_LENGTH 1015 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_TIMEOUT_MSB_TIMEOUT 1016 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_TIMEOUT_LSB_TIMEOUT 1017 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BIT_RATE_MSB_BIT_RATE 1018 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_BIT_RATE_LSB_BIT_RATE 1019 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN 1020 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN 1021 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN 1022 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN 1023 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN 1024 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN 1025 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN 1026 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN 1027 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_FSK_RSSI_FILTER_ALPHA_FSK_RSSI_FILTER_ALPHA 1028 +#define SX1302_REG_RX_TOP_LORA_SERVICE_FSK_DUMMY1_DUMMY1 1029 +#define SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_ENABLE 1030 +#define SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_CAPTUREWRAP 1031 +#define SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_CAPTUREFORCETRIGGER 1032 +#define SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_CAPTURESTART 1033 +#define SX1302_REG_CAPTURE_RAM_CAPTURE_CFG_RAMCONFIG 1034 +#define SX1302_REG_CAPTURE_RAM_CAPTURE_SOURCE_A_SOURCEMUX 1035 +#define SX1302_REG_CAPTURE_RAM_CAPTURE_SOURCE_B_SOURCEMUX 1036 +#define SX1302_REG_CAPTURE_RAM_CAPTURE_PERIOD_0_CAPTUREPERIOD 1037 +#define SX1302_REG_CAPTURE_RAM_CAPTURE_PERIOD_1_CAPTUREPERIOD 1038 +#define SX1302_REG_CAPTURE_RAM_STATUS_CAPCOMPLETE 1039 +#define SX1302_REG_CAPTURE_RAM_LAST_RAM_ADDR_0_LASTRAMADDR 1040 +#define SX1302_REG_CAPTURE_RAM_LAST_RAM_ADDR_1_LASTRAMADDR 1041 +#define SX1302_REG_CAPTURE_RAM_CLOCK_GATE_OVERRIDE_CLK_OVERRIDE 1042 +#define SX1302_REG_CAPTURE_RAM_DUMMY0_DUMMY0 1043 + +#define LGW_TOTALREGS 1044 + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC MACROS -------------------------------------------------------- */ + +#define SX1302_REG_TX_TOP_TX_TRIG_TX_FSM_CLR(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_TRIG_TX_FSM_CLR : \ + SX1302_REG_TX_TOP_B_TX_TRIG_TX_FSM_CLR) +#define SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_GPS(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_TRIG_TX_TRIG_GPS : \ + SX1302_REG_TX_TOP_B_TX_TRIG_TX_TRIG_GPS) +#define SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_DELAYED(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_TRIG_TX_TRIG_DELAYED : \ + SX1302_REG_TX_TOP_B_TX_TRIG_TX_TRIG_DELAYED) +#define SX1302_REG_TX_TOP_TX_TRIG_TX_TRIG_IMMEDIATE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_TRIG_TX_TRIG_IMMEDIATE : \ + SX1302_REG_TX_TOP_B_TX_TRIG_TX_TRIG_IMMEDIATE) +#define SX1302_REG_TX_TOP_TIMER_TRIG_BYTE3_TIMER_DELAYED_TRIG(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TIMER_TRIG_BYTE3_TIMER_DELAYED_TRIG : \ + SX1302_REG_TX_TOP_B_TIMER_TRIG_BYTE3_TIMER_DELAYED_TRIG) +#define SX1302_REG_TX_TOP_TIMER_TRIG_BYTE2_TIMER_DELAYED_TRIG(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TIMER_TRIG_BYTE2_TIMER_DELAYED_TRIG : \ + SX1302_REG_TX_TOP_B_TIMER_TRIG_BYTE2_TIMER_DELAYED_TRIG) +#define SX1302_REG_TX_TOP_TIMER_TRIG_BYTE1_TIMER_DELAYED_TRIG(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TIMER_TRIG_BYTE1_TIMER_DELAYED_TRIG : \ + SX1302_REG_TX_TOP_B_TIMER_TRIG_BYTE1_TIMER_DELAYED_TRIG) +#define SX1302_REG_TX_TOP_TIMER_TRIG_BYTE0_TIMER_DELAYED_TRIG(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TIMER_TRIG_BYTE0_TIMER_DELAYED_TRIG : \ + SX1302_REG_TX_TOP_B_TIMER_TRIG_BYTE0_TIMER_DELAYED_TRIG) +#define SX1302_REG_TX_TOP_TX_START_DELAY_MSB_TX_START_DELAY(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_START_DELAY_MSB_TX_START_DELAY : \ + SX1302_REG_TX_TOP_B_TX_START_DELAY_MSB_TX_START_DELAY) +#define SX1302_REG_TX_TOP_TX_START_DELAY_LSB_TX_START_DELAY(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_START_DELAY_LSB_TX_START_DELAY : \ + SX1302_REG_TX_TOP_B_TX_START_DELAY_LSB_TX_START_DELAY) +#define SX1302_REG_TX_TOP_TX_CTRL_WRITE_BUFFER(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CTRL_WRITE_BUFFER : \ + SX1302_REG_TX_TOP_B_TX_CTRL_WRITE_BUFFER) +#define SX1302_REG_TX_TOP_TX_RAMP_DURATION_TX_RAMP_DURATION(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RAMP_DURATION_TX_RAMP_DURATION : \ + SX1302_REG_TX_TOP_B_TX_RAMP_DURATION_TX_RAMP_DURATION) +#define SX1302_REG_TX_TOP_GEN_CFG_0_MODULATION_TYPE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_GEN_CFG_0_MODULATION_TYPE : \ + SX1302_REG_TX_TOP_B_GEN_CFG_0_MODULATION_TYPE) +#define SX1302_REG_TX_TOP_TEST_0_TX_ACTIVE_CTRL(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TEST_0_TX_ACTIVE_CTRL : \ + SX1302_REG_TX_TOP_B_TEST_0_TX_ACTIVE_CTRL) +#define SX1302_REG_TX_TOP_TEST_0_TX_ACTIVE_SEL(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TEST_0_TX_ACTIVE_SEL : \ + SX1302_REG_TX_TOP_B_TEST_0_TX_ACTIVE_SEL) +#define SX1302_REG_TX_TOP_TX_FLAG_TX_TIMEOUT(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_FLAG_TX_TIMEOUT : \ + SX1302_REG_TX_TOP_B_TX_FLAG_TX_TIMEOUT) +#define SX1302_REG_TX_TOP_TX_FLAG_PKT_DONE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_FLAG_PKT_DONE : \ + SX1302_REG_TX_TOP_B_TX_FLAG_PKT_DONE) +#define SX1302_REG_TX_TOP_AGC_TX_BW_AGC_TX_BW(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_AGC_TX_BW_AGC_TX_BW : \ + SX1302_REG_TX_TOP_B_AGC_TX_BW_AGC_TX_BW) +#define SX1302_REG_TX_TOP_AGC_TX_PWR_AGC_TX_PWR(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_AGC_TX_PWR_AGC_TX_PWR : \ + SX1302_REG_TX_TOP_B_AGC_TX_PWR_AGC_TX_PWR) +#define SX1302_REG_TX_TOP_TIMEOUT_CNT_BYTE_2_TIMEOUT_CNT(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TIMEOUT_CNT_BYTE_2_TIMEOUT_CNT : \ + SX1302_REG_TX_TOP_B_TIMEOUT_CNT_BYTE_2_TIMEOUT_CNT) +#define SX1302_REG_TX_TOP_TIMEOUT_CNT_BYTE_1_TIMEOUT_CNT(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TIMEOUT_CNT_BYTE_1_TIMEOUT_CNT : \ + SX1302_REG_TX_TOP_B_TIMEOUT_CNT_BYTE_1_TIMEOUT_CNT) +#define SX1302_REG_TX_TOP_TIMEOUT_CNT_BYTE_0_TIMEOUT_CNT(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TIMEOUT_CNT_BYTE_0_TIMEOUT_CNT : \ + SX1302_REG_TX_TOP_B_TIMEOUT_CNT_BYTE_0_TIMEOUT_CNT) +#define SX1302_REG_TX_TOP_TX_FSM_STATUS_TX_STATUS(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_FSM_STATUS_TX_STATUS : \ + SX1302_REG_TX_TOP_B_TX_FSM_STATUS_TX_STATUS) +#define SX1302_REG_TX_TOP_DUMMY_CONTROL_DUMMY(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_DUMMY_CONTROL_DUMMY : \ + SX1302_REG_TX_TOP_B_DUMMY_CONTROL_DUMMY) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL_PLL_DIV_CTRL(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_PLL_DIV_CTRL : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_PLL_DIV_CTRL) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL_TX_CLK_EDGE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_CLK_EDGE : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_CLK_EDGE) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL_TX_MODE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_MODE : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_MODE) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL_TX_IF_DST(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_IF_DST : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_IF_DST) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL_TX_IF_SRC(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL_TX_IF_SRC : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL_TX_IF_SRC) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL2_SX125X_IQ_INVERT(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL2_SX125X_IQ_INVERT : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL2_SX125X_IQ_INVERT) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_CTRL2_PLL_DIV_CTRL_AGC(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_CTRL2_PLL_DIV_CTRL_AGC : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_CTRL2_PLL_DIV_CTRL_AGC) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_IQ_GAIN_IQ_GAIN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_IQ_GAIN_IQ_GAIN : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_IQ_GAIN_IQ_GAIN) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_I_OFFSET_I_OFFSET(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_I_OFFSET_I_OFFSET : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_I_OFFSET_I_OFFSET) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_Q_OFFSET_Q_OFFSET(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_Q_OFFSET_Q_OFFSET : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_Q_OFFSET_Q_OFFSET) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_RF_H_FREQ_RF(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_RF_H_FREQ_RF : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_RF_H_FREQ_RF) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_RF_M_FREQ_RF(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_RF_M_FREQ_RF : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_RF_M_FREQ_RF) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_RF_L_FREQ_RF(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_RF_L_FREQ_RF : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_RF_L_FREQ_RF) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_DEV_H_FREQ_DEV) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_FREQ_DEV_L_FREQ_DEV) +#define SX1302_REG_TX_TOP_TX_RFFE_IF_TEST_MOD_FREQ(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_RFFE_IF_TEST_MOD_FREQ : \ + SX1302_REG_TX_TOP_B_TX_RFFE_IF_TEST_MOD_FREQ) +#define SX1302_REG_TX_TOP_DUMMY_MODULATOR_DUMMY(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_DUMMY_MODULATOR_DUMMY : \ + SX1302_REG_TX_TOP_B_DUMMY_MODULATOR_DUMMY) +#define SX1302_REG_TX_TOP_FSK_PKT_LEN_PKT_LENGTH(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_PKT_LEN_PKT_LENGTH : \ + SX1302_REG_TX_TOP_B_FSK_PKT_LEN_PKT_LENGTH) +#define SX1302_REG_TX_TOP_FSK_CFG_0_TX_CONT(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_CFG_0_TX_CONT : \ + SX1302_REG_TX_TOP_B_FSK_CFG_0_TX_CONT) +#define SX1302_REG_TX_TOP_FSK_CFG_0_CRC_IBM(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_CFG_0_CRC_IBM : \ + SX1302_REG_TX_TOP_B_FSK_CFG_0_CRC_IBM) +#define SX1302_REG_TX_TOP_FSK_CFG_0_DCFREE_ENC(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_CFG_0_DCFREE_ENC : \ + SX1302_REG_TX_TOP_B_FSK_CFG_0_DCFREE_ENC) +#define SX1302_REG_TX_TOP_FSK_CFG_0_CRC_EN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_CFG_0_CRC_EN : \ + SX1302_REG_TX_TOP_B_FSK_CFG_0_CRC_EN) +#define SX1302_REG_TX_TOP_FSK_CFG_0_PKT_MODE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_CFG_0_PKT_MODE : \ + SX1302_REG_TX_TOP_B_FSK_CFG_0_PKT_MODE) +#define SX1302_REG_TX_TOP_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE : \ + SX1302_REG_TX_TOP_B_FSK_PREAMBLE_SIZE_MSB_PREAMBLE_SIZE) +#define SX1302_REG_TX_TOP_FSK_PREAMBLE_SIZE_LSB_PREAMBLE_SIZE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_PREAMBLE_SIZE_LSB_PREAMBLE_SIZE : \ + SX1302_REG_TX_TOP_B_FSK_PREAMBLE_SIZE_LSB_PREAMBLE_SIZE) +#define SX1302_REG_TX_TOP_FSK_BIT_RATE_MSB_BIT_RATE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_BIT_RATE_MSB_BIT_RATE : \ + SX1302_REG_TX_TOP_B_FSK_BIT_RATE_MSB_BIT_RATE) +#define SX1302_REG_TX_TOP_FSK_BIT_RATE_LSB_BIT_RATE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_BIT_RATE_LSB_BIT_RATE : \ + SX1302_REG_TX_TOP_B_FSK_BIT_RATE_LSB_BIT_RATE) +#define SX1302_REG_TX_TOP_FSK_MOD_FSK_REF_PATTERN_SIZE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_MOD_FSK_REF_PATTERN_SIZE : \ + SX1302_REG_TX_TOP_B_FSK_MOD_FSK_REF_PATTERN_SIZE) +#define SX1302_REG_TX_TOP_FSK_MOD_FSK_PREAMBLE_SEQ(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_MOD_FSK_PREAMBLE_SEQ : \ + SX1302_REG_TX_TOP_B_FSK_MOD_FSK_PREAMBLE_SEQ) +#define SX1302_REG_TX_TOP_FSK_MOD_FSK_REF_PATTERN_EN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_MOD_FSK_REF_PATTERN_EN : \ + SX1302_REG_TX_TOP_B_FSK_MOD_FSK_REF_PATTERN_EN) +#define SX1302_REG_TX_TOP_FSK_MOD_FSK_GAUSSIAN_SELECT_BT(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_MOD_FSK_GAUSSIAN_SELECT_BT : \ + SX1302_REG_TX_TOP_B_FSK_MOD_FSK_GAUSSIAN_SELECT_BT) +#define SX1302_REG_TX_TOP_FSK_MOD_FSK_GAUSSIAN_EN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_MOD_FSK_GAUSSIAN_EN : \ + SX1302_REG_TX_TOP_B_FSK_MOD_FSK_GAUSSIAN_EN) +#define SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN : \ + SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE7_FSK_REF_PATTERN) +#define SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN : \ + SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE6_FSK_REF_PATTERN) +#define SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN : \ + SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE5_FSK_REF_PATTERN) +#define SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN : \ + SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE4_FSK_REF_PATTERN) +#define SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN : \ + SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE3_FSK_REF_PATTERN) +#define SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN : \ + SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE2_FSK_REF_PATTERN) +#define SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN : \ + SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE1_FSK_REF_PATTERN) +#define SX1302_REG_TX_TOP_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN : \ + SX1302_REG_TX_TOP_B_FSK_REF_PATTERN_BYTE0_FSK_REF_PATTERN) +#define SX1302_REG_TX_TOP_DUMMY_GSFK_DUMMY(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_DUMMY_GSFK_DUMMY : \ + SX1302_REG_TX_TOP_B_DUMMY_GSFK_DUMMY) +#define SX1302_REG_TX_TOP_TXRX_CFG0_0_MODEM_BW(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_0_MODEM_BW : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_0_MODEM_BW) +#define SX1302_REG_TX_TOP_TXRX_CFG0_0_MODEM_SF(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_0_MODEM_SF : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_0_MODEM_SF) +#define SX1302_REG_TX_TOP_TXRX_CFG0_1_PPM_OFFSET_HDR_CTRL(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_1_PPM_OFFSET_HDR_CTRL : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_1_PPM_OFFSET_HDR_CTRL) +#define SX1302_REG_TX_TOP_TXRX_CFG0_1_PPM_OFFSET(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_1_PPM_OFFSET : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_1_PPM_OFFSET) +#define SX1302_REG_TX_TOP_TXRX_CFG0_1_POST_PREAMBLE_GAP_LONG(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_1_POST_PREAMBLE_GAP_LONG : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_1_POST_PREAMBLE_GAP_LONG) +#define SX1302_REG_TX_TOP_TXRX_CFG0_1_CODING_RATE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_1_CODING_RATE : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_1_CODING_RATE) +#define SX1302_REG_TX_TOP_TXRX_CFG0_2_FINE_SYNCH_EN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_2_FINE_SYNCH_EN : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_2_FINE_SYNCH_EN) +#define SX1302_REG_TX_TOP_TXRX_CFG0_2_MODEM_EN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_2_MODEM_EN : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_2_MODEM_EN) +#define SX1302_REG_TX_TOP_TXRX_CFG0_2_CADRXTX(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_2_CADRXTX : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_2_CADRXTX) +#define SX1302_REG_TX_TOP_TXRX_CFG0_2_IMPLICIT_HEADER(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_2_IMPLICIT_HEADER : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_2_IMPLICIT_HEADER) +#define SX1302_REG_TX_TOP_TXRX_CFG0_2_CRC_EN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_2_CRC_EN : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_2_CRC_EN) +#define SX1302_REG_TX_TOP_TXRX_CFG0_3_PAYLOAD_LENGTH(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG0_3_PAYLOAD_LENGTH : \ + SX1302_REG_TX_TOP_B_TXRX_CFG0_3_PAYLOAD_LENGTH) +#define SX1302_REG_TX_TOP_TXRX_CFG1_0_INT_STEP_ORIDE_EN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_0_INT_STEP_ORIDE_EN : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_0_INT_STEP_ORIDE_EN) +#define SX1302_REG_TX_TOP_TXRX_CFG1_0_INT_STEP_ORIDE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_0_INT_STEP_ORIDE : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_0_INT_STEP_ORIDE) +#define SX1302_REG_TX_TOP_TXRX_CFG1_1_MODEM_START(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_1_MODEM_START : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_1_MODEM_START) +#define SX1302_REG_TX_TOP_TXRX_CFG1_1_HEADER_DIFF_MODE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_1_HEADER_DIFF_MODE : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_1_HEADER_DIFF_MODE) +#define SX1302_REG_TX_TOP_TXRX_CFG1_1_ZERO_PAD(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_1_ZERO_PAD : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_1_ZERO_PAD) +#define SX1302_REG_TX_TOP_TXRX_CFG1_2_PREAMBLE_SYMB_NB(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_2_PREAMBLE_SYMB_NB : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_2_PREAMBLE_SYMB_NB) +#define SX1302_REG_TX_TOP_TXRX_CFG1_3_PREAMBLE_SYMB_NB(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_3_PREAMBLE_SYMB_NB : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_3_PREAMBLE_SYMB_NB) +#define SX1302_REG_TX_TOP_TXRX_CFG1_4_AUTO_ACK_INT_DELAY(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_4_AUTO_ACK_INT_DELAY : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_4_AUTO_ACK_INT_DELAY) +#define SX1302_REG_TX_TOP_TXRX_CFG1_4_AUTO_ACK_RX(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_4_AUTO_ACK_RX : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_4_AUTO_ACK_RX) +#define SX1302_REG_TX_TOP_TXRX_CFG1_4_AUTO_ACK_TX(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TXRX_CFG1_4_AUTO_ACK_TX : \ + SX1302_REG_TX_TOP_B_TXRX_CFG1_4_AUTO_ACK_TX) +#define SX1302_REG_TX_TOP_TX_CFG0_0_CHIRP_LOWPASS(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CFG0_0_CHIRP_LOWPASS : \ + SX1302_REG_TX_TOP_B_TX_CFG0_0_CHIRP_LOWPASS) +#define SX1302_REG_TX_TOP_TX_CFG0_0_PPM_OFFSET_SIG(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CFG0_0_PPM_OFFSET_SIG : \ + SX1302_REG_TX_TOP_B_TX_CFG0_0_PPM_OFFSET_SIG) +#define SX1302_REG_TX_TOP_TX_CFG0_0_CONTCHIRP(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CFG0_0_CONTCHIRP : \ + SX1302_REG_TX_TOP_B_TX_CFG0_0_CONTCHIRP) +#define SX1302_REG_TX_TOP_TX_CFG0_0_CHIRP_INVERT(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CFG0_0_CHIRP_INVERT : \ + SX1302_REG_TX_TOP_B_TX_CFG0_0_CHIRP_INVERT) +#define SX1302_REG_TX_TOP_TX_CFG0_0_CONTINUOUS(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CFG0_0_CONTINUOUS : \ + SX1302_REG_TX_TOP_B_TX_CFG0_0_CONTINUOUS) +#define SX1302_REG_TX_TOP_TX_CFG0_1_POWER_RANGING(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CFG0_1_POWER_RANGING : \ + SX1302_REG_TX_TOP_B_TX_CFG0_1_POWER_RANGING) +#define SX1302_REG_TX_TOP_TX_CFG1_0_FRAME_NB(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CFG1_0_FRAME_NB : \ + SX1302_REG_TX_TOP_B_TX_CFG1_0_FRAME_NB) +#define SX1302_REG_TX_TOP_TX_CFG1_1_HOP_CTRL(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CFG1_1_HOP_CTRL : \ + SX1302_REG_TX_TOP_B_TX_CFG1_1_HOP_CTRL) +#define SX1302_REG_TX_TOP_TX_CFG1_1_IFS(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_TX_CFG1_1_IFS : \ + SX1302_REG_TX_TOP_B_TX_CFG1_1_IFS) +#define SX1302_REG_TX_TOP_FRAME_SYNCH_0_AUTO_SCALE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FRAME_SYNCH_0_AUTO_SCALE : \ + SX1302_REG_TX_TOP_B_FRAME_SYNCH_0_AUTO_SCALE) +#define SX1302_REG_TX_TOP_FRAME_SYNCH_0_DROP_ON_SYNCH(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FRAME_SYNCH_0_DROP_ON_SYNCH : \ + SX1302_REG_TX_TOP_B_FRAME_SYNCH_0_DROP_ON_SYNCH) +#define SX1302_REG_TX_TOP_FRAME_SYNCH_0_GAIN(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FRAME_SYNCH_0_GAIN : \ + SX1302_REG_TX_TOP_B_FRAME_SYNCH_0_GAIN) +#define SX1302_REG_TX_TOP_FRAME_SYNCH_0_PEAK1_POS(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FRAME_SYNCH_0_PEAK1_POS : \ + SX1302_REG_TX_TOP_B_FRAME_SYNCH_0_PEAK1_POS) +#define SX1302_REG_TX_TOP_FRAME_SYNCH_1_FINETIME_ON_LAST(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FRAME_SYNCH_1_FINETIME_ON_LAST : \ + SX1302_REG_TX_TOP_B_FRAME_SYNCH_1_FINETIME_ON_LAST) +#define SX1302_REG_TX_TOP_FRAME_SYNCH_1_TIMEOUT_OPT(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FRAME_SYNCH_1_TIMEOUT_OPT : \ + SX1302_REG_TX_TOP_B_FRAME_SYNCH_1_TIMEOUT_OPT) +#define SX1302_REG_TX_TOP_FRAME_SYNCH_1_PEAK2_POS(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_FRAME_SYNCH_1_PEAK2_POS : \ + SX1302_REG_TX_TOP_B_FRAME_SYNCH_1_PEAK2_POS) +#define SX1302_REG_TX_TOP_LORA_TX_STATE_STATUS(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_LORA_TX_STATE_STATUS : \ + SX1302_REG_TX_TOP_B_LORA_TX_STATE_STATUS) +#define SX1302_REG_TX_TOP_LORA_TX_FLAG_FRAME_DONE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_LORA_TX_FLAG_FRAME_DONE : \ + SX1302_REG_TX_TOP_B_LORA_TX_FLAG_FRAME_DONE) +#define SX1302_REG_TX_TOP_LORA_TX_FLAG_CONT_DONE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_LORA_TX_FLAG_CONT_DONE : \ + SX1302_REG_TX_TOP_B_LORA_TX_FLAG_CONT_DONE) +#define SX1302_REG_TX_TOP_LORA_TX_FLAG_PLD_DONE(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_LORA_TX_FLAG_PLD_DONE : \ + SX1302_REG_TX_TOP_B_LORA_TX_FLAG_PLD_DONE) +#define SX1302_REG_TX_TOP_DUMMY_LORA_DUMMY(rf_chain) ((rf_chain == 0) ? \ + SX1302_REG_TX_TOP_A_DUMMY_LORA_DUMMY : \ + SX1302_REG_TX_TOP_B_DUMMY_LORA_DUMMY) +#define DEBUG_REG 1 + + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +#if DEBUG_REG == 1 + #define DEBUG_MSG(str) fprintf(stderr, str) + #define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args) + #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_REG_ERROR;} +#else + #define DEBUG_MSG(str) + #define DEBUG_PRINTF(fmt, args...) + #define CHECK_NULL(a) if(a==NULL){return LGW_REG_ERROR;} +#endif + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */ +#ifdef __cplusplus +extern "C" +{ +#endif + + + +/** +@brief Connect LoRa concentrator by opening SPI link +@param spidev_path path to the SPI device to be used to connect to the SX1302 +@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR) +*/ +int lgw_connect(const char *spidev_path); + +/** +@brief Disconnect LoRa concentrator by closing SPI link +@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR) +*/ +int lgw_disconnect(void); + +/** +@brief LoRa concentrator register write +@param register_id register number in the data structure describing registers +@param reg_value signed value to write to the register (for u32, use cast) +@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR) +*/ +int lgw_reg_w(uint16_t register_id, int32_t reg_value); + +/** +@brief LoRa concentrator register read +@param register_id register number in the data structure describing registers +@param reg_value pointer to a variable where to write register read value +@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR) +*/ +int lgw_reg_r(uint16_t register_id, int32_t *reg_value); + +/** +@brief LoRa concentrator register burst write +@param register_id register number in the data structure describing registers +@param data pointer to byte array that will be sent to the LoRa concentrator +@param size size of the transfer, in byte(s) +@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR) +*/ +int lgw_reg_wb(uint16_t register_id, uint8_t *data, uint16_t size); + +/** +@brief LoRa concentrator register burst read +@param register_id register number in the data structure describing registers +@param data pointer to byte array that will be written from the LoRa concentrator +@param size size of the transfer, in byte(s) +@return status of register operation (LGW_REG_SUCCESS/LGW_REG_ERROR) +*/ +int lgw_reg_rb(uint16_t register_id, uint8_t *data, uint16_t size); + +/** +TODO +*/ +int lgw_mem_wb(uint16_t mem_addr, const uint8_t *data, uint16_t size); + +/** +TODO +*/ +int lgw_mem_rb(uint16_t mem_addr, uint8_t *data, uint16_t size, bool fifo_mode); + +#ifdef __cplusplus +} +#endif + +#endif + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_spi.h b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_spi.h new file mode 100644 index 0000000..6a99644 --- /dev/null +++ b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/loragw_spi.h @@ -0,0 +1,108 @@ +/* + / _____) _ | | +( (____ _____ ____ _| |_ _____ ____| |__ + \____ \| ___ | (_ _) ___ |/ ___) _ \ + _____) ) ____| | | || |_| ____( (___| | | | +(______/|_____)_|_|_| \__)_____)\____)_| |_| + (C)2019 Semtech + +Description: + Host specific functions to address the LoRa concentrator registers through + a SPI interface. + Single-byte read/write and burst read/write. + Could be used with multiple SPI ports in parallel (explicit file descriptor) + +License: Revised BSD License, see LICENSE.TXT file include in the project +*/ + + +#ifndef _LORAGW_SPI_H +#define _LORAGW_SPI_H + +/* -------------------------------------------------------------------------- */ +/* --- DEPENDANCIES --------------------------------------------------------- */ + +#include /* C99 types*/ + +#include "config.h" /* library configuration options (dynamically generated) */ + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC CONSTANTS ----------------------------------------------------- */ + +#define LGW_SPI_SUCCESS 0 +#define LGW_SPI_ERROR -1 +#define LGW_BURST_CHUNK 1024 + +#define SPI_SPEED 2000000 + +#define LGW_SPI_MUX_TARGET_SX1302 0x00 +#define LGW_SPI_MUX_TARGET_RADIOA 0x01 +#define LGW_SPI_MUX_TARGET_RADIOB 0x02 + +/* -------------------------------------------------------------------------- */ +/* --- PUBLIC FUNCTIONS PROTOTYPES ------------------------------------------ */ +#ifdef __cplusplus +extern "C" +{ +#endif +/** +@brief LoRa concentrator SPI setup (configure I/O and peripherals) +@param spidev_path path to the SPI device to be used to connect to the SX1302 +@param spi_target_ptr pointer on a generic pointer to SPI target (implementation dependant) +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ + +int lgw_spi_open(const char * spidev_path, void **spi_target_ptr); + +/** +@brief LoRa concentrator SPI close +@param spi_target generic pointer to SPI target (implementation dependant) +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ + +int lgw_spi_close(void *spi_target); + +/** +@brief LoRa concentrator SPI single-byte write +@param spi_target generic pointer to SPI target (implementation dependant) +@param address 7-bit register address +@param data data byte to write +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ +int lgw_spi_w(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t data); + +/** +@brief LoRa concentrator SPI single-byte read +@param spi_target generic pointer to SPI target (implementation dependant) +@param address 7-bit register address +@param data data byte to write +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ +int lgw_spi_r(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t *data); + +/** +@brief LoRa concentrator SPI burst (multiple-byte) write +@param spi_target generic pointer to SPI target (implementation dependant) +@param address 7-bit register address +@param data pointer to byte array that will be sent to the LoRa concentrator +@param size size of the transfer, in byte(s) +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ +int lgw_spi_wb(void *spi_target, uint8_t spi_mux_target, uint16_t address, const uint8_t *data, uint16_t size); + +/** +@brief LoRa concentrator SPI burst (multiple-byte) read +@param spi_target generic pointer to SPI target (implementation dependant) +@param address 7-bit register address +@param data pointer to byte array that will be written from the LoRa concentrator +@param size size of the transfer, in byte(s) +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ +int lgw_spi_rb(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t *data, uint16_t size); + +#ifdef __cplusplus +} +#endif +#endif + +/* --- EOF ------------------------------------------------------------------ */ diff --git a/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/spi.cpp b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/spi.cpp new file mode 100644 index 0000000..e544f22 --- /dev/null +++ b/examples/T-ETH-ELite-Shield/T-ETH-Elite-Gateway-Shield/spi.cpp @@ -0,0 +1,251 @@ + +#include +#include +#include "loragw_spi.h" +#include "loragw_reg.h" + +#define RADIO_CS_PIN 41 +#define SPI_MISO_PIN 9 +#define SPI_MOSI_PIN 11 +#define SPI_SCLK_PIN 10 +#define RADIO_RST_PIN 2 + +#define READ_ACCESS 0x00 +#define WRITE_ACCESS 0x80 +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + + + +/** +@brief LoRa concentrator SPI setup (configure I/O and peripherals) +@param spidev_path path to the SPI device to be used to connect to the SX1302 +@param spi_target_ptr pointer on a generic pointer to SPI target (implementation dependant) +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ + +int lgw_spi_open(const char *spidev_path, void **spi_target_ptr) +{ + pinMode(RADIO_RST_PIN, OUTPUT); + + digitalWrite(RADIO_RST_PIN, HIGH); delay(100); + + digitalWrite(RADIO_RST_PIN, LOW); delay(100); + + // Using SPI requires an explicit call + SPI.begin(SPI_SCLK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN); + + pinMode(RADIO_CS_PIN, OUTPUT); + + *spi_target_ptr = &SPI; + + return LGW_SPI_SUCCESS; +} + + +/** +@brief LoRa concentrator SPI close +@param spi_target generic pointer to SPI target (implementation dependant) +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ + +int lgw_spi_close(void *spi_target) +{ + return LGW_SPI_SUCCESS; +} + +/** +@brief LoRa concentrator SPI single-byte write +@param spi_target generic pointer to SPI target (implementation dependant) +@param address 7-bit register address +@param data data byte to write +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ +int lgw_spi_w(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t data) +{ + // printf("lgw_spi_w -> spi_mux_target: %u address: %X data[0]: %X size: %u\n", spi_mux_target, address, data); + + uint8_t out_buf[4]; + uint8_t command_size; + + /* prepare frame to be sent */ + out_buf[0] = spi_mux_target; + out_buf[1] = WRITE_ACCESS | ((address >> 8) & 0x7F); + out_buf[2] = ((address >> 0) & 0xFF); + out_buf[3] = data; + command_size = 4; + + digitalWrite(RADIO_CS_PIN, LOW); + SPI.beginTransaction( SPISettings(8E6, MSBFIRST, SPI_MODE0)); + SPI.transfer(out_buf, command_size); + SPI.endTransaction(); + digitalWrite(RADIO_CS_PIN, HIGH); + + return LGW_SPI_SUCCESS; +} + + +/** +@brief LoRa concentrator SPI single-byte read +@param spi_target generic pointer to SPI target (implementation dependant) +@param address 7-bit register address +@param data data byte to write +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ +int lgw_spi_r(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t *data) +{ + uint8_t out_buf[5]; + uint8_t command_size; + uint8_t in_buf[ARRAY_SIZE(out_buf)]; + + /* prepare frame to be sent */ + out_buf[0] = spi_mux_target; + out_buf[1] = READ_ACCESS | ((address >> 8) & 0x7F); + out_buf[2] = ((address >> 0) & 0xFF); + out_buf[3] = 0x00; + out_buf[4] = 0x00; + command_size = 5; + + SPI.beginTransaction( SPISettings()); + digitalWrite(RADIO_CS_PIN, LOW); + SPI.transfer(out_buf, command_size); + SPI.endTransaction(); + digitalWrite(RADIO_CS_PIN, HIGH); + *data = out_buf[command_size - 1]; + + + // printf("lgw_spi_r -> spi_mux_target: %u address: %X data[0]: %X size: %u\n", spi_mux_target, address, data[0]); + + return LGW_SPI_SUCCESS; +} + + +/** +@brief LoRa concentrator SPI burst (multiple-byte) write +@param spi_target generic pointer to SPI target (implementation dependant) +@param address 7-bit register address +@param data pointer to byte array that will be sent to the LoRa concentrator +@param size size of the transfer, in byte(s) +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ +int lgw_spi_wb(void *spi_target, uint8_t spi_mux_target, uint16_t address, const uint8_t *data, uint16_t size) +{ + + // printf("lgw_spi_wb -> spi_mux_target: %u address: %X data[0]: %X size: %u\n", spi_mux_target, address, data[0], size); + + int spi_device; + uint8_t command[3]; + uint8_t command_size; + // struct spi_ioc_transfer k[2]; + int size_to_do, chunk_size, offset; + int byte_transferred = 0; + int i; + + // /* check input parameters */ + CHECK_NULL(data); + if (size == 0) { + DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n"); + return LGW_SPI_ERROR; + } + + // //spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */ + + // /* prepare command byte */ + command[0] = spi_mux_target; + command[1] = WRITE_ACCESS | ((address >> 8) & 0x7F); + command[2] = ((address >> 0) & 0xFF); + command_size = 3; + size_to_do = size; + + // /* I/O transaction */ + // memset(&k, 0, sizeof(k)); /* clear k */ + // k[0].tx_buf = (unsigned long) &command[0]; + // k[0].len = command_size; + // k[0].cs_change = 0; + // k[1].cs_change = 0; + + for (i = 0; size_to_do > 0; ++i) { + chunk_size = (size_to_do < LGW_BURST_CHUNK) ? size_to_do : LGW_BURST_CHUNK; + offset = i * LGW_BURST_CHUNK; + // k[1].tx_buf = (unsigned long)(data + offset); + // k[1].len = chunk_size; + // byte_transferred += (ioctl(spi_device, SPI_IOC_MESSAGE(2), &k) - k[0].len ); + // DEBUG_PRINTF("BURST WRITE: to trans %d # chunk %d # transferred %d \n", size_to_do, chunk_size, byte_transferred); + size_to_do -= chunk_size; /* subtract the quantity of data already transferred */ + } + + // /* determine return code */ + if (byte_transferred != size) { + DEBUG_MSG("ERROR: SPI BURST WRITE FAILURE\n"); + return LGW_SPI_ERROR; + } else { + DEBUG_MSG("Note: SPI burst write success\n"); + return LGW_SPI_SUCCESS; + } + + return LGW_SPI_SUCCESS; +} + +/** +@brief LoRa concentrator SPI burst (multiple-byte) read +@param spi_target generic pointer to SPI target (implementation dependant) +@param address 7-bit register address +@param data pointer to byte array that will be written from the LoRa concentrator +@param size size of the transfer, in byte(s) +@return status of register operation (LGW_SPI_SUCCESS/LGW_SPI_ERROR) +*/ +int lgw_spi_rb(void *spi_target, uint8_t spi_mux_target, uint16_t address, uint8_t *data, uint16_t size) +{ + int spi_device; + uint8_t command[4]; + uint8_t command_size; + // struct spi_ioc_transfer k[2]; + int size_to_do, chunk_size, offset; + int byte_transferred = 0; + int i; + + // printf("lgw_spi_rb -> spi_mux_target: %u address: %X data[0]: %X size: %u\n", spi_mux_target, address, data[0], size); + + // /* check input parameters */ + CHECK_NULL(data); + if (size == 0) { + DEBUG_MSG("ERROR: BURST OF NULL LENGTH\n"); + return LGW_SPI_ERROR; + } + + // spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */ + + // /* prepare command byte */ + command[0] = spi_mux_target; + command[1] = READ_ACCESS | ((address >> 8) & 0x7F); + command[2] = ((address >> 0) & 0xFF); + command[3] = 0x00; + command_size = 4; + size_to_do = size; + + // /* I/O transaction */ + // memset(&k, 0, sizeof(k)); /* clear k */ + // k[0].tx_buf = (unsigned long) &command[0]; + // k[0].len = command_size; + // k[0].cs_change = 0; + // k[1].cs_change = 0; + for (i = 0; size_to_do > 0; ++i) { + chunk_size = (size_to_do < LGW_BURST_CHUNK) ? size_to_do : LGW_BURST_CHUNK; + offset = i * LGW_BURST_CHUNK; + // k[1].rx_buf = (unsigned long)(data + offset); + // k[1].len = chunk_size; + // byte_transferred += (ioctl(spi_device, SPI_IOC_MESSAGE(2), &k) - k[0].len ); + // DEBUG_PRINTF("BURST READ: to trans %d # chunk %d # transferred %d \n", size_to_do, chunk_size, byte_transferred); + size_to_do -= chunk_size; /* subtract the quantity of data already transferred */ + } + + /* determine return code */ + if (byte_transferred != size) { + DEBUG_MSG("ERROR: SPI BURST READ FAILURE\n"); + return LGW_SPI_ERROR; + } else { + DEBUG_MSG("Note: SPI burst read success\n"); + return LGW_SPI_SUCCESS; + } + return LGW_SPI_SUCCESS; +} + diff --git a/examples/T-ETH-ELite-Shield/T-ETH-Elite-LTE-Shield/T-ETH-Elite-LTE-Shield.ino b/examples/T-ETH-ELite-Shield/T-ETH-Elite-LTE-Shield/T-ETH-Elite-LTE-Shield.ino new file mode 100644 index 0000000..5592f9a --- /dev/null +++ b/examples/T-ETH-ELite-Shield/T-ETH-Elite-LTE-Shield/T-ETH-Elite-LTE-Shield.ino @@ -0,0 +1,257 @@ +/** + * @file T-ETH-Elite-LTE-Shield.ino + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd + * @date 2024-06-5 + * @note This warehouse does not provide modem examples, only how to communicate and initialize. + * For how to use modem, you can check the TinyGSM library or check the AT command manual of the relevant modem. + * + * Example links for reference: + * You can refer to the example link, written for novice users. Please note that it is a reference, + * not a direct operation. The relevant GPIO must be set to be consistent with ELite before running. + * + * - A7670X/A7608X/SIM7670G : https://github.com/Xinyuan-LilyGO/LilyGO-T-A76XX + * - SIM7600X : https://github.com/Xinyuan-LilyGO/T-SIM7600X + * - SIM7070G/SIM7000X : https://github.com/Xinyuan-LilyGO/LilyGO-T-SIM7000G + * - SIM7080G : https://github.com/Xinyuan-LilyGO/LilyGO-T-SIM7080G + * If the message "No GPS data received" appears, please check whether the GPS switch on the back of the T-ETH-Elite-LTE-Shield board has been turned to the ON side. + */ + +#include +#include "utilities.h" + +// The baud rate may not be suitable for all GPS modules. Adjust the baud rate according to your own GPS module. +#define GPS_BAUD 9600 +#define GPSSerial Serial1 +#define SerialAT Serial2 + + +#include +TinyGPSPlus gps; + +static bool waitResponse(String &data, String rsp, uint32_t timeout); +static bool waitResponse(String rsp, uint32_t timeout); +static void printStr(const char *str, int len); +static void printDateTime(TinyGPSDate &d, TinyGPSTime &t); +static void printInt(unsigned long val, bool valid, int len); +static void smartDelay(unsigned long ms); +static void printFloat(float val, bool valid, int len, int prec); +static bool checkSimCard(); + +uint32_t checkAutoBaud() +{ + static uint32_t rates[] = {115200, 9600, 57600, 38400, 19200, 74400, 74880, + 230400, 460800, 2400, 4800, 14400, 28800 + }; + for (uint8_t i = 0; i < sizeof(rates) / sizeof(rates[0]); i++) { + uint32_t rate = rates[i]; + Serial.printf("Trying baud rate %u\n", rate); + SerialAT.updateBaudRate(rate); + delay(10); + for (int j = 0; j < 10; j++) { + SerialAT.print("AT\r\n"); + String input = SerialAT.readString(); + if (input.indexOf("OK") >= 0) { + Serial.printf("Modem responded at rate:%u\n", rate); + return rate; + } + } + } + SerialAT.updateBaudRate(115200); + return 0; +} + +void setup() +{ + Serial.begin(115200); + + SerialAT.begin(115200, SERIAL_8N1, MODEM_RX_PIN, MODEM_TX_PIN); + + GPSSerial.begin(9600, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + + Serial.println("Start modem ."); + + // Turn on modem + pinMode(MODEM_PWRKEY_PIN, OUTPUT); + digitalWrite(MODEM_PWRKEY_PIN, LOW); + delay(100); + digitalWrite(MODEM_PWRKEY_PIN, HIGH); + delay(100); + digitalWrite(MODEM_PWRKEY_PIN, LOW); + + delay(6000); + + if (!checkAutoBaud()) { + while (1) { + Serial.println(F(" Failed to connect to the modem! Check the baud and try again.")); + delay(2000); + } + } + + bool simCardOk = false; + int retry = 0; + while (retry < 5) { + simCardOk = checkSimCard(); + if (simCardOk) { + break; + } + retry++; + } + + if (simCardOk) { + Serial.println("SIM Card detected PASS"); + } else { + Serial.println("SIM Card detected FAILED"); + Serial.println("SIM Card detected FAILED"); + Serial.println("SIM Card detected FAILED"); + } + + + Serial.println("-----------------"); + Serial.println("GPS Start ......"); + +} + +void loop() +{ + if (gps.location.isValid() && gps.time.isValid() && gps.date.isValid()) { + printInt(gps.satellites.value(), gps.satellites.isValid(), 5); + printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1); + printFloat(gps.location.lat(), gps.location.isValid(), 11, 6); + printFloat(gps.location.lng(), gps.location.isValid(), 12, 6); + printInt(gps.location.age(), gps.location.isValid(), 5); + printDateTime(gps.date, gps.time); + printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2); + printFloat(gps.course.deg(), gps.course.isValid(), 7, 2); + printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2); + printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6); + printInt(gps.charsProcessed(), true, 6); + printInt(gps.sentencesWithFix(), true, 10); + printInt(gps.failedChecksum(), true, 9); + Serial.println(); + } else { + Serial.print("."); + } + smartDelay(1000); + if (millis() > 5000 && gps.charsProcessed() < 10) { + Serial.println(F("No GPS data received: check wiring")); + Serial.println(F("Please check whether the GPS switch on the back of the T-ETH-Elite-LTE-Shield board has been turned to the ON side.")); + delay(500); + } +} + + +static bool checkSimCard() +{ + SerialAT.println("AT"); + if (waitResponse("OK", 1000)) { + SerialAT.println("AT+CPIN?"); + if (waitResponse("+CPIN: READ", 1000)) { + Serial.println("[Modem]: SIM Card detected inserted"); + return true; + } + } + return false; +} + + +static bool waitResponse(String rsp, uint32_t timeout) +{ + String data; + return waitResponse(data, rsp, timeout); +} + +static bool waitResponse(String &data, String rsp, uint32_t timeout) +{ + uint32_t startMillis = millis(); + do { + while (SerialAT.available() > 0) { + int8_t ch = SerialAT.read(); + data += static_cast(ch); + if (rsp.length() && data.endsWith(rsp)) { + return true; + } + } + } while (millis() - startMillis < 1000); + return false; +} + + + + +// This custom version of delay() ensures that the gps object +// is being "fed". +static void smartDelay(unsigned long ms) +{ + unsigned long start = millis(); + do { + while (GPSSerial.available()) { + // Serial.write(GPSSerial.read()); + gps.encode(GPSSerial.read()); + } + } while (millis() - start < ms); +} + +static void printFloat(float val, bool valid, int len, int prec) +{ + if (!valid) { + while (len-- > 1) + Serial.print('*'); + Serial.print(' '); + } else { + Serial.print(val, prec); + int vi = abs((int)val); + int flen = prec + (val < 0.0 ? 2 : 1); // . and - + flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1; + for (int i = flen; i < len; ++i) + Serial.print(' '); + } + smartDelay(0); +} + + + +static void printInt(unsigned long val, bool valid, int len) +{ + char sz[32] = "*****************"; + if (valid) + sprintf(sz, "%ld", val); + sz[len] = 0; + for (int i = strlen(sz); i < len; ++i) + sz[i] = ' '; + if (len > 0) + sz[len - 1] = ' '; + Serial.print(sz); + smartDelay(0); +} + +static void printDateTime(TinyGPSDate &d, TinyGPSTime &t) +{ + if (!d.isValid()) { + Serial.print(F("********** ")); + } else { + char sz[32]; + sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year()); + Serial.print(sz); + } + + if (!t.isValid()) { + Serial.print(F("******** ")); + } else { + char sz[32]; + sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second()); + Serial.print(sz); + } + + printInt(d.age(), d.isValid(), 5); + smartDelay(0); +} + +static void printStr(const char *str, int len) +{ + int slen = strlen(str); + for (int i = 0; i < len; ++i) + Serial.print(i < slen ? str[i] : ' '); + smartDelay(0); +} \ No newline at end of file diff --git a/examples/T-ETH-ELite-Shield/T-ETH-Elite-LoRa-Shield/T-ETH-Elite-LoRa-Shield.ino b/examples/T-ETH-ELite-Shield/T-ETH-Elite-LoRa-Shield/T-ETH-Elite-LoRa-Shield.ino new file mode 100644 index 0000000..cb0e823 --- /dev/null +++ b/examples/T-ETH-ELite-Shield/T-ETH-Elite-LoRa-Shield/T-ETH-Elite-LoRa-Shield.ino @@ -0,0 +1,899 @@ +/** + * @file LoRaShield.ino + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd + * @date 2024-06-22 + * @note The example demonstrates the functions of all peripherals on the T-ETH-Elite-LoRa-Shield + * If the message "No GPS data received" appears, please check whether the GPS switch on the back of the T-ETH-Elite-LoRa-Shield board has been turned to the ON side. + */ +#include "config.h" +#include +#include +#include +#if ESP_ARDUINO_VERSION < ESP_ARDUINO_VERSION_VAL(3,0,0) +#include //Is to use the modified ETHClass +#define ETH ETH2 +#else +#include +#endif + +enum adc_buttonF { + ADC_BUTTON_NONE, + ADC_BUTTON_1, + ADC_BUTTON_2, + ADC_BUTTON_3, + ADC_BUTTON_4, + ADC_BUTTON_5, +}; + +#define GPSSerial Serial1 +#define GPS_BAUD 9600 +#define SAMPLE_TIME 200 +#define DEVIATION 0.1 +#define SEALEVELPRESSURE_HPA (1013.25) + +float current_freq = CONFIG_RADIO_FREQ; + +TinyGPSPlus gps; +Adafruit_BME280 bme; + +static xSemaphoreHandle btnSemap = NULL; +static xQueueHandle adc_queue = NULL; +// save transmission state between loops +static int transmissionState = RADIOLIB_ERR_NONE; +// flag to indicate that a packet was sent +static volatile bool transmittedFlag = false; +static uint32_t counter = 0; +static String payload = "None"; + +static uint32_t last_btn_num = ADC_BUTTON_1; +static bool last_recv_status = false; +static int prev_state; +static int curr_state = HIGH; + +void setFlag(void) +{ + // we sent a packet, set the flag + transmittedFlag = true; +} + + + +void setup() +{ + Serial.begin(115200); + + // Register eth envet + WiFi.onEvent(WiFiEvent); + + // Onboard LED is a multiplexed function + // SX1276-TCXO: LED IO38 is multiplexed as TCXO enable function + // SX1280PA: LED IO38 is multiplexed as LoRa (TX) antenna control function enable function + // When using other model modules, it is only LED function +#ifdef TCXO_ENABLE_PIN + pinMode(TCXO_ENABLE_PIN, OUTPUT); + digitalWrite(TCXO_ENABLE_PIN, HIGH); +#else + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, HIGH); +#endif + + // Initialize SPI bus + SPI.begin(SPI_SCLK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN); + + // Radio and SD card share the bus. During initialization, their respective CS Pin needs to be set to HIGH. + pinMode(RADIO_CS_PIN, OUTPUT); + digitalWrite(RADIO_CS_PIN, HIGH); + // Radio and SD card share the bus. During initialization, their respective CS Pin needs to be set to HIGH. + pinMode(SD_CS_PIN, OUTPUT); + digitalWrite(SD_CS_PIN, HIGH); + + // Initialize sdcard + if (!SD.begin(SD_CS_PIN)) { + Serial.println("Warning: Failed to init SD card"); + } else { + Serial.println("SD card init succeeded, size : "); + Serial.print(SD.cardSize() / (1024 * 1024)); + Serial.println("MBytes"); + } + + // Initialize gps serial + GPSSerial.begin(GPS_BAUD, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + + // Initialize wire bus + Wire.begin(I2C_SDA_PIN, I2C_SCL_PIN); + + // Initialize ethernet + if (!ETH.begin(ETH_PHY_W5500, 1, ETH_CS_PIN, ETH_INT_PIN, ETH_RST_PIN, + SPI3_HOST, + ETH_SCLK_PIN, ETH_MISO_PIN, ETH_MOSI_PIN)) { + Serial.println("ETH start Failed!"); + } + + // Initialize adc button + beginButton(); + + // Initialize ssd1306 oled + beginDisplay(); + + // Initialize bme280 sensor + bool isSensorOnline = beginSensor(); + + // Initialize LoRa + bool isRadioOnline = beginRadio(); + + + printResult(isRadioOnline, isSensorOnline); + + // init boot button + pinMode(0, INPUT_PULLUP); +} + + + +// Only used for LR1121 frequency switching function +void switch_freq() +{ +#ifdef CONFIG_RADIO_FREQ1 + if (current_freq == CONFIG_RADIO_FREQ) { + current_freq = CONFIG_RADIO_FREQ1; + if (radio.setFrequency(current_freq, false) == RADIOLIB_ERR_INVALID_FREQUENCY) { + Serial.printf("Selected frequency %f is invalid for this module!\n", current_freq); + } + if (radio.setOutputPower(CONFIG_RADIO_OUTPUT_POWER1) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { + Serial.printf("Selected output power %d is invalid for this module!\n", CONFIG_RADIO_OUTPUT_POWER1); + } + + } else { + current_freq = CONFIG_RADIO_FREQ; + if (radio.setFrequency(current_freq, false) == RADIOLIB_ERR_INVALID_FREQUENCY) { + Serial.printf("Selected frequency %f is invalid for this module!\n", current_freq); + } + if (radio.setOutputPower(CONFIG_RADIO_OUTPUT_POWER) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { + Serial.printf("Selected output power %d is invalid for this module!\n", CONFIG_RADIO_OUTPUT_POWER); + } + } +#endif +} + + + +void loop() +{ + + // BOOT Pin Swtcih Freq1 +#ifdef CONFIG_RADIO_FREQ1 + prev_state = curr_state; + curr_state = digitalRead(0); + if (prev_state == HIGH && curr_state == LOW) { + switch_freq(); + last_recv_status = false; + } +#endif + + xSemaphoreTake(btnSemap, portMAX_DELAY); + uint32_t btn = last_btn_num; + xSemaphoreGive(btnSemap); + switch (btn) { + case ADC_BUTTON_1: // GPS + dispGPS(); + last_recv_status = false; + break; + case ADC_BUTTON_2: // Radio Tx + dispRadioTx(); + last_recv_status = false; + break; + case ADC_BUTTON_3: // Radio Rx + dispRadioRx(); + break; + case ADC_BUTTON_4: // Sensor + dispSensor(); + last_recv_status = false; + break; + case ADC_BUTTON_5: // NetWork + last_recv_status = false; + dispNetwork(); + break; + default: + break; + } + smartDelay(150); +} + +void smartDelay(uint32_t ms) +{ + static uint32_t interval = 0; + uint32_t start = millis(); + do { + while (GPSSerial.available()) { + // Serial.write(GPSSerial.read()); + gps.encode(GPSSerial.read()); + } + } while (millis() - start < ms); + + // Check GPS data + if (millis() > 15000 && gps.charsProcessed() < 30) { + if (millis() > interval) { + Serial.println(F("No GPS data received: check wiring")); + Serial.println(F("Please check whether the GPS switch on the back of the T-ETH-Elite-LoRa-Shield board has been turned to the ON side.")); + interval = millis() + 2000; + } + } +} + +void dispNetwork() +{ + if (u8g2) { + u8g2->clearBuffer(); + u8g2->drawRFrame(0, 0, 128, 64, 5); + u8g2->setFont(u8g2_font_crox1h_tr); + u8g2->setCursor(10, 15); + u8g2->print("IP:"); u8g2->print(ETH.localIP().toString()); + u8g2->setCursor(10, 30); + u8g2->print("MAC:"); u8g2->print(ETH.macAddress()); + u8g2->sendBuffer(); + } else { + Serial.print("IP:"); Serial.println(ETH.localIP().toString()); + Serial.print("MAC:"); Serial.println(ETH.macAddress()); + delay(1000); + } +} + +void dispGPS() +{ + if (u8g2) { + u8g2->clearBuffer(); + u8g2->drawRFrame(0, 0, 128, 64, 5); + u8g2->setFont(u8g2_font_crox1h_tr); + u8g2->setCursor(10, 15); + u8g2->print("lat:"); u8g2->print(gps.location.isValid() ? gps.location.lat() : 0, 5); + u8g2->setCursor(10, 30); + u8g2->print("lng:"); u8g2->print(gps.location.isValid() ? gps.location.lng() : 0, 5); + u8g2->setCursor(10, 45); + u8g2->print("Time:"); + if (gps.date.isValid() && gps.time.isValid()) { + u8g2->print(gps.time.hour()); + u8g2->print(":"); + u8g2->print(gps.time.minute()); + u8g2->print(":"); + u8g2->print(gps.time.second()); + } else { + u8g2->print("00:00:00"); + } + u8g2->setCursor(10, 60); + u8g2->print("Rx:"); + u8g2->print(gps.charsProcessed()); + u8g2->sendBuffer(); + } else { + printInt(gps.satellites.value(), gps.satellites.isValid(), 5); + printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1); + printFloat(gps.location.lat(), gps.location.isValid(), 11, 6); + printFloat(gps.location.lng(), gps.location.isValid(), 12, 6); + printInt(gps.location.age(), gps.location.isValid(), 5); + printDateTime(gps.date, gps.time); + printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2); + printFloat(gps.course.deg(), gps.course.isValid(), 7, 2); + printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2); + printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6); + printInt(gps.charsProcessed(), true, 6); + printInt(gps.sentencesWithFix(), true, 10); + printInt(gps.failedChecksum(), true, 9); + Serial.println(); + + } +} + +void dispRadioTx() +{ + static uint32_t last_send_millis = 0; + + + // check if the previous transmission finished + if (transmittedFlag) { + + payload = "#" + String(counter++); + + // reset flag + transmittedFlag = false; + + Serial.print(F("Radio Sending another packet ... ")); + + if (transmissionState == RADIOLIB_ERR_NONE) { + // packet was successfully sent + Serial.println(F("transmission finished!")); + // NOTE: when using interrupt-driven transmit method, + // it is not possible to automatically measure + // transmission data rate using getDataRate() + } else { + Serial.print(F("failed, code ")); + Serial.println(transmissionState); + } + + if (u8g2) { + u8g2->clearBuffer(); + u8g2->drawRFrame(0, 0, 128, 64, 5); + + u8g2->setFont(u8g2_font_crox1h_tr); + u8g2->setCursor(15, 15); + u8g2->print("TX:"); + u8g2->setCursor(15, 30); + u8g2->print("STATE:"); + u8g2->setCursor(15, 45); + u8g2->print("FREQ:"); + + // u8g2->setFont(u8g2_font_crox1h_tr); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(payload.c_str()) - 14, 15 ); + u8g2->print(payload); + String state = transmissionState == RADIOLIB_ERR_NONE ? "NONE" : String(transmissionState); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(state.c_str()) - 14, 30 ); + u8g2->print(state); + String freq = String(current_freq) + "MHz"; + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(freq.c_str()) - 14, 45 ); + u8g2->print(freq); + u8g2->sendBuffer(); + } + + } + + if (millis() > last_send_millis) { + // send another one + // + + // you can transmit C-string or Arduino string up to + // 256 characters long + transmissionState = radio.startTransmit(payload); + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + int state = radio.startTransmit(byteArr, 8); + */ + last_send_millis = millis() + 1000; + } +} + +void drawRadioRx(String payload, String snr, String rssi) +{ + if (u8g2) { + u8g2->clearBuffer(); + u8g2->drawRFrame(0, 0, 128, 64, 5); + u8g2->setFont(u8g2_font_crox1h_tr); + u8g2->setCursor(15, 15); + u8g2->print("RX:"); + u8g2->setCursor(15, 30); + u8g2->print("SNR:"); + u8g2->setCursor(15, 45); + u8g2->print("RSSI:"); + u8g2->setCursor(15, 58); + u8g2->print("FREQ:"); + + // u8g2->setFont(u8g2_font_crox1h_tr); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(payload.c_str()) - 21, 15 ); + u8g2->print(payload); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(snr.c_str()) - 21, 30 ); + u8g2->print(snr); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(rssi.c_str()) - 21, 45 ); + u8g2->print(rssi); + u8g2->setCursor( U8G2_HOR_ALIGN_RIGHT(String(current_freq).c_str()) - 21, 58 ); + u8g2->print(String(current_freq)); + u8g2->sendBuffer(); + } +} + +void dispRadioRx() +{ + + if (!last_recv_status) { + transmissionState = radio.startReceive(); + last_recv_status = true; + drawRadioRx("NONE", "0dB", "0dBm"); + } + + // check if the flag is set + if (transmittedFlag) { + + // reset flag + transmittedFlag = false; + + // you can read received data as an Arduino String + int state = radio.readData(payload); + + // you can also read received data as byte array + /* + byte byteArr[8]; + int state = radio.readData(byteArr, 8); + */ + + if (state == RADIOLIB_ERR_NONE) { + + String rssi = String(radio.getRSSI()) + "dBm"; + String snr = String(radio.getSNR()) + "dB"; + + drawRadioRx(payload, snr, rssi); + + // packet was successfully received + Serial.println(F("Radio Received packet!")); + + // print data of the packet + Serial.print(F("Radio Data:\t\t")); + Serial.println(payload); + + // print RSSI (Received Signal Strength Indicator) + Serial.print(F("Radio RSSI:\t\t")); + Serial.println(rssi); + + // print SNR (Signal-to-Noise Ratio) + Serial.print(F("Radio SNR:\t\t")); + Serial.println(snr); + + } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { + // packet was received, but is malformed + Serial.println(F("CRC error!")); + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + } + + // put module back to listen mode + radio.startReceive(); + + } +} + +void dispSensor() +{ + if (u8g2) { + u8g2->clearBuffer(); + + u8g2->drawRFrame(0, 0, 128, 64, 5); + u8g2->setFont(u8g2_font_crox1h_tr); + + u8g2->setCursor(10, 15); + + u8g2->print("Temperature:"); + u8g2->print(bme.readTemperature()); + u8g2->print(" *C"); + + u8g2->setCursor(10, 30); + u8g2->print("Pressure:"); + u8g2->println(bme.readPressure() / 100.0F); + u8g2->print(" hPa"); + + u8g2->setCursor(10, 45); + u8g2->print("Altitude:"); + u8g2->println(bme.readAltitude(SEALEVELPRESSURE_HPA)); + u8g2->print(" m"); + + u8g2->setCursor(10, 58); + u8g2->print("Humidity:"); + u8g2->println(bme.readHumidity()); + u8g2->print(" %"); + + u8g2->sendBuffer(); + } else { + Serial.print("Temperature = "); + Serial.print(bme.readTemperature()); + Serial.println(" *C"); + + Serial.print("Pressure = "); + + Serial.print(bme.readPressure() / 100.0F); + Serial.println(" hPa"); + + Serial.print("Approx. Altitude = "); + Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA)); + Serial.println(" m"); + + Serial.print("Humidity = "); + Serial.print(bme.readHumidity()); + Serial.println(" %"); + + Serial.println(); + } +} + +void button_task(void *arg) +{ + uint32_t btn_number = ADC_BUTTON_NONE; + while (1) { + double voltage = analogReadMilliVolts(7) / 1000.0; + if (voltage > 2.2 - DEVIATION && voltage <= 2.2 + DEVIATION) { + btn_number = ADC_BUTTON_5; + } else if (voltage > 1.65 - DEVIATION && voltage <= 1.65 + DEVIATION) { + btn_number = ADC_BUTTON_4; + } else if (voltage > 1.11 - DEVIATION && voltage <= 1.11 + DEVIATION) { + btn_number = ADC_BUTTON_3; + } else if (voltage > 0.76 - DEVIATION && voltage <= 0.76 + DEVIATION) { + btn_number = ADC_BUTTON_2; + } else if (voltage > 0.43 - DEVIATION && voltage <= 0.43 + DEVIATION) { + btn_number = ADC_BUTTON_1; + } + xSemaphoreTake(btnSemap, portMAX_DELAY); + if (btn_number != last_btn_num) { + last_btn_num = btn_number; + } + xSemaphoreGive(btnSemap); + vTaskDelay(pdMS_TO_TICKS(SAMPLE_TIME)); + } + vTaskDelete(NULL); +} + +void beginButton() +{ + btnSemap = xSemaphoreCreateBinary(); + xSemaphoreGive(btnSemap); + adc_queue = xQueueCreate(1, sizeof(uint32_t)); + analogReadResolution(12); + analogSetAttenuation(ADC_11db); + xTaskCreatePinnedToCore(&button_task, "btn", 3 * 1024, NULL, 5, NULL, 0); +} + +bool beginSensor() +{ + // default settings + bool status = bme.begin(); + // You can also pass in a Wire library object like &Wire2 + // status = bme.begin(0x76, &Wire2) + if (!status) { + Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!"); + Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(), 16); + Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n"); + Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n"); + Serial.print(" ID of 0x60 represents a BME 280.\n"); + Serial.print(" ID of 0x61 represents a BME 680.\n"); + if (u8g2) { + u8g2->setFont(u8g2_font_ncenB08_tr); + u8g2->clearBuffer(); + u8g2->setCursor(0, 16); + u8g2->print("BME280 Could not find"); + u8g2->sendBuffer(); + } + return false; + } + return true; +} + +bool beginRadio() +{ + // initialize radio with default settings + int state = radio.begin(); + + Serial.print(F("Radio Initializing ... ")); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + return false; + } + + // set the function that will be called + // when packet transmission is finished + radio.setPacketSentAction(setFlag); + + /* + * Sets carrier frequency. + * SX1278/SX1276 : Allowed values range from 137.0 MHz to 525.0 MHz. + * SX1268/SX1262 : Allowed values are in range from 150.0 to 960.0 MHz. + * SX1280 : Allowed values are in range from 2400.0 to 2500.0 MHz. + * LR1121 : Allowed values are in range from 150.0 to 960.0 MHz, 1900 - 2200 MHz and 2400 - 2500 MHz. Will also perform calibrations. + * * * */ + + if (radio.setFrequency(current_freq) == RADIOLIB_ERR_INVALID_FREQUENCY) { + Serial.println(F("Selected frequency is invalid for this module!")); + return false; + } + + /* + * Sets LoRa link bandwidth. + * SX1278/SX1276 : Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz. Only available in %LoRa mode. + * SX1268/SX1262 : Allowed values are 7.8, 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125.0, 250.0 and 500.0 kHz. + * SX1280 : Allowed values are 203.125, 406.25, 812.5 and 1625.0 kHz. + * LR1121 : Allowed values are 62.5, 125.0, 250.0 and 500.0 kHz. + * * * */ + if (radio.setBandwidth(CONFIG_RADIO_BW) == RADIOLIB_ERR_INVALID_BANDWIDTH) { + Serial.println(F("Selected bandwidth is invalid for this module!")); + return false; + } + + + /* + * Sets LoRa link spreading factor. + * SX1278/SX1276 : Allowed values range from 6 to 12. Only available in LoRa mode. + * SX1262 : Allowed values range from 5 to 12. + * SX1280 : Allowed values range from 5 to 12. + * LR1121 : Allowed values range from 5 to 12. + * * * */ + if (radio.setSpreadingFactor(12) == RADIOLIB_ERR_INVALID_SPREADING_FACTOR) { + Serial.println(F("Selected spreading factor is invalid for this module!")); + return false; + } + + /* + * Sets LoRa coding rate denominator. + * SX1278/SX1276/SX1268/SX1262 : Allowed values range from 5 to 8. Only available in LoRa mode. + * SX1280 : Allowed values range from 5 to 8. + * LR1121 : Allowed values range from 5 to 8. + * * * */ + if (radio.setCodingRate(6) == RADIOLIB_ERR_INVALID_CODING_RATE) { + Serial.println(F("Selected coding rate is invalid for this module!")); + return false; + } + + /* + * Sets LoRa sync word. + * SX1278/SX1276/SX1268/SX1262/SX1280 : Sets LoRa sync word. Only available in LoRa mode. + * * */ + if (radio.setSyncWord(0xAB) != RADIOLIB_ERR_NONE) { + Serial.println(F("Unable to set sync word!")); + return false; + } + + /* + * Sets transmission output power. + * SX1278/SX1276 : Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin). High power +20 dBm operation is also supported, on the PA_BOOST pin. Defaults to PA_BOOST. + * SX1262 : Allowed values are in range from -9 to 22 dBm. This method is virtual to allow override from the SX1261 class. + * SX1268 : Allowed values are in range from -9 to 22 dBm. + * SX1280 : Allowed values are in range from -18 to 13 dBm. PA Version range : -18 ~ 3dBm + * LR1121 : Allowed values are in range from -9 to 22 dBm (high-power PA) or -17 to 14 dBm (low-power PA) + * * * */ + if (radio.setOutputPower(CONFIG_RADIO_OUTPUT_POWER) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { + Serial.println(F("Selected output power is invalid for this module!")); + return false; + } + +#if !defined(USING_SX1280) && !defined(USING_SX1280PA) && !defined(USING_LR1121) + /* + * Sets current limit for over current protection at transmitter amplifier. + * SX1278/SX1276 : Allowed values range from 45 to 120 mA in 5 mA steps and 120 to 240 mA in 10 mA steps. + * SX1262/SX1268 : Allowed values range from 45 to 120 mA in 2.5 mA steps and 120 to 240 mA in 10 mA steps. + * NOTE: set value to 0 to disable overcurrent protection + * * * */ + if (radio.setCurrentLimit(140) == RADIOLIB_ERR_INVALID_CURRENT_LIMIT) { + Serial.println(F("Selected current limit is invalid for this module!")); + return false; + } +#endif + + /* + * Sets preamble length for LoRa or FSK modem. + * SX1278/SX1276 : Allowed values range from 6 to 65535 in %LoRa mode or 0 to 65535 in FSK mode. + * SX1262/SX1268 : Allowed values range from 1 to 65535. + * SX1280 : Allowed values range from 1 to 65535. preamble length is multiple of 4 + * LR1121 : Allowed values range from 1 to 65535. + * * */ + if (radio.setPreambleLength(16) == RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH) { + Serial.println(F("Selected preamble length is invalid for this module!")); + return false; + } + + // Enables or disables CRC check of received packets. + if (radio.setCRC(false) == RADIOLIB_ERR_INVALID_CRC_CONFIGURATION) { + Serial.println(F("Selected CRC is invalid for this module!")); + return false; + } + +// RADIOLIB_LR11X0_RFSW_DIO6_ENABLED +#ifdef USING_DIO2_AS_RF_SWITCH +#ifdef USING_SX1262 + // Some SX126x modules use DIO2 as RF switch. To enable + // this feature, the following method can be used. + // NOTE: As long as DIO2 is configured to control RF switch, + // it can't be used as interrupt pin! + if (radio.setDio2AsRfSwitch() != RADIOLIB_ERR_NONE) { + Serial.println(F("Failed to set DIO2 as RF switch!")); + return false; + } +#endif //USING_SX1262 +#endif //USING_DIO2_AS_RF_SWITCH + + +#if defined(USING_LR1121) + // LR1121 + // set RF switch configuration for Wio WM1110 + // Wio WM1110 uses DIO5 and DIO6 for RF switching + static const uint32_t rfswitch_dio_pins[] = { + RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, + RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC + }; + + static const Module::RfSwitchMode_t rfswitch_table[] = { + // mode DIO5 DIO6 + { LR11x0::MODE_STBY, { LOW, LOW } }, + { LR11x0::MODE_RX, { HIGH, LOW } }, + { LR11x0::MODE_TX, { LOW, HIGH } }, + { LR11x0::MODE_TX_HP, { LOW, HIGH } }, + { LR11x0::MODE_TX_HF, { LOW, LOW } }, + { LR11x0::MODE_GNSS, { LOW, LOW } }, + { LR11x0::MODE_WIFI, { LOW, LOW } }, + END_OF_MODE_TABLE, + }; + radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table); + + // LR1121 TCXO Voltage 2.85~3.15V + radio.setTCXO(3.0); +#endif + +#ifdef RADIO_RX_PIN + // SX1280 PA Version + radio.setRfSwitchPins(RADIO_RX_PIN, RADIO_TX_PIN); +#endif + + // start transmitting the first packet + Serial.print(F("Radio Sending first packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + transmissionState = radio.startTransmit(String(counter).c_str()); + + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + state = radio.startTransmit(byteArr, 8); + */ + + return true; +} + + +bool beginDisplay() +{ + Wire.beginTransmission(DISPLAY_ADDR); + if (Wire.endTransmission() == 0) { + Serial.printf("Find Display model at 0x%X address\n", DISPLAY_ADDR); + u8g2 = new DISPLAY_MODEL(U8G2_R0, U8X8_PIN_NONE); + u8g2->begin(); + u8g2->clearBuffer(); + u8g2->setFont(u8g2_font_inb19_mr); + u8g2->drawStr(0, 30, "LilyGo"); + u8g2->drawHLine(2, 35, 47); + u8g2->drawHLine(3, 36, 47); + u8g2->drawVLine(45, 32, 12); + u8g2->drawVLine(46, 33, 12); + u8g2->setFont(u8g2_font_inb19_mf); + u8g2->drawStr(58, 60, "LoRa"); + u8g2->sendBuffer(); + u8g2->setFont(u8g2_font_fur11_tf); + delay(3000); + return true; + } + + Serial.printf("Warning: Failed to find Display at 0x%0X address\n", DISPLAY_ADDR); + return false; +} + + + +void printResult(bool radio, bool sensor) +{ + Serial.print("Radio : "); + Serial.println((radio) ? "+" : "-"); + + Serial.print("PSRAM : "); + Serial.println((psramFound()) ? "+" : "-"); + + Serial.print("Display : "); + Serial.println(( u8g2) ? "+" : "-"); + + Serial.print("Sd Card : "); + Serial.println((SD.cardSize() != 0) ? "+" : "-"); + + Serial.print("Sensor : "); + Serial.println((sensor) ? "+" : "-"); + + + if (u8g2) { + u8g2->clearBuffer(); + u8g2->setFont(u8g2_font_NokiaLargeBold_tf ); + uint16_t str_w = u8g2->getStrWidth("T-ETH"); + u8g2->drawStr((u8g2->getWidth() - str_w) / 2, 16, "T-ETH"); + u8g2->drawHLine(5, 21, u8g2->getWidth() - 5); + u8g2->drawStr( 0, 38, "Disp:"); u8g2->drawStr( 45, 38, ( u8g2) ? "+" : "-"); + u8g2->drawStr( 0, 54, "SD :"); u8g2->drawStr( 45, 54, (SD.cardSize() != 0) ? "+" : "-"); + u8g2->drawStr( 62, 38, "Radio:"); u8g2->drawStr( 120, 38, ( radio ) ? "+" : "-"); + u8g2->drawStr( 62, 54, "Sensor:"); u8g2->drawStr( 120, 54, ( sensor ) ? "+" : "-"); + u8g2->sendBuffer(); + + } +} + + +static void printFloat(float val, bool valid, int len, int prec) +{ + if (!valid) { + while (len-- > 1) + Serial.print('*'); + Serial.print(' '); + } else { + Serial.print(val, prec); + int vi = abs((int)val); + int flen = prec + (val < 0.0 ? 2 : 1); // . and - + flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1; + for (int i = flen; i < len; ++i) + Serial.print(' '); + } + smartDelay(0); +} + +static void printInt(unsigned long val, bool valid, int len) +{ + char sz[32] = "*****************"; + if (valid) + sprintf(sz, "%ld", val); + sz[len] = 0; + for (int i = strlen(sz); i < len; ++i) + sz[i] = ' '; + if (len > 0) + sz[len - 1] = ' '; + Serial.print(sz); + smartDelay(0); +} + +static void printDateTime(TinyGPSDate &d, TinyGPSTime &t) +{ + if (!d.isValid()) { + Serial.print(F("********** ")); + } else { + char sz[32]; + sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year()); + Serial.print(sz); + } + + if (!t.isValid()) { + Serial.print(F("******** ")); + } else { + char sz[32]; + sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second()); + Serial.print(sz); + } + + printInt(d.age(), d.isValid(), 5); + smartDelay(0); +} + +static void printStr(const char *str, int len) +{ + int slen = strlen(str); + for (int i = 0; i < len; ++i) + Serial.print(i < slen ? str[i] : ' '); + smartDelay(0); +} + + +void WiFiEvent(arduino_event_id_t event) +{ + switch (event) { + case ARDUINO_EVENT_ETH_START: + Serial.println("ETH Started"); + break; + case ARDUINO_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case ARDUINO_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.print("Mbps"); + Serial.print(", "); + Serial.print("GatewayIP:"); + Serial.println(ETH.gatewayIP()); + break; + case ARDUINO_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + break; + case ARDUINO_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + break; + default: + break; + } +} diff --git a/examples/T-ETH-ELite-Shield/T-ETH-Elite-LoRa-Shield/config.h b/examples/T-ETH-ELite-Shield/T-ETH-Elite-LoRa-Shield/config.h new file mode 100644 index 0000000..8a0a5c0 --- /dev/null +++ b/examples/T-ETH-ELite-Shield/T-ETH-Elite-LoRa-Shield/config.h @@ -0,0 +1,109 @@ +/** + * @file config.h + * @author Lewis He (lewishe@outlook.com) + * @license MIT + * @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd + * @date 2024-06-22 + * + */ +#include +#include +#include +#include +#include "utilities.h" + +// Please select the LoRa model you need to use in config.h +// #define USING_SX1262 +// #define USING_LR1121 +// #define USING_SX1280 +// #define USING_SX1276 +// #define USING_SX1276_TCXO +// #define USING_SX1280PA + + +#define DISPLAY_MODEL U8G2_SSD1306_128X64_NONAME_F_HW_I2C +#define DISPLAY_ADDR 0x3C +#define U8G2_HOR_ALIGN_CENTER(t) ((u8g2->getDisplayWidth() - (u8g2->getUTF8Width(t))) / 2) +#define U8G2_HOR_ALIGN_RIGHT(t) ( u8g2->getDisplayWidth() - u8g2->getUTF8Width(t)) + + +DISPLAY_MODEL *u8g2 = NULL; + +#if defined(USING_SX1276) +#define CONFIG_RADIO_FREQ 850.0 +#define CONFIG_RADIO_OUTPUT_POWER 17 +#define CONFIG_RADIO_BW 125.0 +SX1276 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + + +#elif defined(USING_SX1276_TCXO) +#define CONFIG_RADIO_FREQ 850.0 +#define CONFIG_RADIO_OUTPUT_POWER 17 +#define CONFIG_RADIO_BW 125.0 +#define TCXO_ENABLE_PIN 38 +SX1276 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + + +#elif defined(USING_SX1278) +#define CONFIG_RADIO_FREQ 433.0 +#define CONFIG_RADIO_OUTPUT_POWER 17 +#define CONFIG_RADIO_BW 125.0 +SX1278 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_SX1262) +#define CONFIG_RADIO_FREQ 850.0 +#define CONFIG_RADIO_OUTPUT_POWER 22 +#define CONFIG_RADIO_BW 125.0 + +SX1262 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_SX1280) +#define CONFIG_RADIO_FREQ 2450.0 +#define CONFIG_RADIO_OUTPUT_POWER 13 +#define CONFIG_RADIO_BW 203.125 +SX1280 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#define RADIO_RX_PIN 13 +#define RADIO_TX_PIN 38 + +#elif defined(USING_SX1280PA) +#define CONFIG_RADIO_FREQ 2450.0 +// PA Version power range : -18 ~ 3dBm +#define CONFIG_RADIO_OUTPUT_POWER 3 +#define CONFIG_RADIO_BW 203.125 +SX1280 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + + +#define RADIO_RX_PIN 13 +#define RADIO_TX_PIN 38 + + +#elif defined(USING_SX1268) +#define CONFIG_RADIO_FREQ 433.0 +#define CONFIG_RADIO_OUTPUT_POWER 22 +#define CONFIG_RADIO_BW 125.0 +SX1268 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#elif defined(USING_LR1121) + +// The maximum power of LR1121 2.4G band can only be set to 13 dBm +#define CONFIG_RADIO_FREQ 2450.0 +#define CONFIG_RADIO_OUTPUT_POWER 13 +#define CONFIG_RADIO_BW 125.0 + +// The maximum power of LR1121 Sub 1G band can only be set to 22 dBm +#define CONFIG_RADIO_FREQ1 850.0 +#define CONFIG_RADIO_OUTPUT_POWER1 22 +#define CONFIG_RADIO_BW1 125.0 + +LR1121 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +#else + +#error "Please select the LoRa model you need to use in config.h !" + +#endif + + + +