How to Set Up Point-to-Point Communication Between Two LoRa-E5 Mini Modules?

Yes when I saw our settings were different I tried with yours: it doesn’t change anything unfortunately.

Have you tried simplifying the code to the minimum necessary for radio.begin()?

Yes I’ve tried to, doesn’t do anything, it really gets stuck at radio.begin() in findChip method of the module at the first reset() function call.

It doesn’t find the “rstPin” in the register so it just gets stuck there.

Maybe the registers got wiped and don’t contain any information ? (Is it even possible ?) And it’d be weird that it happened on both of my boards.

This is a screenshot of STLink. Please compare it.


Same except for those

I ticked them back and retried with a sketch, same…

bool SX126x::findChip(const char* verStr) {
  uint8_t i = 0;
  bool flagFound = false;
  while((i < 10) && !flagFound) {
    // reset the module
    reset();    // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<---------

    // read the version string
    char version[16];
    this->mod->SPIreadRegisterBurst(RADIOLIB_SX126X_REG_VERSION_STRING, 16, reinterpret_cast<uint8_t*>(version));

    // check version register
    if(strncmp(verStr, version, 6) == 0) {
      RADIOLIB_DEBUG_BASIC_PRINTLN("Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:");
      RADIOLIB_DEBUG_BASIC_HEXDUMP(reinterpret_cast<uint8_t*>(version), 16, RADIOLIB_SX126X_REG_VERSION_STRING);
      RADIOLIB_DEBUG_BASIC_PRINTLN();
      flagFound = true;
    } else {
      #if RADIOLIB_DEBUG_BASIC
        RADIOLIB_DEBUG_BASIC_PRINTLN("SX126x not found! (%d of 10 tries) RADIOLIB_SX126X_REG_VERSION_STRING:", i + 1);
        RADIOLIB_DEBUG_BASIC_HEXDUMP(reinterpret_cast<uint8_t*>(version), 16, RADIOLIB_SX126X_REG_VERSION_STRING);
        RADIOLIB_DEBUG_BASIC_PRINTLN("Expected string: %s", verStr);
      #endif
      this->mod->hal->delay(10);
      i++;
    }
  }

  return(flagFound);
}

Doesn’t this reset() function return?
Do you know where the reset() function is defined?

It never returns, it’s defined inside the same class (SX126x.cpp)

int16_t SX126x::reset(bool verify)
{
  // run the reset sequence
  RADIOLIB_DEBUG_BASIC_PRINTLN("RESET call");
  this->mod->hal->pinMode(this->mod->getRst(), this->mod->hal->GpioModeOutput);
  this->mod->hal->digitalWrite(this->mod->getRst(), this->mod->hal->GpioLevelLow);
  this->mod->hal->delay(1);
  this->mod->hal->digitalWrite(this->mod->getRst(), this->mod->hal->GpioLevelHigh);
  RADIOLIB_DEBUG_BASIC_PRINTLN("RESET pins");

  // return immediately when verification is disabled
  if (!verify)
  {
    return (RADIOLIB_ERR_NONE);
  }

  RADIOLIB_DEBUG_BASIC_PRINTLN("RESET verify true");

  // set mode to standby - SX126x often refuses first few commands after reset
  RadioLibTime_t start = this->mod->hal->millis();
  while (true)
  {
    RADIOLIB_DEBUG_BASIC_PRINTLN("RESET loop");
    // try to set mode to standby
    int16_t state = standby();
    if (state == RADIOLIB_ERR_NONE)
    {
      // standby command successful
      return (RADIOLIB_ERR_NONE);
    }

    RADIOLIB_DEBUG_BASIC_PRINTLN("RESET standby failed");

    // standby command failed, check timeout and try again
    if (this->mod->hal->millis() - start >= 1000)
    {
      RADIOLIB_DEBUG_BASIC_PRINTLN("RESET timeout");
      // timed out, possibly incorrect wiring
      return (state);
    }

    // wait a bit to not spam the module
    this->mod->hal->delay(10);
    RADIOLIB_DEBUG_BASIC_PRINTLN("RESET delay");
  }
  RADIOLIB_DEBUG_BASIC_PRINTLN("RESET end");
}

I added Serial.print() to SX126x.cpp for debugging purposes and ran it. Please compare your results with the serial monitor results. You should be able to see where it is hanging up.
You should be able to run it by uploading the attached hex file.
Oren_SX126x_PingPong.ino.zip (45.5 KB)

int16_t SX126x::reset(bool verify) {
  int16_t state;
  Serial.print("********  verify="); Serial.println(verify);
  Serial.println("// run the reset sequence");
  this->mod->hal->pinMode(this->mod->getRst(), this->mod->hal->GpioModeOutput);
  this->mod->hal->digitalWrite(this->mod->getRst(), this->mod->hal->GpioLevelLow);
  this->mod->hal->delay(1);
  this->mod->hal->digitalWrite(this->mod->getRst(), this->mod->hal->GpioLevelHigh);

  Serial.println("// return immediately when verification is disabled");
  if(!verify) {
	Serial.println("**** return verify"); Serial.println();  
    return(RADIOLIB_ERR_NONE);
  }

  Serial.println("// set mode to standby - SX126x often refuses first few commands after reset");
  RadioLibTime_t start = this->mod->hal->millis();
  while(true) {
    Serial.println("// try to set mode to standby");
//    int16_t state = standby();
	state = standby();
    if(state == RADIOLIB_ERR_NONE) {
      Serial.println("// standby command successful");
	  Serial.println("**** return state"); Serial.println();
      return(RADIOLIB_ERR_NONE);
    }

    Serial.println("// standby command failed, check timeout and try again");
    if(this->mod->hal->millis() - start >= 1000) {
      Serial.println("// timed out, possibly incorrect wiring");
	  Serial.println("**** return  timer"); Serial.println();
      return(state);
    }

    Serial.println("// wait a bit to not spam the module");
	Serial.println("while");
    this->mod->hal->delay(10);
  }
  Serial.println("**** return reset()");
  Serial.print("--------  "); Serial.println(state); Serial.println();
}


08:06:39.858 -> Master UID 535EE2F
08:06:39.858 -> ********  verify=1
08:06:39.858 -> // run the reset sequence
08:06:39.858 -> // return immediately when verification is disabled
08:06:39.858 -> // set mode to standby - SX126x often refuses first few commands after reset
08:06:39.858 -> // try to set mode to standby
08:06:39.858 -> // standby command failed, check timeout and try again
08:06:39.858 -> // wait a bit to not spam the module
08:06:39.858 -> while
08:06:39.890 -> // try to set mode to standby
08:06:39.890 -> // standby command successful
08:06:39.890 -> **** return state
08:06:39.890 -> 
08:06:39.890 -> ********  verify=1
08:06:39.890 -> // run the reset sequence
08:06:39.890 -> // return immediately when verification is disabled
08:06:39.890 -> // set mode to standby - SX126x often refuses first few commands after reset
08:06:39.890 -> // try to set mode to standby
08:06:39.890 -> // standby command failed, check timeout and try again
08:06:39.922 -> // wait a bit to not spam the module
08:06:39.922 -> while
08:06:39.922 -> // try to set mode to standby
08:06:39.922 -> // standby command successful
08:06:39.922 -> **** return state
08:06:39.922 -> 
08:06:39.954 -> radio.begin() success!
08:06:39.954 -> END of setup()

Here’s the debug output

14:11:10.286 -> Master UID 5F9F613
14:11:10.286 -> ********  verify=1
14:11:10.286 -> // run the reset sequence
14:11:10.321 -> // return immediately when verification is disabled
14:11:10.321 -> // set mode to standby - SX126x often refuses first few commands after reset
14:11:10.321 -> // try to set mode to standby

Since it seems that the standby() function cannot return, I added Serial.print() inside the standby() function. Please check which line it executes and stops at.

Oren_SX126x_PingPong.ino.zip (45.8 KB)

int16_t SX126x::standby() {
  Serial.print("    standby() standbyXOSC="); Serial.println(standbyXOSC);	
  return(SX126x::standby(this->standbyXOSC ? RADIOLIB_SX126X_STANDBY_XOSC : RADIOLIB_SX126X_STANDBY_RC));
}

int16_t SX126x::standby(uint8_t mode, bool wakeup) {
  Serial.print("    standby() mode="); Serial.print(mode); Serial.print("  wakeup="); Serial.println(wakeup);	
  Serial.println("    // set RF switch (if present)");
  this->mod->setRfSwitchState(Module::MODE_IDLE);

  if(wakeup) {
    Serial.println("    // pull NSS low to wake up");
    this->mod->hal->digitalWrite(this->mod->getCs(), this->mod->hal->GpioLevelLow);
  }
  uint8_t data[] = { mode };
  Serial.println("    SPIwriteStream RADIOLIB_SX126X_CMD_SET_STANDBY");
  return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_STANDBY, data, 1));
}

08:49:22.792 → Master UID 535EE2F
08:49:22.792 → ******** verify=1
08:49:22.792 → // run the reset sequence
08:49:22.792 → // return immediately when verification is disabled
08:49:22.792 → // set mode to standby - SX126x often refuses first few commands after reset
08:49:22.792 → // try to set mode to standby
08:49:22.792 → standby() standbyXOSC=0
08:49:22.792 → standby() mode=0 wakeup=1
08:49:22.792 → // set RF switch (if present)
08:49:22.792 → // pull NSS low to wake up
08:49:22.792 → SPIwriteStream RADIOLIB_SX126X_CMD_SET_STANDBY
08:49:22.824 → // standby command failed, check timeout and try again
08:49:22.824 → // wait a bit to not spam the module
08:49:22.824 → while
08:49:22.824 → // try to set mode to standby
08:49:22.824 → standby() standbyXOSC=0
08:49:22.824 → standby() mode=0 wakeup=1
08:49:22.824 → // set RF switch (if present)
08:49:22.824 → // pull NSS low to wake up
08:49:22.824 → SPIwriteStream RADIOLIB_SX126X_CMD_SET_STANDBY
08:49:22.857 → // standby command successful
08:49:22.857 → **** return state
08:49:22.857 →
08:49:22.857 → ******** verify=1
08:49:22.857 → // run the reset sequence
08:49:22.857 → // return immediately when verification is disabled
08:49:22.857 → // set mode to standby - SX126x often refuses first few commands after reset
08:49:22.857 → // try to set mode to standby
08:49:22.857 → standby() standbyXOSC=0
08:49:22.857 → standby() mode=0 wakeup=1
08:49:22.857 → // set RF switch (if present)
08:49:22.857 → // pull NSS low to wake up
08:49:22.889 → SPIwriteStream RADIOLIB_SX126X_CMD_SET_STANDBY
08:49:22.889 → // standby command failed, check timeout and try again
08:49:22.889 → // wait a bit to not spam the module
08:49:22.889 → while
08:49:22.889 → // try to set mode to standby
08:49:22.889 → standby() standbyXOSC=0
08:49:22.889 → standby() mode=0 wakeup=1
08:49:22.889 → // set RF switch (if present)
08:49:22.889 → // pull NSS low to wake up
08:49:22.921 → SPIwriteStream RADIOLIB_SX126X_CMD_SET_STANDBY
08:49:22.921 → // standby command successful
08:49:22.921 → **** return state
08:49:22.921 →
08:49:22.921 → standby() standbyXOSC=0
08:49:22.921 → standby() mode=0 wakeup=1
08:49:22.921 → // set RF switch (if present)
08:49:22.921 → // pull NSS low to wake up
08:49:22.921 → SPIwriteStream RADIOLIB_SX126X_CMD_SET_STANDBY
08:49:22.921 → standby() standbyXOSC=0
08:49:22.921 → standby() mode=0 wakeup=1
08:49:22.921 → // set RF switch (if present)
08:49:22.954 → // pull NSS low to wake up
08:49:22.954 → SPIwriteStream RADIOLIB_SX126X_CMD_SET_STANDBY
08:49:22.987 → radio.begin() success!
08:49:22.987 → END of setup()

1 Like

Here’s the output

20:34:52.032 -> Master UID 5F9F613
20:34:52.032 -> ********  verify=1
20:34:52.032 -> // run the reset sequence
20:34:52.070 -> // return immediately when verification is disabled
20:34:52.070 -> // set mode to standby - SX126x often refuses first few commands after reset
20:34:52.070 -> // try to set mode to standby
20:34:52.070 ->     standby() standbyXOSC=0
20:34:52.070 ->     standby() mode=0  wakeup=1
20:34:52.070 ->     // set RF switch (if present)
20:34:52.070 ->     // pull NSS low to wake up
20:34:52.070 ->     SPIwriteStream RADIOLIB_SX126X_CMD_SET_STANDBY
  return(this->mod->SPIwriteStream(RADIOLIB_SX126X_CMD_SET_STANDBY, data, 1));

It seems that this line is not executing. There may be a problem with SPI.
Unfortunately, I don’t have the skills to investigate further.

Yes it gets stuck here in spiTransferStream

this->hal->spiBeginTransaction();
  this->hal->digitalWrite(this->csPin, this->hal->GpioLevelLow);
  this->hal->spiTransfer(buffOut, buffLen, buffIn);
  this->hal->digitalWrite(this->csPin, this->hal->GpioLevelHigh);
  this->hal->spiEndTransaction();

Considering that the same problem occurred with two LoRa-E5 devices, I am beginning to wonder if the problem lies with the USB power supply rather than the firmware. What do you think?

Unfortunately no, I’ve already tried different USB hubs, with a different computer, using a battery and a 5V charger…

And the lora chip seems works fine when using the examples MCU package (GitHub - Seeed-Studio/LoRaWan-E5-Node at qian) though it nevers joins the TTN network successfully but that’s only because I have no gateway nearby, it atleast send the first the TX message

My issue is finally resolved after long days of troubleshooting.

SUBGHSPISD register was 0x00 on both boards, so that meant that the RF chip was never on.
I have no idea why this happened on both chip, I didn’t see this information anywhere on the wiki or in the docs, but those coming after me will have it.


(Thanks to this thread: Having issues enabling the SubGhzSPI on STM32WLE5J... - STMicroelectronics Community )

1 Like

Looking at the screenshot, the device is STM32WL5x_CM4, but my device setting is STM32WLE5_CM4.

Well it might just be a Low Energy variant, I don’t know but atleast it’s resolved ! Thanks again for all your hard work

1 Like