ESP32-S31 Function-CoreBoard-1 — hardware reference¶
Pin maps and onboard features for the Espressif ESP32-S31 Function-CoreBoard-1, read from the
official schematic so projectMM work (Ethernet, audio, SD, USB-host) reads this instead of
re-scraping the PDF. The board is the bench S31 (esp32s31 firmware).
Sources - Schematic (rev C, 2026-05-13): https://dl.espressif.com/schematics/esp32-s31-function-coreboard-1-schematics.pdf - PCB layout: https://dl.espressif.com/schematics/esp32-s31-function-coreboard-1-pcb-layout.pdf - Datasheet (chip): https://documentation.espressif.com/esp32-s31_datasheet_en.pdf - Module (WROOM-3): https://documentation.espressif.com/esp32-s31-wroom-3_datasheet_en.pdf - User guide: https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32s31/esp32-s31-function-coreboard-1/user_guide.html
The module is ESP32-S31-WROOM-3: RISC-V dual-core (≤300 MHz), Wi-Fi 6, BT, IEEE 802.15.4, on-chip 1 Gbps EMAC. It shares the MoonLive RISC-V backend with the ESP32-P4.
Audio (ES8311 codec)¶
The onboard electret mic (J6) and speaker connect through an ES8311 mono codec (U7) + an NS4150B 3 W class-D amplifier (U9). The ESP is the I2S master (it drives MCLK).
| Signal | GPIO | Direction / role |
|---|---|---|
| I2S_MCLK | 52 | master clock → codec (ESP is I2S master; MCLK = 256 × sample_rate) |
| I2S_SCLK (BCLK) | 53 | bit clock |
| I2S_LRCK (WS) | 55 | word select |
| I2S_ASDOUT | 54 | mic / ADC data: codec → ESP (the record path) |
| I2S_DSDIN | 56 | playback / DAC data: ESP → codec (speaker path) |
| ESP_I2C_SDA | 51 | codec control bus — SDA is GPIO51, SCL is GPIO50 |
| ESP_I2C_SCL | 50 | codec control bus |
| PA_CTRL | 57 | NS4150B amplifier enable |
SDA/SCL are GPIO51/GPIO50 — the opposite of what the schematic's
ESP_I2C_SDA/ESP_I2C_SCLnet labels suggest. Bench-confirmed: the I2cScanModule (sda=51, scl=50 in the S31 catalog entry) finds the ES8311 ACK at 0x18; with 50/51 nothing ACKs. The other audio pins match the schematic + the chip's GPIO table (all of GPIO50–57 are plain I/O GPIOs routed through the matrix — no special-function conflict).
- ES8311 I2C address:
0x18(the default; set by theCEpin tie). - Driven by Espressif's
esp_codec_devmanaged component (the ES8311 driver). The codec needs MCLK running before it answers I2C, andes8311_codec_cfg.mclk_divmust be set (256, the standard ratio) oropenfails "unable to configure sample rate". So AudioService brings up the I2S channel (which drives MCLK on GPIO52) before the codec I2C config. - Mic-only path (audio-reactive input) needs MCLK/SCLK/LRCK + ASDOUT (record) + the I2C bus. The speaker path (DSDIN + PA_CTRL) is output, a separate capability.
Ethernet (YT8531 PHY, RGMII, 1 Gbps)¶
On-chip EMAC → YT8531 (Motorcomm) PHY (U8) → RJ45, RGMII with a 25 MHz crystal (Y2).
Pin map — bench-verified (link + DHCP confirmed on the CoreBoard). The RGMII data + clock
GPIOs are the chip's fixed IO_MUX pads (the only ones the EMAC accepts; from IDF's
esp32s31/emac_periph.c); MDC/MDIO are IDF's S31 SMI defaults (ETH_ESP32_EMAC_DEFAULT_CONFIG):
| Signal | GPIO | Signal | GPIO | |
|---|---|---|---|---|
| ETH_INTN | 2 | ETH_TXD3 | 11 | |
| PHY_MDC | 5 | ETH_TX_CTL | 12 | |
| PHY_MDIO | 6 | ETH_TXCLK | 13 | |
| ETH_PHY_RST | 7 | ETH_RX_CLK | 14 | |
| ETH_TXD0 | 8 | ETH_RX_CTL | 15 | |
| ETH_TXD1 | 9 | ETH_RXD3 | 16 | |
| ETH_TXD2 | 10 | ETH_RXD2 | 17 | |
| ETH_RXD1 | 18 | |||
| ETH_RXD0 | 19 |
RGMII, not RMII. projectMM's classic/P4 Ethernet is RMII (fewer data lines, 50 MHz ref clock); the S31's 1 Gbps EMAC is RGMII (4-bit data each way + TX/RX clocks). The shared
ethInitEmac()insrc/platform/esp32/platform_esp32.cppdrives both: an#ifdef CONFIG_IDF_TARGET_ESP32S31block selects the RGMII interface and sets the CoreBoard's data/clock pins from the table above, then shares the driver-install / netif / DHCP tail with the RMII path. The board's default eth config (ethConfigDefaultinplatform_config.h) uses PHY typeethYt8531(PHY address auto-detected), driven by the generic IEEE-802.3 PHY ctor since the YT8531 is a standard-register PHY.RGMII 125 MHz Tx clock = APLL. The EMAC needs a clean 125 MHz Tx clock; the default MPLL is owned by PSRAM (400 MHz, no integer path to 125) and CPLL can't hit it on the 40 MHz XTAL grid, so
sdkconfig.defaults.esp32s31setsCONFIG_ETH_EMAC_RGMII_TX_CLK_SRC_APLL— the fractional PLL synthesises 125 MHz exactly.
Other onboard features¶
- Addressable RGB LED — WS2812 (D7) on GPIO60. (Driven today: the catalog's S31
RmtLedDriverusespins: "60", withloopbackTxPin: 48/loopbackRxPin: 47for the self-test — see § Free GPIO.) - SD card slot — SD_D0–D3 / SD_CLK / SD_CMD on the module's SDIO pins (GPIO20–25 per the user
guide). Note:
SOC_SDMMC_SUPPORTEDis absent in the S31 soc-caps, so the slot is likely SPI-mode (GPSPI) rather than the SDMMC peripheral — confirm before relying on it. - USB-A host — USB 2.0 high-speed host port (5 V, 0.5 A limit).
- USB-C ×2 — one is USB Serial/JTAG (native), one is a USB-to-UART bridge (CP2102N default, or CH9102X with the alternate BOM). Auto-download via DTR/RTS → EN/BOOT.
- Buttons — BOOT (GPIO61), RESET (EN).
- J5 — power/enable jumper (a 2-pin header next to the 5V→3.3V DC/DC converter U4 and the 3.3V power-on LED D11). Leave it installed. With J5 removed the board is half-powered: the CP2102N runs off USB VBUS so its port still enumerates, but the ESP32-S31's 3.3V/EN rail is incomplete and the chip drives nothing — you get a serial port that opens but zero bytes from the MCU, at any baud, in any reset/download mode (see lessons.md — this cost an hour of chasing a cable that wasn't the problem).
- 40-pin GPIO header (J2). Optional 32.768 kHz crystal footprint (Y1, NC by default).
Free GPIO for user peripherals (LED strips, loopback)¶
The board's own peripherals claim a large, contiguous low-GPIO block; the J2 header exposes the rest. Tallying the maps above, the taken pins are:
| Peripheral | GPIOs |
|---|---|
| Ethernet RGMII | 2, 5–19 |
| ES8311 audio (I²S + I²C) | 50–57 |
| SD card (SDIO/SPI) | 20–25 |
| Onboard WS2812 RGB LED | 60 |
| BOOT button | 61 |
J2 is a 2×20 header — each column carries two GPIOs, a top-row pin above a bottom-row pin. Reading the silkscreen left→right (top / bottom per column):
| col | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| top | G | RX0 | 60 | G | 3 | 1 | 48 | 46 | 44 | 42 | 38 | 36 | D0 | D2 | CLK | 4 | C | 3V3 | G | 5V |
| bottom | G | TX0 | 61 | 2 | 0 | 49 | 47 | 45 | 43 | 40 | 39 | 37 | 35 | D1 | D3 | CMD | G | 3V3 | G | 5V |
The two pins in one column are physically stacked, so a 2-pin jumper cap bridges them with no flying wire — that adjacency is what makes a column a good loopback pair.
Free on J2 for user I/O (read off the table above, minus the board peripherals and boot straps): the numbered GPIOs on cols 5–16 — 4, 36, 37, 38, 39, 40, 42, 43, 44, 45, 46, 47, 48, 49 — are plain I/O clear of Ethernet (2, 5–19), audio (50–57), the SD lines (broken out as D0–D3 / CLK / CMD by function, cols 13–16), the onboard LED (60) and the straps (0, 1, 3, 61). The C label at col 17 is a chip-enable, not a GPIO. The GPIO numbers here are read from the board silkscreen and not yet bench-confirmed — the S31 reference pin tables have been found off-by-one before (see the S31 Ethernet lesson), so probe a pin before committing a design to it.
Recommended assignment (what the S31 catalog entry uses):
- LED strip data: the onboard WS2812 is on GPIO 60 (the catalog default). For an external strand, use GPIO 42 as the single-lane pick; a parallel rig (RMT/Parlio) takes the free block (36–49, skipping 41 which isn't broken out) for several lanes. GPIO 4 (col 16 top) also works as an LED data pin and sits one column from the
G/3V3/5Vpower rail (cols 17–20), so a single strip's data + ground + 5 V wires land close together — handy for a tidy 3-wire pigtail. It's a plain I/O with no strap or peripheral tie on this board (the SD lines beside it, D0–D3 / CLK / CMD, are broken out by function name, not GPIO number, so GPIO 4 is not one of them; it just neighbours that cluster on the header). The only reason it reads as "distinct" from the rest of the free run is its header position — it's over by the SD/power group rather than in the low-block on cols 8–12. - Loopback self-test: Tx = GPIO 48, Rx = GPIO 47 — the two pins of column 7 (48 top, 47 bottom), so a single jumper cap shorts them. A driver transmits a known WS2812 frame out Tx and reads it back on Rx to verify output on real silicon (same pattern as the P4-NANO bench's 32↔33). They sit at the top of the free run, clear of the operational LED pins so the strip wiring and the jumper don't interfere. Bench-confirmed PASS on the S31 for both RmtLedDriver and ParlioLedDriver — the two WS2812 output drivers the S31 supports. LcdLedDriver is not one of them: it's the ESP32-S3-specific LCD_CAM i80 driver, and the RISC-V S31 has no LCD_CAM peripheral (it reports "no valid pins"). Testing several drivers in a row, they all default loopback to GPIO 48, so only one can hold the pin at a time — toggle each driver's
loopbackTestoff before testing the next.
SoC capabilities (from components/soc/esp32s31/include/soc/soc_caps.h)¶
Wi-Fi 6 · Bluetooth (no separate BLE soc-flag) · IEEE 802.15.4 (Thread/Zigbee) · USB-OTG · GPSPI · TWAI (CAN) · RMT · Parlio · LCD_CAM i80 · on-chip EMAC · PSRAM. RISC-V dual-core.
The S31 catalog entry drives LEDs (RMT on GPIO60) and Wi-Fi 6, and wires an
I2cScanModule on the codec bus (SDA 51 / SCL 50) for
I2C bring-up. The AudioService ES8311 path is implemented
— the codec seam configures the ES8311 over I2C (codec reachable, ACK at 0x18) and AudioService
reads the I2S mic. End-to-end mic validation depends on confirming MCLK at GPIO52; the S31 entry
keeps Audio under planned until that bench check passes, so the installer advertises only
what's confirmed working. The other board capabilities (Ethernet, Bluetooth, SD, USB host, …)
likewise live in the entry's planned list — see the S31 entry in web-installer/deviceModels.json.