Classic ESP32 Continuous ADC and Audio Can Compete for the Same I2S0 Resource

An analog acquisition feature and an audio feature can each work alone yet fail when combined on the original ESP32. Different driver names do not guarantee different hardware. In ESP-IDF v5.2.5, the continuous ADC driver uses I2S0 as its DMA FIFO, so an audio configuration can consume the resource that analog capture needs before any ADC sampling starts.

This article covers the original ESP32, not ESP32-S2 or ESP32-S3. The implementation has target-specific branches; moving this conclusion to another chip without reviewing its branch would be incorrect. No audio, ADC or resource-switching test was performed here.

Diagnose the hardware claim before changing buffer sizes

The ESP32 continuous ADC guide explicitly identifies the I2S0 dependency. When creating the ADC handle fails, preserve the return code and preceding driver logs. An unavailable peripheral is not repaired by enlarging the ADC result pool or reducing the sample rate.

The tagged ADC implementation makes the boundary concrete. In its ESP32 branch, handle creation requests I2S_NUM_0 through i2s_platform_acquire_occupation(). Failure is translated to ESP_ERR_NOT_FOUND. The same initialization also allocates an interrupt, so the numeric result alone should not be treated as a unique proof of I2S ownership conflict; follow the failing stage and logs.

Write a resource ledger for the complete firmware: component, requested peripheral, selected port, initialization owner and release point. Include libraries that initialize audio internally. A feature labeled “microphone” may claim a controller before the application reaches its own ADC setup, and a component using automatic selection may not consume the port its integrator expected.

Continuous ADC on classic ESP32 and an audio driver both request I2S0. Stopping ADC conversion leaves the driver handle's I2S0 reservation intact; deinitializing the stopped handle releases it. Standard-mode audio may be reviewed for I2S1, but I2S0-only modes cannot be moved there by renaming a port.

Original peripheral-ownership diagram for the specified ESP32 baseline. It does not describe ESP32-S3 DMA routing.

Make automatic I2S selection visible

The v5.2.5 I2S common driver handles I2S_NUM_AUTO by searching available controllers. Controller acquisition participates in the shared platform-occupation mechanism. Thus, initialization order can affect which resources remain available to a later component.

Consider a product that needs continuous ADC plus standard digital audio. If audio initializes first with automatic selection, it can occupy I2S0. Reordering initialization may make a demonstration work, but it leaves an implicit dependency that can change when another feature is added. Prefer an explicit, reviewed port plan for a fixed product architecture, and log the effective assignment in diagnostic builds.

Do not use a raw register sequence to bypass the driver’s failed claim. That would allow two software owners to configure the same peripheral without a compatible shared contract. A successful write to a register would not make their DMA channels, interrupts and clock configuration independent.

Check whether I2S1 actually supports the audio mode

The versioned I2S mode table lists standard mode on both ESP32 I2S controllers, while PDM transmit and receive are listed on I2S0. Therefore, “move audio to I2S1” is a candidate only after checking the actual mode and hardware interface.

For standard-mode audio, review the codec or microphone connection, available GPIO routing, clocks and driver configuration before reserving I2S1. For an I2S0-only requirement, choose a different architecture rather than silently changing mode semantics. Options might include an external converter with a suitable digital interface, a different chip, or deliberately nonconcurrent operating modes. Each has a product cost and requires its own signal and timing qualification.

The relevant decision is whether the required features can coexist on the chosen silicon. It is not simply whether both examples compile against the same SDK.

Distinguish stopped conversion from released ownership

The ADC source separates adc_continuous_stop() from adc_continuous_deinit(). Stop ends conversion and releases operational resources such as ADC-unit locks, while the ESP32 I2S occupation is released in deinitialization. The deinitializer also requires the handle to be in its initialized, nonrunning state.

Consequently, stopping ADC sampling does not by itself make I2S0 available to an unrelated audio driver. For mutually exclusive product modes, the transition must retire the continuous ADC handle through its supported lifecycle before the next owner acquires the controller. The reverse transition must likewise use the audio driver’s supported release sequence.

Define what happens to unread samples, callbacks and callers holding the old handle before permitting that transition. After deinitialization, invalidate the application’s stored handle and reconstruct a new one when returning to capture mode. Do not reuse a pointer just because its previous sampling operation was stopped. This is a mode-switch design, not a recommendation to churn drivers for every sample.

Qualify both feature coexistence and mode switching

A proposed bench sequence first runs ADC alone and records handle creation, start, stop and deinit results. Next initialize audio on the intended port and attempt ADC creation. Compare that result with the approved port plan, not with whichever initialization order happened to work previously.

For a nonconcurrent design, test acquisition before and after stop-only, then after full deinitialization. This distinguishes conversion state from retained peripheral ownership. Repeat switching under the intended workload while checking that obsolete handles are not accessed and that both audio and sample consumers receive an explicit mode-change result.

Retain board revision, chip identity, sdkconfig, effective I2S assignments and operation logs. No such tests were run for this article. Release only when the resource ledger matches the deployed driver behavior and the required audio/analog combination has been demonstrated, rather than inferred from two independent examples.

Similar Posts