Skip to content

Fix M5Stack Unit C6L: RX, flash size, pin conflicts#1875

Open
wbijen wants to merge 4 commits intomeshcore-dev:devfrom
wbijen:fix/c6l-rx-flash-pins
Open

Fix M5Stack Unit C6L: RX, flash size, pin conflicts#1875
wbijen wants to merge 4 commits intomeshcore-dev:devfrom
wbijen:fix/c6l-rx-flash-pins

Conversation

@wbijen
Copy link

@wbijen wbijen commented Feb 28, 2026

Fix M5Stack Unit C6L: RX not working, bootloop on flash, pin conflicts

Hi! I picked up my C6L and ran into a few issues getting it to work properly. Spent some time digging through the hardware docs and comparing with Meshtastic's working variant (variants/esp32c6/m5stack_unitc6l/) to figure out what was going on. Hopefully this helps get the C6L into a good state!

What was wrong

RX was completely dead. Turns out the C6L routes its RF switch and LNA through an I2C GPIO expander (PI4IOE5V6408 at 0x43) rather than direct ESP32 GPIOs. Without initializing this expander, the antenna never gets connected to the SX1262's RX path. TX still worked because DIO2 handles that side directly, which made it a bit confusing at first. Also SX126X_RXEN=5 was pointing at a GPIO that isn't actually connected to the RF switch on this board.

Web flasher binaries bootlooped. The PlatformIO board definition esp32-c6-devkitm-1 defaults to 4MB flash — which is correct for Espressif's own DevKitM-1, but the C6L actually has 16MB. Flashing via pio run -t upload works fine because esptool auto-detects the size, but merged binaries (which the web flasher uses) had 4MB baked into the header, causing a watchdog reset on every boot.

I2C was on the wrong pins. PIN_BOARD_SDA/SCL were set to 16/17 (the external Grove port), but the GPIO expander lives on SDA=10, SCL=8.

P_LORA_TX_LED=15 was conflicting with the OLED. GPIO15 is actually the SSD1306 display reset pin on the C6L, not a TX LED — looks like it was carried over from the Xiao C6 variant. The C6L has a WS2812C NeoPixel on GPIO2 instead. With this define active, ESP32Board::begin() holds the display in permanent reset.

TCXO voltage was set to 1.8V instead of 3.0V (matching hardware and Meshtastic).

Changes

variants/m5stack_unit_c6l/platformio.ini:

  • Add board_build.flash_size = 16MB / board_upload.flash_size = 16MB
  • Remove P_LORA_TX_LED=15
  • Change PIN_BOARD_SDA/SCL from 16/17 to 10/8
  • Remove SX126X_RXEN=5
  • Change SX126X_DIO3_TCXO_VOLTAGE from 1.8 to 3.0
  • Remove unused GPS_RX/GPS_TX (C6L has no GPS, and the codebase uses PIN_GPS_RX/PIN_GPS_TX anyway)
  • Add M5Stack_Unit_C6L_companion_radio_wifi env (was missing)

variants/m5stack_unit_c6l/UnitC6LBoard.h:

  • Add initGPIOExpander() that configures the PI4IOE5V6408 — sets P6 (RF switch) and P7 (LoRa reset) as outputs, drives them HIGH. Matches Meshtastic's c6l_init() in their variant.cpp.

Testing

  • BLE companion builds and boots (no bootloop)
  • WiFi companion builds, boots, connects to network
  • Merged binary flashes correctly via web flasher (16MB in header)
  • LoRa RX receives packets
  • LoRa TX still works
  • BLE pairs with MeshCore app

- Initialize PI4IOE5V6408 I2C GPIO expander for RF switch/LNA control
- Fix I2C bus pins (SDA=10, SCL=8) - ESP32-C6 only has one I2C peripheral
- Remove SX126X_RXEN=5 (RF switch is on expander, not ESP32 GPIO)
- Set flash size to 16MB (actual hardware, was defaulting to 4MB)
- Remove P_LORA_TX_LED=15 (GPIO15 is OLED reset, not TX LED)
- Fix TCXO voltage 1.8V -> 3.0V
- Remove unused GPS_RX/GPS_TX defines
- Add esp_mac.h include for ESP32-C6 BLE builds
- Add WiFi companion radio build target
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.

1 participant