Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TinyGo silent-serial reproduction (XIAO ESP32-C3, macOS)

Minimal reproduction of a bug where a TinyGo sketch that writes to machine.Serial produces no output on /dev/cu.usbmodem* when flashed to a Seeed XIAO ESP32-C3 on macOS, while functionally-identical Arduino and MicroPython sketches on the same board and cable work fine.

Environment

Component Version
Hardware Seeed XIAO ESP32-C3
Host macOS 15.7.4, Apple Silicon (M1)
Go 1.26.5 darwin/arm64
TinyGo 0.41.1 (also tested 0.41.0 — same silent behavior)
arduino-cli 1.5.1
esp32:esp32 core 3.3.11
MicroPython v1.28.0 (2026-04-06) ESP32_GENERIC_C3
mpremote 1.28.0

Prerequisites

brew install tinygo arduino-cli

arduino-cli config init
arduino-cli config add board_manager.additional_urls \
  https://espressif.github.io/arduino-esp32/package_esp32_index.json
arduino-cli core update-index
arduino-cli core install esp32:esp32

Plug the XIAO ESP32-C3 into USB. Confirm the port appears:

ls /dev/cu.usbmodem*

Reproduction

Arduino (control — works)

make flash-arduino
make monitor

Expected AND actual output:

tick 0
tick 1
tick 2
...

TinyGo (bug — silent)

make flash-tinygo
make monitor

Expected output:

boot
tick 0
tick 1
tick 2
...

Actual output: nothing — silent for the full 15-second monitor window.

MicroPython (second control — works)

Extra prereqs:

pip install mpremote   # or: brew install mpremote

Download the ESP32_GENERIC_C3 firmware .bin from https://micropython.org/download/ESP32_GENERIC_C3/ and drop it into micropython/firmware/. Then:

make flash-micropython-firmware   # one-time: erase + install MicroPython
make flash-micropython            # upload micropython/main.py and reset
make monitor

Expected AND actual output (the board's REPL auto-runs main.py at boot):

boot
tick 0
tick 1
tick 2
...

Same board, same cable, same /dev/cu.usbmodem* — MicroPython prints immediately, so USB-CDC on this hardware/host works and the silence is isolated to TinyGo.

Observations

  • Flash completes successfully in both cases (esptool verify passes; MD5 matches).
  • USB-CDC is enabled in both cases:
    • Arduino: the default XIAO_ESP32C3 board profile has USBMode=hwcdc, CDCOnBoot=cdc.
    • TinyGo: "serial": "usb" is set in targets/esp32c3.json, inherited by xiao-esp32c3.json. machine.Serial maps to USB-CDC.
  • The failure also reproduces with TinyGo's own src/examples/echo/echo.go sketch — not specific to the code in this repro.
  • Physical USB unplug/replug (including switching USB ports on the Mac) does not recover output for the TinyGo case.
  • Both TinyGo 0.41.0 and 0.41.1 are silent. Older TinyGo (0.40.x) cannot be tested against Go 1.26 (cannot compile with Go toolchain version go1.26).
  • The chip itself is fine: switching to the Arduino sketch on the same cable/port/board prints as expected within seconds of make flash-arduino.
  • MicroPython v1.28.0 (ESP32_GENERIC_C3) also prints tick N correctly over the same USB-CDC endpoint — two independent stacks (Arduino, MicroPython) work; only TinyGo is silent.

Sketches

Both sketches do the same thing — print tick N over serial once per second.

  • arduino/arduino.ino — 8 lines of C++.
  • tinygo/main.go — modeled after $(brew --prefix tinygo)/src/examples/echo/echo.go.
  • micropython/main.py — same tick N loop in Python (second control).

Layout

.
├── Makefile             Targets: flash-arduino / flash-tinygo / flash-micropython[-firmware] / monitor / clean
├── README.md            This file
├── arduino/
│   └── arduino.ino      Arduino sketch (control)
├── tinygo/
│   ├── go.mod
│   └── main.go          TinyGo sketch (bug)
└── micropython/
    ├── main.py          MicroPython sketch (second control)
    └── firmware/        Drop ESP32_GENERIC_C3 .bin here (gitignored)

About

Silent USB-CDC output on xiao-esp32c3

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages