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.
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()
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 )
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