Repository navigation
Commit 202fcfe
espressif: add audiopwmio.PWMAudioOut for the ESP32-S2
The espressif port had no audiopwmio at all, so boards whose speaker is
not wired to a DAC pin had no way to play samples. On the Adafruit
FunHouse the piezo is on GPIO42, while the ESP32-S2 DAC is hardwired to
GPIO17/GPIO18 (and GPIO18 is the light sensor), so audioio cannot reach
it.
LEDC has no DMA path for its duty registers, and the S2's I2S has no PDM
transmitter (no SOC_I2S_SUPPORTS_PDM_TX), so samples are pushed from a
GPTimer alarm ISR running at the sample rate. The ISR drains one of two
device buffers; audiopwmout_background(), called from
port_background_task(), refills the other from the audiosample protocol.
The ISR deliberately touches nothing but its own object's volatile state.
It must not queue a background callback: on this port that macro is
taskENTER_CRITICAL(), which aborts when called from ISR context. Driving
the refill by polling instead also means a buffer the ISR found empty is
always picked up again, rather than relying on the ISR to have queued the
refill before it stalled.
Every gptimer call is checked, so a timer that cannot be configured
raises instead of leaving `playing` true forever. alarm_config is static
because CircuitPython builds with CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM, under
which gptimer_set_alarm_action() rejects a config outside internal RAM.
The carrier is APB_CLK / 2**10 = 78.125 kHz, which keeps it out of the
audio band while leaving 10 bits of amplitude resolution. The GPTimer
runs at 40 MHz (the finest the timer group divider allows), putting the
sample-rate error below 0.01% at 8k/11k/22k/44.1k.
A single-buffer sample that loops wraps inside the ISR rather than
round-tripping through the background task, so looping RawSamples do not
click.
ledc_ll.h lives in the per-target esp_hal_ledc directory, which was not
on the include path, so add it.
Enabled for esp32s2 only; the S3 has neither DAC nor audiopwmio and could
reuse this later. Costs 2336 bytes of flash and 648 bytes of internal
SRAM on adafruit_funhouse, and nothing on boards that leave it off.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>1 parent cfe5624 commit 202fcfe
7 files changed
Lines changed: 527 additions & 0 deletions
File tree
- ports/espressif
- common-hal/audiopwmio
- supervisor
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
123 | 123 | | |
124 | 124 | | |
125 | 125 | | |
| 126 | + | |
126 | 127 | | |
127 | 128 | | |
128 | 129 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
11 | 14 | | |
12 | 15 | | |
13 | 16 | | |
| |||
28 | 31 | | |
29 | 32 | | |
30 | 33 | | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
31 | 37 | | |
32 | 38 | | |
33 | 39 | | |
| |||
0 commit comments