Skip to content

Add ESP32-C6 support#5248

Open
gandarez wants to merge 8 commits intotinygo-org:devfrom
gandarez:feat/esp32-c6
Open

Add ESP32-C6 support#5248
gandarez wants to merge 8 commits intotinygo-org:devfrom
gandarez:feat/esp32-c6

Conversation

@gandarez
Copy link
Contributor

@gandarez gandarez commented Mar 13, 2026

Summary

  • Adds full ESP32-C6 (RISC-V) target support including runtime, machine peripherals, interrupt handling, linker script, and flash tooling
  • The ESP32-C6-DevKitC boots, runs user programs, and outputs serial via USB-Serial-JTAG
  • Fixes chip-specific SPI flash frequency encoding in the firmware image header (0x00 for 80MHz on C6 vs 0x0F on C3)

What's included

  • Runtime: watchdog disabling (TIMG0/1, LP_WDT, SWD), 160MHz PLL clock setup, USB-Serial-JTAG serial I/O, SYSTIMER-based timekeeping
  • Interrupts: PLIC-style vectored interrupt controller with 31 priority levels
  • Machine peripherals: GPIO (30 pins), ADC, I2C, SPI, PWM (LEDC)
  • Linker script: unified 512KB SRAM (IRAM/DRAM at 0x40800000), flash-mapped IROM/DROM with MMU page alignment
  • Flash tooling: esp32jtag flash method, correct chip ID (0x000D), ESP32-C6 frequency encoding in image header
  • Board definition: ESP32-C6-DevKitC pin mappings, WS2812/NeoPixel LED on GPIO8, UART/I2C/SPI default pins

Test plan

  • Test on real device
  • Firmware boots without checksum errors
  • Serial output works via USB-Serial-JTAG (println in a loop)
  • time.Sleep works correctly
  • GPIO output verified with external LED
  • I2C/SPI/ADC/PWM peripheral testing
  • WS2812 onboard LED via tinygo.org/x/drivers/ws2812

Closes: #4029

gandarez and others added 5 commits March 13, 2026 11:12
… enable serial

The super watchdog write-protect key was copied from ESP32-C3 (0x8F1D312A)
but ESP32-C6 uses 0x50D83AA1, so the SWD was never actually disabled and
would reset the chip after a few seconds.

The clock configuration was also setting HS_DIV_NUM=0, running the CPU at
480MHz (SPLL/1) instead of the intended 160MHz (SPLL/3). This caused USB
Serial/JTAG PHY timing failures, preventing any serial output. Fixed by
setting HS_DIV_NUM=2 and explicitly configuring AHB/APB bus dividers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…atch

The sarEnable() method references regI2C and analog config constants
defined in machine_esp32xx_adc.go, which excludes m5stamp_c3. Moving it
to a new file with the matching build constraint prevents undefined
symbol errors for that target.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gandarez and others added 3 commits March 13, 2026 17:41
ESP32-C6 uses rv32imac ISA (with atomics), unlike ESP32-C3 which uses
rv32imc. The features string was copied from ESP32-C3 and incorrectly
disabled the atomic-related LLVM features.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@@ -0,0 +1,79 @@
//go:build esp32c6

// This file contains the default pin mappings for the ESP32-C6 generic target.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is not really such a thing as "generic" target. From the comments below, shouldn't this be board_esp32c6_devkitc?

})
}

func (uart *UART) serveInterrupt(num int) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is named handleInterrupt most places elsewhere in TinyGo.

@@ -0,0 +1,19 @@
//go:build esp32c3 || esp32s3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps naming like machine_esp32x3_periph.go?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe not merge, but copy?

@deadprogram
Copy link
Member

deadprogram commented Mar 15, 2026

Just as an overall comment, it would be a lot easier to review/test this as a series of PRs which each added another set of capabilities. See the recent work on esp32s3 as a example of this.

You can perhaps take the commits from this PR (once all tested/working on real hardware) and then have your coding tools take that set of commits and turn them into a series of atomic commits for review.

For example:

  • commit that adds the basic processor/runtime
  • commit that adds gpio
  • commit that adds i2c
  • commit that adds spi

@deadprogram
Copy link
Member

@gandarez this is PR I am working on for STM32u585 with the commit structuring I mentioned above:

#5251

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.

3 participants