jgromes / RadioLib

Universal wireless communication library for embedded devices
https://jgromes.github.io/RadioLib/
MIT License
1.52k stars 381 forks source link

[LR1121]: Strange SPI behavior #1174

Closed Tipetofficial closed 1 month ago

Tipetofficial commented 2 months ago

I am using the LR1121 on an own PCB with an ESP32-S3-WROOM-1U and I keep getting the code -2 for a bad SPI-Interface when using the LR11x0_Firmware_Update. I checked my wiring (see schematic) and followed the Non-standard SPI setup as u can see in the code below.

As displayed in the basic debug output the red value and the expected value are the same, but it still fails.

I would highly appreciate any hints to how I could resolve this issue.

Schematic

Schematic_black.pdf

Code that fails

#include <Arduino.h>
#include <SPI.h>
/*
  RadioLib LR11x0 Firmware Update Example

  This example updates the internal LR1110 firmware.
  Newer versions of the firmware introduce fixes
  and possibly even new features, so it is recommended
  to use the latest available firmware version
  when possible.

  Other modules from LR11x0 family can also be used.

  For full API reference, see the GitHub Pages
  https://jgromes.github.io/RadioLib/
*/

// include the library
#include <RadioLib.h>
//#include "LR1121.h"
// select the firmware image you want to upload
// WARNING: Make sure you select the correct firmware
//          for your device! Uploading incorrect firmware
//          (e.g. LR1110 firmware to LR1120 device)
//          may damage your hardware!
//#define RADIOLIB_LR1110_FIRMWARE_0303
//#define RADIOLIB_LR1110_FIRMWARE_0304
//#define RADIOLIB_LR1110_FIRMWARE_0305
//#define RADIOLIB_LR1110_FIRMWARE_0306
//#define RADIOLIB_LR1110_FIRMWARE_0307
//define RADIOLIB_LR1110_FIRMWARE_0401
//#define RADIOLIB_LR1120_FIRMWARE_0101
//#define RADIOLIB_LR1120_FIRMWARE_0102
//#define RADIOLIB_LR1120_FIRMWARE_0201
//#define RADIOLIB_LR1121_FIRMWARE_0102
#define RADIOLIB_LR1121_FIRMWARE_0103
// enable this macro if you want to store the image in host
// MCU RAM instead of Flash.
// NOTE: the firmware images are very large, up to 240 kB!
//#define RADIOLIB_LR1110_FIRMWARE_IN_RAM

// include the firmware image
#include <modules/LR11x0/LR11x0_firmware.h>

#define SPI_MOSI  11
#define SPI_MISO  10
#define SPI_CLK   9 
#define SPI_CLOCK_FREQ 2000000
#define NSS       8

/* 
SPIClass* g_spi;

void spiinit()
{
  g_spi = new SPIClass(HSPI);
  g_spi->begin(SPI_CLK, SPI_MISO, SPI_MOSI, NSS);
  pinMode(g_spi->pinSS(), OUTPUT);  
}

Module* mod;
LR1121* radio;
*/
// LR1110 has the following connections:
// NSS pin:   8
// IRQ/DIO9 pin:   7  
// NRST pin:  6
// BUSY pin:  5

SPIClass spi(FSPI);

SPISettings spiSettings(2000000, MSBFIRST, SPI_MODE0);
LR1121 radio = new Module(NSS, 7, 6, 5, spi, spiSettings);

// or using RadioShield
// https://github.com/jgromes/RadioShield
//LR1110 radio = RadioShield.ModuleA;
void printVersions();
void setup() {
  delay(3000);
  Serial.begin(9600);
  spi.begin(SPI_CLK, SPI_MISO, SPI_MOSI, NSS);

  /*
  spiinit();
  mod = new Module(NSS, 7, 6, 5, *g_spi, RADIOLIB_DEFAULT_SPI_SETTINGS);
  radio = new LR1121(mod);
  */
  // initialize LR1110 with default settings
  Serial.print(F("[LR1121] Initializing ... "));
  int state = radio.begin();
  if (state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while (true) { delay(10); }
  }

  // print the firmware versions before the update
  printVersions();

  // prompt the user
  Serial.println(F("[LR1121] Send any character to start the update"));
  while(!Serial.available()) { delay(1); }

  // upload update into LR11x0 non-volatile memory
  Serial.print(F("[LR1121] Updating firmware, this may take several seconds ... "));
  state = radio.updateFirmware(lr11xx_firmware_image, RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE);
  /*
    use the following if you enabled RADIOLIB_LR1110_FIRMWARE_IN_RAM
    state = radio.updateFirmware(lr11xx_firmware_image, RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE, false);
  */
  if (state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while (true) { delay(10); }
  }

  // print the firmware versions after the update
  printVersions();

}

void printVersions() {
  LR11x0VersionInfo_t version;
  Serial.print(F("[LR1121] Reading firmware versions ... "));
  int16_t state = radio.getVersionInfo(&version);
  if (state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));

    Serial.print(F("[LR1121] Device: "));
    Serial.println(version.device);

    Serial.print(F("[LR1121] Base firmware: "));
    Serial.print(version.fwMajor);
    Serial.print('.');
    Serial.println(version.fwMinor);

    Serial.print(F("[LR1121] WiFi firmware: "));
    Serial.print(version.fwMajorWiFi);
    Serial.print('.');
    Serial.println(version.fwMinorWiFi);

    Serial.print(F("[LR1121] GNSS firmware: "));
    Serial.print(version.fwGNSS);
    Serial.print('.');
    Serial.println(version.almanacGNSS);

  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while (true) { delay(10); }

  }

}

void loop() {

}

SPI Debug Output

[LR1121] Initializing ... RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
RLB_SPI: CMDW<9>1<9>1<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>7<9>22<9>3<9>1<9>1<9><\n>
RLB_SPI: CMDW<9>3<9>20<9><\n>
RLB_SPI: SI<9><9><9><\n>
RLB_SPI: SO<9>5<9>13<9><\n>
RLB_SPI: CMDR<9><\n>
RLB_SPI: SI<9>0<9>0<9>0<9><\n>
RLB_SPI: SO<9>3<9>13<9>0<9><\n>
failed, code -2<\r><\n>

Basic Debug Output

[LR1121] Initializing ... RLB_DBG: <\n>
RadioLib Info<\n>
Version:  "6.6.0.0"<\n>
Platform: "ESP32"<\n>
Compiled: "Jul 30 2024" "08:49:34"<\n>
RLB_DBG: LR11x0 not found! (1 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: LR11x0 not found! (2 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: LR11x0 not found! (3 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: LR11x0 not found! (4 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: LR11x0 not found! (5 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: LR11x0 not found! (6 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: LR11x0 not found! (7 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: LR11x0 not found! (8 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: LR11x0 not found! (9 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: LR11x0 not found! (10 of 10 tries) RADIOLIB_LR11X0_CMD_GET_VERSION = 0x03<\n>
RLB_DBG: Expected: 0x03<\n>
RLB_DBG: No LR11x0 found!<\n>
failed, code -2<\r><\n>

Output Logic Analyser

SPI_logic_1_klein

jgromes commented 2 months ago

This is interesting, since the excepted and read-out values match, the only way for the radio presence check to fail is if the method LR11x0::getVersion fails itself. There's probably some subtle difference between LR1110 (which I used to write the LR11x0 driver) and the LR1121 in that regard that is causing this method to fail. Unfortunately I'm away from most of my hardware at the moment, so this will take a couple of days for me to look into.

jgromes commented 1 month ago

@Tipetofficial I went through the log once more and noticed that a command to read WiFi scanning formware version is being called. For LR1121 that will always fail, since it does not have that functionality. A check to fix this was added in 87fac1797e8e8ef2a8c6cffb722e4212c3050a19, but was not released yet. Could you please try this again with the latest master?

Tipetofficial commented 1 month ago

@jgromes Thank you for the fast answer, the master fixed this problem but now I get the -707 error. I am using a TCXO and added

radio.setTCXO(2.4);

because the TCXO I use need at least 1.7V rather that the default 1.6V but the error stays the same.

jgromes commented 1 month ago

You have to pass the TCXO voltage as an argument to the begin method, otherwise it will fail before it has a chance to initialize.

Tipetofficial commented 1 month ago

Thank you. With your help I was able to fix the issue.