esp32c6: machine.InitADC() hangs indefinitely in readADC1()
Author: m-antiCreated Sep 2, 2026Updated Sep 10, 2026
Description
When attempting to read from the ADC on an ESP32-C6 (board ESP32-C6-DevKitC-1), the program gets stuck inside machine.InitADC() and never returns.
Minimal Reproducible Example
package main
import (
"machine"
"time"
)
func main() {
time.Sleep(time.Second)
println("Init ADC...")
machine.InitADC() // Hangs here
println("Init done")
sensor := machine.ADC{Pin: machine.ADC0}
sensor.Configure(machine.ADCConfig{})
for {
val := sensor.Get()
println(val)
time.Sleep(time.Millisecond * 500)
}
}Expected Behavior
machine.InitADC() initializes the ADC peripheral, prints "Init done", and proceeds to read values in the main loop.
Actual Behavior
The program prints "Init ADC..." and halts indefinitely.
Suspected Cause
Debugging indicates that InitADC() calls adcSelfCalibrate(), which invokes readADC1(). Inside readADC1(), the execution enters a busy-wait loop waiting for the hardware:
func readADC1() uint32 {
esp.APB_SARADC.SetINT_CLR_APB_SARADC1_DONE_INT_CLR(1)
esp.APB_SARADC.SetONETIME_SAMPLE_SARADC_ONETIME_START(0)
esp.APB_SARADC.SetONETIME_SAMPLE_SARADC_ONETIME_START(1)
// Execution hangs here because APB_SARADC1_DONE_INT_RAW is never set to 1
for esp.APB_SARADC.GetINT_RAW_APB_SARADC1_DONE_INT_RAW() == 0 {
}
raw := esp.APB_SARADC.GetSAR1DATA_STATUS_APB_SARADC1_DATA() & 0xfff
esp.APB_SARADC.SetONETIME_SAMPLE_SARADC_ONETIME_START(0)
return uint32(raw)
}It appears the hardware register setup for the ESP32-C6 target lacks necessary clock/power gating initialization or configuration bits required to trigger the one-time sample completion.
Environment Details
- Board: ESP32-C6-DevKitC-1
- Architecture: RISC-V esp32c6 (chip rev: 0.2)
- TinyGo Version: 0.42.0 linux/amd64
- Compiled & flashed with:
tinygo flash -target xiao-esp32c6 -port /dev/ttyACM0 -monitor adc.go
Source: tinygo-org/tinygo