Skip to content

Conversation

@sgrimee
Copy link

@sgrimee sgrimee commented Dec 1, 2025

Summary

  • Add support for LilyGo T-LoRa V1.6.1 board with TCXO (Temperature Compensated Crystal Oscillator)
  • Includes TCXO-specific initialization with enable pin and stabilization delay for improved frequency stability
  • Provides 4 build environments: companion radio (BLE & USB), repeater, and room server

@sgrimee sgrimee marked this pull request as draft December 1, 2025 18:37
@sgrimee sgrimee force-pushed the lilygo_t3_v1.6.1_tcxo branch from c3792f8 to 5f946cd Compare December 1, 2025 19:03
@sgrimee sgrimee marked this pull request as ready for review December 1, 2025 19:05
@jbrazio
Copy link
Contributor

jbrazio commented Dec 2, 2025

Is this a new radio ? If this is the "well known" variants/lilygo_tlora_v2_1/platformio.ini and the TCXO is not being enabled on that profile, update the profile instead of creating a new one.

@sgrimee
Copy link
Author

sgrimee commented Dec 2, 2025

Versions of the LilyGo LoRa32 V2.1_1.6 exist both with and without a TCXO. The standard non-TCXO model uses a basic crystal oscillator, while TCXO-equipped boards (e.g., SX1276 868/915 MHz TCXO) are available for regions requiring precise timing, though they may need firmware tweaks for compatibility with libraries like LMIC due to unconnected DIO1 pins. TCXO variants are explicitly offered by LilyGo and third-party sellers, but support in projects like Paxcounter or Meshtastic may be limited without modifications.

I do not have the hardware without TCXO, so I didn't dare modifying that version and breaking it for other users.

I have tried the lilygo_tlora_v2_1 and it won't boot correctly on the version with TCXO.

How other projects handle it:
meshtastic/firmware#3080
Xinyuan-LilyGO/LilyGo-LoRa-Series#148

If there is a better way to approach it I am happy to help out and adjust.

@jbrazio
Copy link
Contributor

jbrazio commented Dec 2, 2025

Actually it should be the other way around: first try to init TXCO and if it fails fallback to no TXCO.
Have a look at src/helpers/radiolib/CustomSX1276.h:

      int status = begin(LORA_FREQ, LORA_BW, LORA_SF, cr, RADIOLIB_SX126X_SYNC_WORD_PRIVATE, LORA_TX_POWER, 16);
      // if radio init fails with -707/-706, try again with tcxo voltage set to 0.0f
      if (status != RADIOLIB_ERR_NONE) {
        Serial.print("ERROR: radio init failed: ");
        Serial.println(status);
        return false;  // fail
      }

This way we can still keep only one target.

@sgrimee
Copy link
Author

sgrimee commented Dec 2, 2025

Hi @jbrazio,

Thank you for the feedback on auto-detection. After investigating, I found that auto-detection is not feasible due to hardware constraints. Here's what I learned:

The Issue

GPIO 33 has different purposes on the two hardware variants:

  • Crystal boards (more common): GPIO 33 = DIO1 (LoRa interrupt line)
  • TCXO boards: GPIO 33 = TCXO_EN (power enable), DIO1 is not connected

Why auto-detection doesn't work:

  • TCXO boards require both GPIO 33 HIGH (to power the TCXO) and DIO1=RADIOLIB_NC (so RadioLib doesn't try to use GPIO 33 as an interrupt) before radio initialization
  • Without these conditions, TCXO boards fail with error -16 (RADIOLIB_ERR_SPI_WRITE_FAILED)
  • Simply enabling GPIO 33 HIGH after a failed init doesn't work - the Module object must be created with DIO1=RADIOLIB_NC from the start
  • This means we cannot attempt a "test init" to detect the variant, because the Module configuration is set at compile time
  • There's no way to distinguish between the two hardware variants through software

Meshtastic's Approach

Meshtastic solved this with two separate variant directories:

  1. Crystal variant: https://github.com/meshtastic/firmware/tree/develop/variants/esp32/tlora_v2_1_16

    • DIO1 = GPIO 33
  2. TCXO variant: https://github.com/meshtastic/firmware/tree/develop/variants/esp32/tlora_v2_1_16_tcxo

    • DIO1 = RADIOLIB_NC (not connected)
    • Defines -D LORA_TCXO_GPIO=33

My Current Solution

I've simplified the implementation to assume TCXO variant:

  • Set P_LORA_DIO_1=RADIOLIB_NC in platformio.ini
  • Enable GPIO 33 HIGH in radio_init() for TCXO power

This works perfectly on my TCXO hardware. However, I only have TCXO boards to test with.

Options Going Forward

  1. Follow Meshtastic approach - Maintain two separate variant directories (could use naming like lilygo_tlora_v2_1 and lilygo_tlora_v2_1_tcxo)
  2. Assume TCXO for all boards - Keep current implementation and test on crystal hardware to verify it doesn't break DIO1 functionality

I'm unable to test on crystal hardware. Which approach would you prefer?

sgrimee added 3 commits December 12, 2025 18:27
Consolidates TCXO hardware variant support into the v2_1 platformio.ini
configuration by adding TCXO-specific environments for all build targets
(repeater, terminal_chat, companion_radio, room_server, and bridges).
Uses shared [tcxo_flags] section to manage TCXO-specific compilation flags.
Removes now-redundant v1_6_1_tcxo variant files.
@sgrimee sgrimee force-pushed the lilygo_t3_v1.6.1_tcxo branch from 66bd2cb to 640f017 Compare December 12, 2025 19:47
@sgrimee
Copy link
Author

sgrimee commented Dec 12, 2025

@jbrazio here is another approach. I still cannot auto-detect if TCXO is enabled or not, but this proposal now adds environments with txco in the existing lilygo_tlora_v2_1. Is this what you meant?

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.

2 participants