Analog (ADC / DAC)
The ADC turns a pad voltage into a number; the DAC does the reverse. core_adc reads pads as raw counts or calibrated millivolts (and the die temperature and supply rail); core_dac drives a voltage out. Both sit on hal_* / ll_* — use the Core / HAL / LL toggle at the top of the sidebar to switch.
Overview
The ADC is a 12-bit SAR converter (counts 0–4095). You can read a pad as raw counts, or as millivolts — the latter uses the factory VREFINT calibration so the reading is supply-independent. The Tier 2 pad calls own ADC1 and read by tile pad number; the Tier 1 handle API gives you resolution, sampling speed, and DMA.
Reading inputs
The shortest path is the Tier 2 pad read — coregen has already set the pad to analog. For full control (resolution, sampling speed) use the Tier 1 handle:
#include "core.h"
// Tier 2 — pad declared analog in config.json:
uint16_t raw = core_adc_read_pad(8);
uint32_t mv = core_adc_read_mv_pad(8);
// Tier 1 — explicit handle:
core_adc_t adc;
core_adc_init(&adc, ADC_12BIT);
core_adc_add(&adc, 8, SAMP_MED);
uint16_t r = core_adc_read(&adc, 8);
uint32_t v = core_adc_read_mv(&adc, 8);Temperature & supply
Two internal channels need no pad: the die temperature sensor and the supply rail (via VREFINT). The Tier 2 calls return tenths of a degree and millivolts:
int32_t decidegc = core_adc_temp_decidegc(); // e.g. 234 = 23.4 °C
uint32_t vdd_mv = core_adc_vdd_mv(); // measured supplyDAC output
On the H5 Core, the DAC drives a fixed voltage out. Init once, then write a raw 12-bit value or a millivolt level:
#include "core.h" // Core.ST.H5 only
core_dac_init();
core_dac_write(2048); // mid-scale (raw 12-bit)
core_dac_write_mv(1650); // 1.65 VCross-architecture support
Raw and millivolt reads are verified broadly; oversampling, continuous/scan, and DMA vary by Core, and the temperature sensor’s accuracy depends on whether the factory cal is bus-accessible. The DAC is H5-only:
See the implementation status for the full matrix.
Known gaps
What the SDK itself lists as missing here, straight from the headers:
read_pad / read_mv_pad use the per-pad slider on the chip view, but temp_decidegc and vdd_mv return fixed values (25.0 °C / 3300 mV). No UI affordance to vary them yet — DSL programs that branch on under-/over-temp or low-VDD logic always see nominal in the IDE.
Tier 2 calls the default instance at its compile-time resolution (12-bit) and per-pad sampling speed set during init. SAMP_FAST / MED / SLOW / VERY_SLOW and ADC_6/8/10/12BIT aliases are reachable only via the explicit-handle Tier 1 API.
Tier 2 wrappers always hit core_adc1. Cores with multiple ADCs (Core.ST.H5 has ADC1 + ADC2) need per-pad peripheral tagging in tile JSON before coregen can emit the dispatch. Until then DSL programs are limited to whichever pads coregen routed to ADC1.
STM32 ADCs can hardware-oversample 2×–256× for extra effective resolution. The HAL exposes the registers but core_adc has no convenience wrapper — callers reach into tal_adc / hal_adc to set OVSR/OVSS bits manually.
Regular-group external triggers ARE supported: core_adc_set_trigger() paces DMA conversions from a TIMx TRGO or EXTI line. Injected groups (a second, higher-priority conversion sequence that preempts the regular one) are not surfaced. Bring-your-own register writes if you need a preempting sample inside a control loop.
Single-sample writes only. STM32H5's DAC supports DMA-fed sample buffers + the internal noise / triangle wave generators — none of which are wrapped. Audio + arbitrary-waveform tiles need this.
The DAC peripheral has two channels that can be triggered together for stereo / I-Q output. Only single-channel writes are exposed.
From the @studio unsupported notes in core_adc.h, core_dac.h — tiles@6af026f.
API reference
ADC
int core_adc_read_pad(uint8_t pad);int core_adc_read_mv_pad(uint8_t pad);int core_adc_temp_decidegc(void);int core_adc_vdd_mv(void);hal_status_t core_adc_init(core_adc_t * adc, uint32_t resolution);hal_status_t core_adc_add(core_adc_t * adc, uint8_t pad, uint32_t samp);uint16_t core_adc_read(core_adc_t * adc, uint8_t pad);uint32_t core_adc_read_mv(core_adc_t * adc, uint8_t pad);int32_t core_adc_temp(core_adc_t * adc);uint32_t core_adc_vdd(core_adc_t * adc);hal_status_t core_adc_start_dma(core_adc_t * adc, uint16_t * buf, uint16_t len, hal_callback_t cb, void * ctx);void core_adc_stop_dma(core_adc_t * adc);uint16_t core_adc_dma_read(core_adc_t * adc, uint8_t pad);uint32_t core_adc_dma_read_mv(core_adc_t * adc, uint8_t pad);uint32_t core_adc_raw_to_mv(core_adc_t * adc, uint16_t raw);hal_status_t core_adc_set_trigger(core_adc_t * adc, uint8_t extsel, uint32_t edge);int core_adc_dma_slot(core_adc_t * adc, uint8_t pad);Generated from core_adc.h — tiles@6f27e78.
DAC
void core_dac_init(void);void core_dac_write(uint16_t val);void core_dac_write_mv(uint16_t mv);uint16_t core_dac_read(void);Generated from core_dac.h — tiles@2a1a847.

