A few months ago, I wrote about my disappointing experience trying to program a Nordic nRF52840 dongle with PlatformIO. The conclusion was clear: abandon PlatformIO and use native toolchains. Yet here I am again, foolishly thinking "maybe this time will be different" with the newer ESP32-C6 chip. Spoiler alert: it wasn't.

The Setup#

I had a simple goal: display text on an ESP32-C6 board with an ST7789 display using LVGL. This should be straightforward in 2025, right? The ESP32-C6 is not some obscure development board—it's Espressif's latest mainstream chip with built-in WiFi 6, Zigbee, and Thread support.

I started with what seemed like a reasonable approach: PlatformIO with Arduino framework, since I had working code from other ESP32 projects.

First Attempt: Arduino Framework#

My platformio.ini looked innocent enough:

[env:esp32-c6-devkitc-1]
platform = espressif32
framework = arduino
board = esp32-c6-devkitc-1
monitor_speed = 115200

lib_deps =
    lvgl/lvgl@^8.3.0

build_flags =
    -D LV_CONF_SKIP=1

This unfortunately failed spectacularly:

CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32-c6-devkitc-1.html
PLATFORM: Espressif 32 (6.12.0) > Espressif ESP32-C6-DevKitC-1
HARDWARE: ESP32C6 160MHz, 320KB RAM, 8MB Flash
DEBUG: Current (cmsis-dap) External (cmsis-dap, esp-bridge, esp-builtin, esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES:
 - framework-arduinoespressif32 @ 3.20017.241212+sha.dcc1105b
 - tool-esptoolpy @ 2.40900.250804 (4.9.0)
 - toolchain-riscv32-esp @ 8.4.0+2021r2-patch5
Error: This board doesn't support arduino framework!
================================================================================= [FAILED] Took 31.46 seconds =================================================================================

Wait, what? The board doesn't support Arduino framework? But the ESP32-C6 DevKit is listed right there in PlatformIO's board documentation. This makes no sense.

Second Attempt: Force Arduino Framework#

Maybe I could force it to work by using an older Arduino core:

[env:esp32-c6-devkitc-1]
platform = espressif32@^6.8.1
framework = arduino
board = esp32-c6-devkitc-1
monitor_speed = 115200

platform_packages =
    framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0

lib_deps =
    lvgl/lvgl@^8.3.0

build_flags =
    -D LV_CONF_SKIP=1
    -D ARDUINO_USB_CDC_ON_BOOT=1

This time I got a different error:

Configuring toolchain packages from a remote source...
Tool Manager: Installing espressif/toolchain-riscv32-esp @ 14.2.0+20241119
UnknownPackageError: Could not find the package with 'espressif/toolchain-riscv32-esp @ 14.2.0+20241119' requirements for your system 'darwin_arm64'

Ah, macOS ARM64 support issues. The bleeding-edge platform is trying to use a toolchain that doesn't exist for my M3 Mac. Back to square one.

Third Attempt: ESP-IDF Framework#

Fine, let's try ESP-IDF framework instead:

[env:esp32-c6-devkitc-1]
platform = espressif32
framework = espidf
board = esp32-c6-devkitc-1
monitor_speed = 115200

lib_deps =
    lvgl/lvgl@^8.3.0

build_flags =
    -D LV_CONF_SKIP=1

This actually started compiling! Progress! But then my display driver header file caused issues:

In file included from src/main.c:5:
./Display_ST7789.h:2:10: fatal error: SPI.h: No such file or directory

*******************************************************************
* Looking for SPI.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:SPI.h"
* Web  > https://registry.platformio.org/search?q=header:%1B%5Bm%1B%5BKSPI.h
*
*******************************************************************

    2 | #include <SPI.h>
      |          ^~~~~~~
compilation terminated.

Of course. My display driver was written for Arduino's SPI library, but now I'm using ESP-IDF framework. I need to rewrite the entire driver to use ESP-IDF's SPI APIs.

Fourth Attempt: Manual Display Driver#

I spent time converting the Arduino SPI calls to ESP-IDF equivalents:

// Arduino style
SPI.begin();
digitalWrite(PIN_DC, HIGH);

// ESP-IDF style
spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
gpio_set_level(PIN_DC, 1);

After considerable effort, I had a basic display driver working, but then the linker complained:

/Users/peterbabic/.platformio/packages/toolchain-riscv32-esp/bin/../lib/gcc/riscv32-esp-elf/14.2.0/../../../../riscv32-esp-elf/bin/ld: .pio/build/esp32-c6-devkitc-1/src/main.c.o: in function `my_disp_flush':
/Users/peterbabic/work/balint-tracking/firmware/src/main.c:17:(.text.my_disp_flush+0x1c): undefined reference to `LCD_addWindow'
/Users/peterbabic/.platformio/packages/toolchain-riscv32-esp/bin/../lib/gcc/riscv32-esp-elf/14.2.0/../../../../riscv32-esp-elf/bin/ld: .pio/build/esp32-c6-devkitc-1/src/main.c.o: in function `app_main':
/Users/peterbabic/work/balint-tracking/firmware/src/main.c:26:(.text.app_main+0x36): undefined reference to `LCD_Init'

PlatformIO with ESP-IDF framework doesn't automatically compile additional C files. I need to create CMakeLists.txt files and manage the build manually—essentially recreating what native ESP-IDF does automatically.

Fifth Attempt: ESP Component Registry#

Then I discovered Espressif's official LVGL component: esp_lvgl_port. This handles all the LVGL initialization complexity and integrates properly with ESP32's LCD drivers. Perfect!

I tried adding it via idf_component.yml:

dependencies:
  espressif/esp_lvgl_port: "^2.6.0"
  lvgl/lvgl: "^8"

But PlatformIO completely ignores this file:

src/main.c:10:10: fatal error: esp_lvgl_port.h: No such file or directory

*****************************************************************************
* Looking for esp_lvgl_port.h dependency? Check our library registry!
*
* CLI  > platformio lib search "header:esp_lvgl_port.h"
* Web  > https://registry.platformio.org/search?q=header:%1B%5Bm%1B%5BKesp_lvgl_port.h
*****************************************************************************

   10 | #include "esp_lvgl_port.h"
      |          ^~~~~~~~~~~~~~~~~
compilation terminated.

PlatformIO doesn't integrate with ESP-IDF's component registry at all. The entire ecosystem of ESP-IDF components is unavailable.

The Pattern Emerges#

This is exactly what happened with the nRF52840 dongle. PlatformIO works great for older, well-established boards and frameworks, but falls apart when you need:

  1. Latest chip support - ESP32-C6 Arduino framework is broken
  2. Native component ecosystems - ESP-IDF components are ignored
  3. Advanced debugging - ESP-IDF's debugging tools aren't accessible
  4. Proper toolchain management - Bleeding-edge toolchains missing for newer platforms

The fundamental problem is that PlatformIO is an abstraction layer trying to unify different embedded ecosystems, but it inevitably lags behind the native toolchains and loses important functionality in translation.

Hope these error messages help someone in the future.