Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LoRaWAN] Rework bands, official Rx windows, support ADR, confirm frames, improve EEPROM handling, support clock drift #867

Merged
merged 22 commits into from
Nov 12, 2023

Conversation

StevenCellist
Copy link
Collaborator

There's a lot to unpack here, as a lot has happened. But first and foremost a HUGE thank you to @HeadBoffin for supporting me through this adventure.

So.. what did happen? The largest change is the integration of ADR which required a complete rework of the Rx windows. Using CAD does not work for high datarate / low SF due to the speed required to catch a downlink. So I had to change to RxSingle with timeout to properly know if a receive is in progress at the end of an Rx window; but then there is a difference in IRQ handling between SX126x and SX127x, such that the logic ends up a bit awkward. There may be room for improvement here.

Here's a (non-exhaustive, I may have forgotten something!) list of what has new or changed:

  • [LoRaWAN] new band system to support both dynamic and fixed bands
  • [LoRaWAN] fix decryption of downlink application payload
  • [LoRaWAN] implement confirmed frames (includes Enabling ACK support for LoRaWAN frames. #861)
  • [LoRaWAN] change EEPROM logic to allow non-EEPROM builds as well (as long as DevNonces / sessions are allowed to be reset from the LNS)
  • [LoRaWAN] implement software wear leveling on FcntUp to improve the lifecycle of EEPROM
  • [LoRaWAN] implement ADR
  • [LoRaWAN] allow setting a specific datarate for joins and uplinks
  • [LoRaWAN] convert joinOTAA to use Rx windows as well
  • [LoRaWAN] allow setting the downlink datarate for Rx2 (required for e.g. TTN EU868)
  • [LoRaWAN] fix Correct EU868 Coding Rate (4/7->4/5) #865
  • [LoRaWAN] update examples (should also fix LoRaWAN OTAA example fix #866)
  • [LoRaWAN] rename band types to dynamic and fixed as per TR007
  • [ArduinoHal] add an option to compensate for drifting clocks (e.g. older Atmel controllers), required for tight timing in LoRaWAN windows
  • [SX126x] implement specific functions for use in Rx windows in LoRaWAN
  • [SX127x] implement specific functions for use in Rx windows in LoRaWAN

This PR has been tested on the following devices:

  • ESP32 & SX1276 (TTGO LoRa32 T3 v1.6.1)
  • SAMD & SX1276 (Adafruit Feather with RFM95)
  • ESP32-S3 & SX1262 (Heltec Wireless Stick Lite V3)
  • ASR605x & SX1262 (Heltec Cubecell AB-01)
  • ATmega4808 & SX1262

And has been tested on the following regions:

  • EU868
  • AU915

Further investigation should be done on the timeout of the SX127x series. It does work almost completely, but I do not fully understand why and this is definitely not final. The device does seem to fail to catch empty downlinks (e.g. confirming an uplink or after ADR Ack Req). One more known problem is the handling of the ADR channel mask on fixed bands, where the index of the channel appears offset by 8 maybe due to swapped bytes. But my testing infrastructure makes it hard to debug this.

I know that there are merging problems due to some further development on the main stack.. don't know how to go about that honestly.

@nmaas87
Copy link
Contributor

nmaas87 commented Nov 3, 2023

Hey @StevenCellist - thanks a lot for the awesome PR,
I directly snatched your repo and tried to do a test with my current setup (RAK11300 / Arduino-Pico framework).

This is the current test code

#include <RadioLib.h>

SPISettings spiSettings(2000000, MSBFIRST, SPI_MODE0);
// cs, irq, rst, GPIO
SX1262 radio = new Module(13, 29, 14, 15, SPI1, spiSettings);

LoRaWANNode node(&radio, &EU868);

void setup() {
  Serial.begin(9600);

SPI1.setCS(13);
SPI1.setSCK(10);
SPI1.setTX(11);
SPI1.setRX(12);
SPI1.begin(13);

// enable antenna switch power
pinMode(25, OUTPUT);
digitalWrite(25, HIGH); 

delay(3000);

  Serial.print(F("[SX1262] Initializing ... "));
  int state = radio.begin();
  if(state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success init!"));
  } else {
    Serial.print(F("failed init, code "));
    Serial.println(state);
    while(true);
  }

  // first we need to initialize the device storage
  node.wipe();

  uint64_t joinEUI = 0x23...;
  uint64_t devEUI = 0xE6....;
  uint8_t nwkKey[] = {0xE6,...};
  uint8_t appKey[] = {0xE6,...};
 
  // this can take up to 20 seconds, and requires a LoRaWAN gateway in range
  Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
  state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
  if(state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success oota!"));
    //while(true);
  } else {
    Serial.print(F("failed oota, code "));
    Serial.println(state);
    while(true);
  }
  
  
  // after the device has been activated,
  // network can be rejoined after device power cycle
  // by calling "begin"
  /*
    Serial.print(F("[LoRaWAN] Resuming previous session ... "));
    state = node.restoreOTAA();
    //state = node.begin();
    if(state == RADIOLIB_ERR_NONE) {
      Serial.println(F("success!"));
    } else {
      Serial.print(F("failed, code "));
      Serial.println(state);
      while(true);
    }
    */
}

// counter to keep track of transmitted packets
int count = 0;

void loop() {
  // send uplink to port 10
  Serial.print(F("[LoRaWAN] Sending uplink packet ... "));
  String strUp = "Hello World! #" + String(count++);
  int state = node.uplink(strUp, 10);
  if(state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
  }

  // wait before sending another packet
  delay(10000);
}

However, this does not compile successfully:

"X:\\arduino\\portable\\packages\\rp2040\\tools\\pqt-gcc\\2.1.0-a-d3d2e6b/bin/arm-none-eabi-g++" -I "X:\\arduino\\build/core" -c -Werror=return-type -Wno-psabi -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSBD_PID=0x000a -DUSBD_VID=0x2e8a -DUSBD_MAX_POWER_MA=250 "-DUSB_MANUFACTURER=\"Raspberry Pi\"" "-DUSB_PRODUCT=\"Pico\"" -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=1 -DLWIP_IPV6=0 -DLWIP_IPV4=1 -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1 "-DARDUINO_VARIANT=\"rpipico\"" -DTARGET_RP2040 -DPICO_FLASH_SIZE_BYTES=2097152 -march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections -fno-exceptions -DARM_MATH_CM0_FAMILY -DARM_MATH_CM0_PLUS -MMD "-iprefixX:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/" "@X:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/lib/platform_inc.txt" "-IX:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/include" -fno-rtti -std=gnu++17 -g -pipe -DF_CPU=133000000L -DARDUINO=10819 -DARDUINO_RASPBERRY_PI_PICO "-DBOARD_NAME=\"RASPBERRY_PI_PICO\"" -DARDUINO_ARCH_RP2040 -Os -DWIFICC=CYW43_COUNTRY_WORLDWIDE "-IX:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0\\cores\\rp2040" "-IX:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0\\variants\\rpipico" "-IX:\\sketchbook\\libraries\\RadioLib\\src" "-IX:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0\\libraries\\SPI\\src" "-IX:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0\\libraries\\EEPROM\\src" "X:\\sketchbook\\libraries\\RadioLib\\src\\protocols\\LoRaWAN\\LoRaWANBands.cpp" -o "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\LoRaWAN\\LoRaWANBands.cpp.o"
X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN\LoRaWAN.cpp: In member function 'void LoRaWANNode::performCSMA()':
X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN\LoRaWAN.cpp:2098:36: error: no matching function for call to 'LoRaWANNode::setupChannels()'
 2098 |                 this->setupChannels();
      |                 ~~~~~~~~~~~~~~~~~~~^~
X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN\LoRaWAN.cpp:1302:9: note: candidate: 'int16_t LoRaWANNode::setupChannels(uint8_t*)'
 1302 | int16_t LoRaWANNode::setupChannels(uint8_t* cfList) {
      |         ^~~~~~~~~~~
X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN\LoRaWAN.cpp:1302:9: note:   candidate expects 1 argument, 0 provided
X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN\LoRaWAN.cpp:2110:40: error: no matching function for call to 'LoRaWANNode::setupChannels()'
 2110 |                     this->setupChannels();
      |                     ~~~~~~~~~~~~~~~~~~~^~
X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN\LoRaWAN.cpp:1302:9: note: candidate: 'int16_t LoRaWANNode::setupChannels(uint8_t*)'
 1302 | int16_t LoRaWANNode::setupChannels(uint8_t* cfList) {
      |         ^~~~~~~~~~~
X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN\LoRaWAN.cpp:1302:9: note:   candidate expects 1 argument, 0 provided
Mehrere Bibliotheken wurden für "RadioLib.h" gefunden
 Benutzt: X:\sketchbook\libraries\RadioLib
 Nicht benutzt: X:\sketchbook\libraries\RadioLib_bkp
Bibliothek RadioLib in Version 6.2.0 im Ordner: X:\sketchbook\libraries\RadioLib  wird verwendet
Bibliothek SPI in Version 1.0 im Ordner: X:\arduino\portable\packages\rp2040\hardware\rp2040\3.6.0\libraries\SPI  wird verwendet
Bibliothek EEPROM in Version 1.0 im Ordner: X:\arduino\portable\packages\rp2040\hardware\rp2040\3.6.0\libraries\EEPROM  wird verwendet
exit status 1
Fehler beim Kompilieren für das Board Raspberry Pi Pico.

Maybe you have an idea?

Thanks a lot,
Nico

@StevenCellist
Copy link
Collaborator Author

Hi Nico,

I had to hotfix that one, it's on the last commit now. Hopefully that'll solve it :)

@nmaas87
Copy link
Contributor

nmaas87 commented Nov 3, 2023

Hey Steven,
thanks a lot, yes that did it, however I got some new issues.
Does not yet successfully compile, but its close 👍🏻

"X:\\arduino\\portable\\packages\\rp2040\\tools\\pqt-gcc\\2.1.0-a-d3d2e6b/bin/arm-none-eabi-gcc" -Werror=return-type -Wno-psabi -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSBD_PID=0x000a -DUSBD_VID=0x2e8a -DUSBD_MAX_POWER_MA=250 "-DUSB_MANUFACTURER=\"Raspberry Pi\"" "-DUSB_PRODUCT=\"Pico\"" -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=1 -DLWIP_IPV6=0 -DLWIP_IPV4=1 -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1 "-DARDUINO_VARIANT=\"rpipico\"" -DTARGET_RP2040 -DPICO_FLASH_SIZE_BYTES=2097152 -march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections -fno-exceptions -DARM_MATH_CM0_FAMILY -DARM_MATH_CM0_PLUS -Os -u _printf_float -u _scanf_float -c "X:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/boot2/boot2_w25q080_2_padded_checksum.S" "-IX:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/pico-sdk/src/rp2040/hardware_regs/include/" "-IX:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/pico-sdk/src/common/pico_binary_info/include" -o "X:\\arduino\\build/boot2.o"
"X:\\arduino\\portable\\packages\\rp2040\\tools\\pqt-gcc\\2.1.0-a-d3d2e6b/bin/arm-none-eabi-g++" "-LX:\\arduino\\build" -Werror=return-type -Wno-psabi -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSBD_PID=0x000a -DUSBD_VID=0x2e8a -DUSBD_MAX_POWER_MA=250 "-DUSB_MANUFACTURER=\"Raspberry Pi\"" "-DUSB_PRODUCT=\"Pico\"" -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=1 -DLWIP_IPV6=0 -DLWIP_IPV4=1 -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1 "-DARDUINO_VARIANT=\"rpipico\"" -DTARGET_RP2040 -DPICO_FLASH_SIZE_BYTES=2097152 -march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections -fno-exceptions -DARM_MATH_CM0_FAMILY -DARM_MATH_CM0_PLUS -Os -u _printf_float -u _scanf_float "@X:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/lib/platform_wrap.txt" -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common "-Wl,--script=X:\\arduino\\build/memmap_default.ld" "-Wl,-Map,X:\\arduino\\build/LoRaWAN_End_Device.ino.map" -o "X:\\arduino\\build/LoRaWAN_End_Device.ino.elf" -Wl,--no-warn-rwx-segments -Wl,--start-group "X:\\arduino\\build\\sketch\\LoRaWAN_End_Device.ino.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\ArduinoHal.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\Hal.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\Module.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\CC1101\\CC1101.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\LLCC68\\LLCC68.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\RF69\\RF69.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX1231\\SX1231.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX126x\\STM32WLx.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX126x\\STM32WLx_Module.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX126x\\SX1261.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX126x\\SX1262.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX126x\\SX1268.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX126x\\SX126x.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX127x\\SX1272.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX127x\\SX1273.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX127x\\SX1276.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX127x\\SX1277.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX127x\\SX1278.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX127x\\SX1279.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX127x\\SX127x.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX128x\\SX1280.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX128x\\SX1281.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX128x\\SX1282.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\SX128x\\SX128x.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\Si443x\\Si4430.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\Si443x\\Si4431.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\Si443x\\Si4432.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\Si443x\\Si443x.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\modules\\nRF24\\nRF24.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\AFSK\\AFSK.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\APRS\\APRS.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\AX25\\AX25.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\BellModem\\BellModem.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\ExternalRadio\\ExternalRadio.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\FSK4\\FSK4.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\Hellschreiber\\Hellschreiber.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\LoRaWAN\\LoRaWAN.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\LoRaWAN\\LoRaWANBands.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\Morse\\Morse.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\Pager\\Pager.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\PhysicalLayer\\PhysicalLayer.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\Print\\ITA2String.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\Print\\Print.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\RTTY\\RTTY.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\protocols\\SSTV\\SSTV.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\utils\\CRC.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\utils\\Cryptography.cpp.o" "X:\\arduino\\build\\libraries\\RadioLib\\utils\\FEC.cpp.o" "X:\\arduino\\build\\libraries\\SPI\\SPI.a" "X:\\arduino\\build\\libraries\\EEPROM\\EEPROM.a" "X:\\arduino\\build/core\\core.a" "X:\\arduino\\build/boot2.o" "X:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/lib/ota.o" "X:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/lib/libpico.a" "X:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/lib/libpicow-noipv6-nobtc-noble.a" "X:\\arduino\\portable\\packages\\rp2040\\hardware\\rp2040\\3.6.0/lib/libbearssl.a" -lm -lc -lstdc++ -lc -Wl,--end-group
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o: in function `_Z19getDownlinkDataRatehhhhh':
X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:5: multiple definition of `_Z19getDownlinkDataRatehhhhh'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:5: first defined here
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:407: multiple definition of `IN865'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:407: first defined here
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:365: multiple definition of `KR920'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:365: first defined here
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:323: multiple definition of `AS923'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:323: first defined here
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:267: multiple definition of `CN500'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:267: first defined here
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:204: multiple definition of `AU915'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:204: first defined here
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:162: multiple definition of `EU433'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:162: first defined here
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:120: multiple definition of `CN780'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:120: first defined here
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:57: multiple definition of `US915'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:57: first defined here
x:/arduino/portable/packages/rp2040/tools/pqt-gcc/2.1.0-a-d3d2e6b/bin/../lib/gcc/arm-none-eabi/12.3.0/../../../../arm-none-eabi/bin/ld.exe: X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWANBands.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:15: multiple definition of `EU868'; X:\arduino\build\libraries\RadioLib\protocols\LoRaWAN\LoRaWAN.cpp.o:X:\sketchbook\libraries\RadioLib\src\protocols\LoRaWAN/LoRaWANBands.cpp:15: first defined here
collect2.exe: error: ld returned 1 exit status
Bibliothek RadioLib in Version 6.2.0 im Ordner: X:\sketchbook\libraries\RadioLib  wird verwendet
Bibliothek SPI in Version 1.0 im Ordner: X:\arduino\portable\packages\rp2040\hardware\rp2040\3.6.0\libraries\SPI  wird verwendet
Bibliothek EEPROM in Version 1.0 im Ordner: X:\arduino\portable\packages\rp2040\hardware\rp2040\3.6.0\libraries\EEPROM  wird verwendet
exit status 1
Fehler beim Kompilieren für das Board Raspberry Pi Pico.

@StevenCellist
Copy link
Collaborator Author

Thank you for checking it out so fast!
Honestly I can't read that error decently and I don't know where "_Z19getDownlinkDataRatehhhhh" would come from..
You're welcome to figure it out... :) my energy is spent. Please report back if you can find it so I can fix it.

@nmaas87
Copy link
Contributor

nmaas87 commented Nov 3, 2023

Thanks Steven :)
Yeah I think there seems to be some error in regards to some circular dependency.
It looks like you include the LoRaWANBands.cpp in the LoRaWAN.cpp ( https://github.com/StevenCellist/RadioLib/blob/60f50e0a04992c1942ca5b18c51f5a449eb4dbbe/src/protocols/LoRaWAN/LoRaWAN.cpp#L2 ) and this leads to issues. However, without that include, the function getDownlinkDataRate is missing.
At least it does look like this error is not only present on my system, the CI checks here in this PR (see above and below, CI / arduino:avr:uno) also show the same issue - so something must have slipped there. If I see something I am going to scream, but I am not seeing it right now :)

@nmaas87
Copy link
Contributor

nmaas87 commented Nov 3, 2023

I could get it to compile if I change LoRaWAN.cpp by removing the LoRaWANBands.cpp include and adding the getDownlinkDataRate there (removing it from LoRaWANBands.cpp). The resulting code successfully joins the LoRaWAN Gateway, however, if I remove node.wipe() and the OTAA functions and try to do a node.restore(); after a successful OTAA - I still get an

[SX1262] Initializing ... success init!
[LoRaWAN] Resuming previous session ... failed, code -1101

So that error seems to be still present, as in #864

#include "LoRaWAN.h"
//#include "LoRaWANBands.cpp"
#include <string.h>

#if !defined(RADIOLIB_EXCLUDE_LORAWAN)

#if defined(RADIOLIB_EEPROM_UNSUPPORTED)
  #warning "Persistent storage not supported!"
#endif

uint8_t getDownlinkDataRate(uint8_t uplink, uint8_t offset, uint8_t base, uint8_t min, uint8_t max) {
  int8_t dr = uplink - offset + base;
  if(dr < min) {
    dr = min;
  } else if (dr > max) {
    dr = max;
  }
  return(dr);
}

// flag to indicate whether there was some action during Rx mode (timeout or downlink)
static volatile bool downlinkAction = false;

// interrupt service routine to handle downlinks automatically
#if defined(ESP8266) || defined(ESP32)
  IRAM_ATTR
#endif
static void LoRaWANNodeOnDownlinkAction(void) {
  downlinkAction = true;
}

@StevenCellist
Copy link
Collaborator Author

Ah, yeah, I had to add that at some point for my local branch. Didn't throw errors for me, but it's fixed now.

The node.wipe() is officially a user error. The problem is that when you go to upload the code that does not wipe, at some point during the build&upload, your device is triggered to reset and the code that's still on there runs for a second or two. So if wipe() is the first thing you do, that'll still run before the new code is uploaded. Best practice is to include a 10 second delay before the wipe & join, such that on the next upload, that won't get triggered before the new code is on there.

@nmaas87
Copy link
Contributor

nmaas87 commented Nov 4, 2023

This looks better, however, you still need to remove the getDownlinkDataRate function from the LoRaWANBands.cpp, otherwise it will not compile.

The node.wipe(); explanation makes sense and I tried to do the run, e.g.

delay(10000);
node.wipe();
node.beginOTAA(...);

and as before, this worked well -> OTAA works out, RP2040/SX1262 starts to uplink messages.

Then I did following

delay(10000);
//node.wipe();
//node.beginOTAA(...);
node.restore(...);

But this did fail:

[LoRaWAN] Resuming previous session ... magic id: 0
failed, code -1101

magic id: 0 is probably all wrong.
I am using the current Arduino-Pico Framework with an RP2040 ( https://github.com/earlephilhower/arduino-pico / more precisely I am using a RAK11300 which includes a RP2040 and a SX1262 hardwired on one module - however, I am using the "Raspberry Pi Pico" generic definition and just rewrite the SPI1 definitions to connect to the right GPIO dynamically by means of the setSPI functions: https://arduino-pico.readthedocs.io/en/latest/spi.html - which works out great :))

Could it be that there is an issue with recognizing this as an RP2040 board or - which is probably the root cause - could it be that the "save" logic for the OTAA data does not work for RP2040s? Do we have any way to test that? Because I think something is off here - and if its able to join successfully on activation each time but not on restore - it could be an issue in that direction.

In addition to the potential "save OTAA" issue I also saw another user with an ESP32 also having issues restoring an OTAA session with their SX1262 ( #858 ) - maybe that could also point something in the SX1262 handling(?)

Thanks :)

@nmaas87
Copy link
Contributor

nmaas87 commented Nov 4, 2023

Also as additional info, a complete power-on, wipe and OTAA with the first sent uplink as debug output, maybe that shows something?

[LoRaWAN] Attempting over-the-air activation ... CMDR	1D	8	E7	
SI	0	0	
SO	A2	18	
CMDR	C0	
SI	0	
SO	22	
CMDW	95	
SI	4	7	0	1	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	8E	
SI	10	4	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	8	E7	
SI	18	
SO	A2	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	7	40	
SI	34	44	
SO	A2	A2	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	7	36	
SI	0	0	
SO	A2	D	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	7	36	
SI	D	
SO	A2	
CMDW	8C	
SI	0	8	0	FF	1	0	
SO	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	

Channel frequency UL = 868.099976 MHz
CMDW	98	
SI	D7	DB	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	86	
SI	36	41	99	80	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
DR 72: LORA (SF: 10, BW: 125.000000, CR: 5)
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8B	
SI	A	4	3	0	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8B	
SI	A	4	3	0	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8B	
SI	A	4	1	0	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	80	
SI	0	
SO	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
Timeout in 556032 us
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	7	36	
SI	0	0	
SO	A2	D	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	7	36	
SI	D	
SO	A2	
CMDW	8C	
SI	0	8	0	17	1	0	
SO	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	8	
SI	2	1	0	1	0	0	0	0	
SO	A2	A2	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	8F	
SI	0	0	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	E	0	
SI	0	E8	60	84	51	53	63	78	23	25	78	63	53	51	84	60	E6	1	0	3B	9B	8C	79	
SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	2	
SI	43	FF	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	8	89	
SI	0	0	
SO	A2	4	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	8	89	
SI	4	
SO	A2	
CMDW	83	
SI	0	0	0	
SO	A2	A2	A2	
CMDR	C0	
SI	0	
SO	62	
CMDW	2	
SI	43	FF	
SO	AC	AC	
CMDR	C0	
SI	0	
SO	2C	
CMDW	80	
SI	0	
SO	AC	
CMDR	C0	
SI	0	
SO	22	
Join-request sent <-- Rx Delay start

Channel frequency DL = 868.099976 MHz
CMDW	98	
SI	D7	DB	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	86	
SI	36	41	99	80	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
DR 72: LORA (SF: 10, BW: 125.000000, CR: 5)
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8B	
SI	A	4	1	0	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8B	
SI	A	4	1	0	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8B	
SI	A	4	1	0	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	7	36	
SI	0	0	
SO	A2	D	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	7	36	
SI	9	
SO	A2	
CMDW	8C	
SI	0	8	0	FF	1	1	
SO	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8	
SI	2	62	2	2	0	0	0	0	
SO	A2	A2	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	8F	
SI	0	0	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	2	
SI	43	FF	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	7	36	
SI	0	0	
SO	A2	9	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	7	36	
SI	9	
SO	A2	
CMDW	8C	
SI	0	8	0	FF	1	1	
SO	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	82	
SI	0	38	B6	
SO	A2	A2	A2	
Opening Rx1 window (226848 us timeout)... <-- Rx Delay end 
closing
CMDR	12	
SI	0	0	0	
SO	D2	0	0	
CMDR	C0	
SI	0	
SO	52	
CMDR	12	
SI	0	0	0	
SO	D2	0	0	
CMDR	C0	
SI	0	
SO	52	
CMDW	80	
SI	0	
SO	A4	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	7	36	
SI	0	0	
SO	A2	9	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	7	36	
SI	D	
SO	A2	
CMDW	8C	
SI	0	8	0	FF	1	0	
SO	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	13	
SI	0	0	0	
SO	A2	21	0	
CMDR	C0	
SI	0	
SO	22	
CMDR	C0	
SI	0	
SO	22	
CMDR	12	
SI	0	0	0	
SO	A2	0	2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	13	
SI	0	0	0	
SO	A2	21	0	
CMDR	C0	
SI	0	
SO	22	
CMDR	1E	0	
SI	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	0	
SO	A2	20	FA	B4	AD	DD	A8	C6	A4	B5	7	19	C3	28	E7	FA	0	3E	C9	18	18	DC	76	12	67	DC	12	F	29	D	11	2D	9F	22	
CMDR	C0	
SI	0	
SO	22	
CMDW	8F	
SI	0	0	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	2	
SI	43	FF	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
joinAcceptMsg:
0000000 20 04 00 00 00 00 00 60 16 25 00 80 01 18 4f 84 |  ......`....O.
0000010 e8 56 84 b8 5e 84 88 66 84 58 6e 84 00 db a4 f1 | .V..^..f.Xn.....
0000020 b8                                              | .                 
JoinNoncePrev: 0, JoinNonce: 4
LoRaWAN revision: 1.1
Channel UL/DL 0 frequency = 868.099976 MHz
Channel UL/DL 1 frequency = 868.299988 MHz
Channel UL/DL 2 frequency = 868.500000 MHz
Channel UL/DL 3 frequency = 867.099976 MHz
Channel UL/DL 4 frequency = 867.299988 MHz
Channel UL/DL 5 frequency = 867.500000 MHz
Channel UL/DL 6 frequency = 867.700012 MHz
Channel UL/DL 7 frequency = 867.900024 MHz
success oota!
[LoRaWAN] Sending uplink packet ... CMDR	1D	8	E2	
SI	0	0	
SO	A2	C	
CMDW	D	8	E2	
SI	C	
SO	A2	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	C	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	20	
CMDW	D	8	E5	
SI	20	
SO	A2	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	20	
CMDW	82	
SI	FF	FF	FF	
SO	A2	A2	A2	
CMDR	1D	8	19	
SI	0	0	
SO	D2	85	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	3A	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	A9	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	64	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	23	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	49	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	E5	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	79	
CMDR	C0	
SI	0	
SO	52	
CMDW	80	
SI	0	
SO	D2	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	C	
CMDW	D	8	E2	
SI	D	
SO	A2	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	D	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	20	
CMDW	D	8	E5	
SI	21	
SO	A2	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	21	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	D	
CMDW	D	8	E2	
SI	C	
SO	A2	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	C	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	21	
CMDW	D	8	E5	
SI	20	
SO	A2	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	20	
CMDW	82	
SI	FF	FF	FF	
SO	A2	A2	A2	
CMDR	1D	8	19	
SI	0	0	
SO	D2	55	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	5A	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	7E	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	3D	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	34	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	6D	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	52	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	54	
CMDR	C0	
SI	0	
SO	52	
CMDW	80	
SI	0	
SO	D2	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	C	
CMDW	D	8	E2	
SI	D	
SO	A2	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	D	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	20	
CMDW	D	8	E5	
SI	21	
SO	A2	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	21	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	D	
CMDW	D	8	E2	
SI	C	
SO	A2	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	C	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	21	
CMDW	D	8	E5	
SI	20	
SO	A2	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	20	
CMDW	82	
SI	FF	FF	FF	
SO	A2	A2	A2	
CMDR	1D	8	19	
SI	0	0	
SO	D2	DD	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	45	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	5A	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	D9	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	D2	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	A5	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	6C	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	8D	
CMDR	C0	
SI	0	
SO	52	
CMDW	80	
SI	0	
SO	D2	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	C	
CMDW	D	8	E2	
SI	D	
SO	A2	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	D	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	20	
CMDW	D	8	E5	
SI	21	
SO	A2	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	21	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	D	
CMDW	D	8	E2	
SI	C	
SO	A2	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	C	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	21	
CMDW	D	8	E5	
SI	20	
SO	A2	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	20	
CMDW	82	
SI	FF	FF	FF	
SO	A2	A2	A2	
CMDR	1D	8	19	
SI	0	0	
SO	D2	1A	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	19	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	60	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	A2	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	AA	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	A2	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	B1	
CMDR	C0	
SI	0	
SO	52	
CMDR	1D	8	19	
SI	0	0	
SO	D2	DB	
CMDR	C0	
SI	0	
SO	52	
CMDW	80	
SI	0	
SO	D2	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	C	
CMDW	D	8	E2	
SI	D	
SO	A2	
CMDR	1D	8	E2	
SI	0	0	
SO	A2	D	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	20	
CMDW	D	8	E5	
SI	21	
SO	A2	
CMDR	1D	8	E5	
SI	0	0	
SO	A2	21	

Channel frequency UL = 867.700012 MHz
CMDW	98	
SI	D7	DB	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	86	
SI	36	3B	33	40	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
DR 72: LORA (SF: 10, BW: 125.000000, CR: 5)
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8B	
SI	A	4	1	0	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8B	
SI	A	4	1	0	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	8B	
SI	A	4	1	0	
SO	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
Uplink MAC payload (1 commands):
0000000 0b 01                                           | ..                
uplinkMsg pre-MIC:
0000000 20 20 20 20 20 20 20 20 20 20 20 20 00 0f 00 00 |             ....
0000010 40 60 16 25 00 82 01 00 9b 69 0a 3a 52 74 c2 45 | @`.....i.:Rt.E
0000020 0a c5 42 15 6e 72 e3 b0 05 db e2 a8 c1 be       | ..B.nr........    
uplinkMsg:
0000000 49 00 00 00 00 00 60 16 25 00 01 00 00 00 00 1a | I.....`.......
0000010 40 60 16 25 00 82 01 00 9b 69 0a 3a 52 74 c2 45 | @`.....i.:Rt.E
0000020 0a c5 42 15 6e 72 e3 b0 05 db 84 cb d7 47       | ..B.nr.......G    
CMDW	80	
SI	0	
SO	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
Timeout in 678912 us
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	7	36	
SI	0	0	
SO	A2	D	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	7	36	
SI	D	
SO	A2	
CMDW	8C	
SI	0	8	0	1E	1	0	
SO	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	8	
SI	2	1	0	1	0	0	0	0	
SO	A2	A2	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	8F	
SI	0	0	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	E	0	
SI	40	60	16	25	0	82	1	0	9B	69	A	3A	52	74	C2	45	A	C5	42	15	6E	72	E3	B0	5	DB	84	CB	D7	47	
SO	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDW	2	
SI	43	FF	
SO	A2	A2	
CMDR	C0	
SI	0	
SO	22	
CMDR	1D	8	89	
SI	0	0	
SO	A2	4	
CMDR	C0	
SI	0	
SO	22	
CMDR	11	
SI	0	0	
SO	A2	1	
CMDR	C0	
SI	0	
SO	22	
CMDW	D	8	89	
SI	4	
SO	A2	
CMDW	83	
SI	0	0	0	
SO	A2	A2	A2	
CMDR	C0	
SI	0	
SO	62	
CMDW	2	
SI	43	FF	
SO	AC	AC	
CMDR	C0	
SI	0	
SO	2C	
CMDW	80	
SI	0	
SO	AC	
CMDR	C0	
SI	0	
SO	22	
Uplink sent <-- Rx Delay start
success!

@StevenCellist
Copy link
Collaborator Author

I don't have any of that hardware, so I can't say things for sure. But if it didn't have EEPROM, I'd expect the .wipe() and .restore() and .save() functions could not even be in the compiled firmware or otherwise would have thrown errors. So I expect there is a mistake then somewhere, but I'm off for the day for a CD recording. I hope to get back to this by Tuesday unless someone else has a go at it first and can find the mistakes. The problem cannot be in the SX126x, as the restore function just looks at the nvm. It must be in the main logic (or something with the wipe or so).

@HeadBoffin
Copy link
Collaborator

@nmaas87, if you can give Team @StevenCellist a bit of time to catch up with RL, I can furnish him with access to a Pico with an SX1262 (and SX1276) for debugging.

In the meanwhile, can you look at what's different about your setup from the two setups that compile for the CI so we aren't chasing our tails on something unique.

I can swap my radio test environment to use US so we can also verify that sometime middle of next week and then it can be tested, so anyone else with a burning ambition to run this PR will need to be patient!

@nmaas87
Copy link
Contributor

nmaas87 commented Nov 4, 2023

Thanks a lot for your help and best of luck for your recordings! :)

I found the issue, the software EEPROM of the RP2040 was not handled correctly, please see this PR for the fix: #868

Also, please remove the duplicated getDownlinkDataRate function from the LoRaWANBands.cpp, otherwise it will not compile.

@HeadBoffin
Copy link
Collaborator

Also, please remove the duplicated getDownlinkDataRate function from the LoRaWANBands.cpp, otherwise it will not compile.

That was already done, can you update and confirm

@nmaas87
Copy link
Contributor

nmaas87 commented Nov 4, 2023

Hey @HeadBoffin - sorry for skipping your comment, I really did not see it.

As written, I have found the issue with the "not restoring a session" - it was due to a problem with the EEPROM handling and have already opened a fix/PR #868 .

The error in my compiler aligns with the failed CI checks here (CI / arduino:avr:uno (pull_request)) and is due to these lines ( https://github.com/StevenCellist/RadioLib/blob/ccb28f3b7b554c1f59cdf85f3c85ca22e0947451/src/protocols/LoRaWAN/LoRaWANBands.cpp#L5-L13 ) being a duplicate from his last fix, so they need to be removed. Then it will just compile fine 👍🏻

Thanks and cheers, seems like the RAK11300 is working fine now - thanks a lot guys, just need to see if I can figure out how to better power the Antenna amplifier / only power it on RX and TX - but maybe setRfSwitchPins() ( https://jgromes.github.io/RadioLib/class_module.html#a7d3adea64acab11c47c804afc74bd4f3 ) is a good idea here.

@StevenCellist
Copy link
Collaborator Author

Did some more research, and I think I start to understand more what is going on.
The preamble is 8 + 4.25 symbols long. The header is the PHDR from the documents (not the MHDR), and from this link it appears to total to 20 bits. This matches the term of 20*ih in the getTimeOnAir function (where ih=1 disables this header).

So, the total RxTimeout value should equal 12.25 symbols + 20 bits, I assume.

Then, the question is how I can convert from 20 bits to a number of symbols. From SX126x.cpp (nPreCodedSymbols), this conversion looks to be (20 + 4SF - 1) / 4SF. As this is an integer equation, this would always be just 1 symbol, which I don't really believe...

@jgromes
Copy link
Owner

jgromes commented Nov 6, 2023

@StevenCellist here's the relevant section from the SX1276 datasheet:
Screenshot_71

Plugging in the known values (PL = 0, CRC = 0, IH = 0) I get

N = 8 + max(ceil( (8*0 - 4*SF + 28 + 16*0 - 20*0)/(4*SF - 8*DE) )*(CR+4), 0)

that simplifies to

N = 8 + max(ceil( (28 - 4*SF)/(4*SF - 8*DE) )*(CR+4), 0)

Now notice how the part 28 - 4*SF can never be positive, because the lowest SF applicable is 7. So the entire max() function will boil down to max(0 or less, 0), which is always 0 and therefore, there are always 8 symbols in the header.

Curiously, adding the 12.25 preamble symbols, we get 20.25 symbols, which is the value you seem to have arrived at using trial and error. I'm not 100% certain the above calculation actually checks out, but I'm willing to call it good enough ;)

@StevenCellist
Copy link
Collaborator Author

That's actually pretty hilarious!! I think I know & understand enough to make this look and function decent including the scanGuard, thank you very much :)
Will send in a new commit tomorrow incorporating all the feedback (and a little bit more).
I'll try my best to set up the necessary variables for you to plug in to the properties/logging struct. If you can integrate that right after, it'll provide a great update!

@StevenCellist
Copy link
Collaborator Author

Delaying a day, getting some more tests done

@StevenCellist
Copy link
Collaborator Author

New commit with more & better examples, improved SX127x timeout, created a unified sendReceive() to prevent the typical user from not calling downlink, re-integrate FSK logic that was lost, some bugfixes regarding ADR, setting datarate and saving/restoring channels. Also added some new functions for the users and fixed the problem with not being able to send an uplink the first 6 seconds after joining/restoring.
It would be highly appreciated if someone's willing to test some of the examples or some of the new functions, before this is merged.

@nmaas87
Copy link
Contributor

nmaas87 commented Nov 8, 2023

Hey @StevenCellist - thanks for the awesome work. Using the RAK11300 (RP2040+SX1262) I just tested LoRaWAN_End_Device Example and this looks good, as well as the persistent one - however persistent had some copy and paste doubeling here:
https://github.com/StevenCellist/RadioLib/blob/3df866e23dfa52031b5a8f10dbc95cc45507a149/examples/LoRaWAN/LoRaWAN_End_Device_persistent/LoRaWAN_End_Device_persistent.ino#L92-L98
I could receive up- and downlinks and restore the session - I guess the saveSession is meant to save Frame Counter etc?

I also tried the LoRaWAN_End_Device_Reference - it looks quite good, however (this one I don't understand) - it always receives a downlink with data in it. Looking at my Gateway and Chirpstack - they also send a downlink. The funny thing however is.. I did never enter anything into the downlink queue. So I am not really sure how that little bugger asks for the downlink and gets... whatever sent down to it - because it is not a confirmed uplink :).

Other than this curiosity of mine - its looking quite good 👍🏻

@StevenCellist
Copy link
Collaborator Author

@nmaas87 thanks for testing those all! Once I start working on it for too long it becomes a mess of what is normal and what may be a problem.. couldn't see it clear anymore.

Gotcha on the copy-paste error. The saveSession() indeed stores everything that has changed since the last saveSession(), such as frame counters and other things that may have changed due to MAC commands (ADR setup, delays, ..).

The reference does accidentally send confirmed uplinks all over the place - the / should be a %; the current division always evaluates to 0 for the first 64 uplinks.. oops.
Will wait if anything else pops up, to prevent too many commits..

@StevenCellist
Copy link
Collaborator Author

@jgromes small heads-up that I'm waiting for seal of approval from @HeadBoffin as he has some equipment to test US915 as well. After his feedback is in I'll add the last commit with the fixes mentioned above :)

@HeadBoffin
Copy link
Collaborator

I've exercised the changes for both AU915 & US915 in my secret underground bunker to shield the inhabitants of the UK from any illegal radio waves and found the code to be beta worthy.

Because of all the little bitty corner cases that exist, as well as implementation habits of varying developers, I'd mark this as not suitable for deployment until we've all had a run at it for a few weeks with some devices that can be left alone as well as a few that are abused (power cycled, maybe hammered on downlinks (via private LNS) etc.

Copy link
Owner

@jgromes jgromes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@StevenCellist I reviewed the changes and left three minor comments. Other than that, I'll try to do some testing myself.

src/modules/SX127x/SX127x.h Outdated Show resolved Hide resolved
src/protocols/LoRaWAN/LoRaWAN.cpp Outdated Show resolved Hide resolved
src/TypeDef.h Show resolved Hide resolved
@jgromes
Copy link
Owner

jgromes commented Nov 11, 2023

@HeadBoffin

I'd mark this as not suitable for deployment until we've all had a run at it for a few weeks

We can keep this open for a bit longer, though I have to admit I'm a bit in the "move fast and break stuff" camp. Unfortunately, for me release (and fast subsequent patches) are the only practical way to see how this behaves in variety of environments. The fact is, not many people are willing (or even know they have the option) to try out patches from PRs for a project of this comparatively small scale.

@HeadBoffin
Copy link
Collaborator

I'd mark this as not suitable for deployment until we've all had a run at it for a few weeks

We can keep this open for a bit longer, though I have to admit I'm a bit in the "move fast and break stuff" camp. Unfortunately, for me release (and fast subsequent patches) are the only practical way to see how this behaves in variety of environments.

I'm suggesting that it is clearly marked as beta and not yet proven for deployment aka production - so warning peeps not to go and make a pile of devices and put them places that are awkward to get to lest a showstopping issue arises. I'm not saying don't merge, just that to my mind it should be described as is - exercised but not yet run for more than a few hours so far.

I'm in the process of setting up some devices to leave to run to test this plus some new sensors and a solar charger board, so it won't take long to build confidence in long term use.

@StevenCellist
Copy link
Collaborator Author

@jgromes if the one comment regarding the SX127x.h interface is something you can solve, I'd say you merge it (and probably add a warning on the main README that LoRaWAN support is in beta). Looking forward to having this integrated 🤩

@jgromes jgromes merged commit 8225810 into jgromes:master Nov 12, 2023
29 checks passed
@jgromes
Copy link
Owner

jgromes commented Nov 12, 2023

... and its done! Huge thanks @StevenCellist and @HeadBoffin

@StevenCellist StevenCellist deleted the bands_adr_mac branch November 24, 2023 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Problems with LoRaWAN / RAK11300
4 participants