mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-04 03:18:10 +10:00
Lr1121 tcxo optional tries xtal first, and get all my yamls in a row (#11215)
* LR11x0: try XTAL before TCXO when oscillator type is uncertain On boards with TCXO_OPTIONAL, a TCXO-first attempt either hangs RadioLib's calibration wait forever on a bare/non-TCXO module (unpatched upstream), or costs a slow failed attempt before falling back even once that's fixed with a timeout. Measured on hardware: XTAL succeeds immediately on a bare module (~350ms) and fails fast and cleanly on a genuine TCXO module (~300ms, RADIOLIB_ERR_SPI_CMD_FAILED), so trying XTAL first is a strict improvement for hang-avoidance regardless of which oscillator is actually present. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * compacted * fix review comment * fix femtofox switches * correct the correction * 13 * 3s timeout * Treat SPI_CMD_TIMEOUT as an LR11x0 init failure The BUSY watchdog breaks RadioLib's wait, so the next bounded transfer returns SPI_CMD_TIMEOUT rather than SPI_CMD_FAILED. Only the latter was checked, so a watchdog-triggered failure fell through to getVersionInfo(), setRfSwitchTable() and startReceive() against an unresponsive chip. Also use Throttle::isWithinTimespanMs() for the watchdog's elapsed-time check instead of raw millis() arithmetic. * Drop the BUSY watchdog and probe XTAL before TCXO The watchdog bounded RadioLib's unbounded BUSY wait in LR11x0::config() by having LockingArduinoHal::digitalRead() report a stuck pin low exactly once. That let a TCXO-first attempt fail cleanly rather than hang, but it meant lying to RadioLib about a GPIO from a HAL shared by every radio driver. Ordering the attempts XTAL-first avoids the hang outright instead: attempt 1 configures no DIO3 Vref, so there is no calibration wait to get stuck in, and the TCXO fallback is only reached on a module that answered and refused XTAL. Attempts are now XTAL, then TCXO, then a settling retry on whichever oscillator was settled on - after a fallback that is a second TCXO attempt. Only TCXO_OPTIONAL builds probe XTAL; a variant that declares a Vref unconditionally still goes straight to it and never probes XTAL at all. SPI_CMD_TIMEOUT stays a failure alongside SPI_CMD_FAILED: a bounded per-command BUSY wait in Module::SPItransferStream() reports it in its own right, independently of the removed watchdog. * Drop a stray tab from the promicro TCXO readme trunk fmt: prettier flags the whitespace-only line inside the <summary> block, which was the only failing check on the PR. --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
Thomas Göttgens
parent
03e6b80989
commit
e78b121d9f
@@ -42,7 +42,7 @@ Making your own node based on this design is straightforward. There are various
|
||||
| Waveshare | Core1262-HF | yes | Ext | |
|
||||
| Waveshare | LoRa Node Module | yes | Int | |
|
||||
| Seeed | Wio-SX1262 | yes | Ext | Cute! DIO2/TXEN are not exposed |
|
||||
| Seeed | Wio-LR1121 | yes | Int | LR1121, needs alternate rfswitch.h |
|
||||
| Seeed | Wio-LR1121 | yes | Int | LR1121, build -D LR1121_MODULE_WIO |
|
||||
| AI-Thinker | RA-02 | No | Int | SX1278 **433mhz band only** |
|
||||
| RF Solutions | RFM95 | No | Int | Untested |
|
||||
| Ebyte | E80-900M2213S | Yes | Int | LR1121 radio |
|
||||
@@ -55,7 +55,24 @@ The E80 from CDEbyte is the most obtainable module at present, and has been sele
|
||||
|
||||
Naturally, CDEbyte have chosen to ignore the generic Semtech implementation of the RF switching logic and have supplied confusing and contradictory documentation, which is explained below.
|
||||
|
||||
tl;dr: The E80 is chosen as the default. **If you wish to use another module, the table in `rfswitch.h` must be adjusted accordingly.**
|
||||
tl;dr: The E80 is chosen as the default. **If you wish to use another module, select it with an `LR1121_MODULE_*` build flag, or adjust the table in `rfswitch.h` accordingly.**
|
||||
|
||||
`rfswitch.h` carries a matrix for each known LR1121 module, guarded by a build flag:
|
||||
|
||||
| Build flag | Module |
|
||||
| ------------------- | ------------------- |
|
||||
| _(none)_ | Ebyte E80-900M2213S |
|
||||
| `LR1121_MODULE_E80` | Ebyte E80-900M2213S |
|
||||
| `LR1121_MODULE_WIO` | Seeed Wio-LR1121 |
|
||||
|
||||
Add it to your environment in `platformio.ini`:
|
||||
|
||||
```ini
|
||||
build_flags = ${nrf52840_base.build_flags}
|
||||
-I variants/nrf52840/diy/nrf52_promicro_diy_tcxo
|
||||
-D NRF52_PROMICRO_DIY
|
||||
-D LR1121_MODULE_WIO
|
||||
```
|
||||
|
||||
### E80 switching - the saga
|
||||
|
||||
@@ -82,7 +99,7 @@ The Semtech default, the values are (taken from [here](https://github.com/Lora-n
|
||||
<details>
|
||||
|
||||
<summary> < Click to expand >
|
||||
|
||||
|
||||
</summary>
|
||||
|
||||
```cpp
|
||||
@@ -119,4 +136,19 @@ Tests were conducted in each of the three configurations between a known-good SX
|
||||
|
||||
The RF switching is based on the code example given. Logically, this shows the DIO5 and DIO6 are swapped compared to the reference design.
|
||||
|
||||
If future DIYers wish to use an alternative module, the table in `rfswitch.h` must be adjusted accordingly.
|
||||
## Seeed Wio-LR1121
|
||||
|
||||
The Wio is the counter-example to the E80: it follows the Semtech reference exactly, so no swap is needed. Its internal switch is a Skyworks SKY13373-460LF, controlled by DIO5 (V1) and DIO6 (V2) only - there is no third control line, so DIO7 is left out of the pin list. Section 4.5 of the module datasheet, "True Table of the Internal RF Switch", gives:
|
||||
|
||||
| V1 (DIO5) | V2 (DIO6) | Status | RadioLib mode |
|
||||
| --------- | --------- | ------------------- | ------------- |
|
||||
| 0 | 0 | Shutdown | `MODE_STBY` |
|
||||
| 1 | 0 | RFI_P_LF & RFI_N_LF | `MODE_RX` |
|
||||
| 0 | 1 | RFO_HP_LF | `MODE_TX_HP` |
|
||||
| 1 | 1 | RFO_LP_LF | `MODE_TX` |
|
||||
|
||||
Note that the LR1121 has no GNSS or WiFi scanning, so `MODE_GNSS` and `MODE_WIFI` are left in the shutdown state.
|
||||
|
||||
Select it with `-D LR1121_MODULE_WIO`.
|
||||
|
||||
If future DIYers wish to use a module not listed above, add a matrix for it to `rfswitch.h` behind a new `LR1121_MODULE_*` guard.
|
||||
|
||||
@@ -6,6 +6,22 @@
|
||||
#define LR20x0 LR2021
|
||||
#endif
|
||||
|
||||
// LR1121 modules differ in how their internal RF switch is wired, so the matrix must match the
|
||||
// module actually fitted. The Ebyte E80-900M2213S is the default; define one of the alternatives
|
||||
// below in your build_flags (or above the #include of this header) to select a different module.
|
||||
//
|
||||
// LR1121_MODULE_E80 Ebyte E80-900M2213S (default if nothing is defined)
|
||||
// LR1121_MODULE_WIO Seeed Wio-LR1121
|
||||
#ifdef USE_LR1121
|
||||
|
||||
#if !defined(LR1121_MODULE_E80) && !defined(LR1121_MODULE_WIO)
|
||||
#define LR1121_MODULE_E80
|
||||
#endif
|
||||
#if defined(LR1121_MODULE_E80) && defined(LR1121_MODULE_WIO)
|
||||
#error "Define only one LR1121_MODULE_* option"
|
||||
#endif
|
||||
|
||||
#ifdef LR1121_MODULE_E80
|
||||
// This is rewritten to match the requirements of the E80-900M2213S
|
||||
// The E80 does not conform to the reference Semtech switches(!) and therefore needs a custom matrix.
|
||||
// See footnote #3 in "https://www.cdebyte.com/products/E80-900M2213S/2#Pin"
|
||||
@@ -13,7 +29,6 @@
|
||||
// DIO5 -> RFSW0_V1
|
||||
// DIO6 -> RFSW1_V2
|
||||
// DIO7 -> not connected on E80 module - note that GNSS and Wifi scanning are not possible.
|
||||
#ifdef USE_LR1121
|
||||
static const uint32_t rfswitch_dio_pins[] = {RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, RADIOLIB_NC,
|
||||
RADIOLIB_NC};
|
||||
|
||||
@@ -30,7 +45,39 @@ static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
END_OF_MODE_TABLE,
|
||||
// clang-format on
|
||||
};
|
||||
#endif
|
||||
#endif // LR1121_MODULE_E80
|
||||
|
||||
#ifdef LR1121_MODULE_WIO
|
||||
// Seeed Wio-LR1121. Unlike the E80 this module DOES follow the Semtech reference topology
|
||||
// (SWSD006: rx = RFSW0, tx = RFSW0|RFSW1, tx_hp = RFSW1).
|
||||
// The internal switch is a Skyworks SKY13373-460LF driven by two lines only:
|
||||
// DIO5 -> V1
|
||||
// DIO6 -> V2
|
||||
// Datasheet section 4.5, "True Table of the Internal RF Switch":
|
||||
// V1 V2 Status
|
||||
// 0 0 Shutdown
|
||||
// 1 0 RFI_P_LF & RFI_N_LF (receive)
|
||||
// 0 1 RFO_HP_LF (sub-GHz high power)
|
||||
// 1 1 RFO_LP_LF (sub-GHz low power)
|
||||
// The LR1121 has no GNSS or WiFi scanning, so those modes are left in the shutdown state.
|
||||
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[] = {
|
||||
// clang-format off
|
||||
// mode DIO5 DIO6
|
||||
{LR11x0::MODE_STBY, {LOW, LOW}},
|
||||
{LR11x0::MODE_RX, {HIGH, LOW}},
|
||||
{LR11x0::MODE_TX, {HIGH, 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,
|
||||
// clang-format on
|
||||
};
|
||||
#endif // LR1121_MODULE_WIO
|
||||
|
||||
#endif // USE_LR1121
|
||||
|
||||
// LR2021 RF switch matrix following the standard Semtech / Seeed T1000-E reference topology.
|
||||
// DIO5 -> antenna path select (HIGH = sub-GHz LF)
|
||||
|
||||
@@ -262,7 +262,7 @@ settings.
|
||||
| Waveshare | Core1262-HF | yes | Ext | |
|
||||
| Waveshare | LoRa Node Module | yes | Int | |
|
||||
| Seeed | Wio-SX1262 | yes | Ext | Cute! DIO2/TXEN are not exposed |
|
||||
| Seeed | Wio-LR1121 | yes | Int | LR1121, needs alternate rfswitch.h |
|
||||
| Seeed | Wio-LR1121 | yes | Int | LR1121, build -D LR1121_MODULE_WIO |
|
||||
| AI-Thinker | RA-02 | No | Int | SX1278 **433mhz band only** |
|
||||
| RF Solutions | RFM95 | No | Int | Untested |
|
||||
| Ebyte | E80-900M2213S | Yes | Int | LR1121 radio |
|
||||
|
||||
Reference in New Issue
Block a user