The overview, with examples running, is on the board page and The ESP32-S3 model (every register).
The ESP32-S3-DevKitC-1
The ESP32-S3 on an Xtensa LX7 at 240 MHz: Espressif's own DevKitC-1, with its RGB LED on the RMT, two USB sockets, LEDC PWM and a twelve-bit ADC.
What it is
The ESP32-S3-DevKitC-1, Espressif's board for the ESP32-S3, running on our own Xtensa core. Firmware is an Xtensa ELF talking to the real ESP32-S3 addresses, and almost every one of those addresses was checked against Espressif's technical reference manual.
The board is 62.7 by 25.4 mm and its two rows of 22 pins are 0.9 inch apart, so it straddles a breadboard's center channel with one row of holes left free on each side, like the classic ESP32 DevKit.
The pins
Twenty-two down each long edge, the two micro-USB sockets at the bottom, the module and its antenna at the top. The silkscreen names each GPIO by its number.
J1, the left column, top to bottom: 3V3, 3V3, RST, 4, 5, 6, 7,
15, 16, 17, 18, 8, 3, 46, 9, 10, 11, 12, 13, 14, 5V,
G.
J3, the right column, top to bottom: G, TX, RX, 1, 2, 42, 41,
40, 39, 38, 37, 36, 35, 0, 45, 48, 47, 21, 20, 19, G,
G.
TX and RX are GPIO 43 and 44, UART0. RST is the chip enable. 5V is the
USB rail. This is a 3.3 volt board and its pins are not 5 V tolerant.
Things the pinout does to you
- GPIO 35, 36 and 37 belong to the PSRAM on the octal-PSRAM boards (the N8R8 most people buy). They are on the header, and on those boards you must not use them. Mokxi has no PSRAM, so here they work, which a desk might not.
- GPIO 19 and 20 are the USB port's D- and D+. Drive them and the "USB" socket stops working on a real board. Here the USB serial port keeps going, which is kinder than the silicon.
- GPIO 0, 3, 45 and 46 are strapping pins, so what is wired to them at power on matters. GPIO 0 is also the BOOT button.
- Some pins power up with their input switched off. GPIO 4 to 8, 15, 16 and
19 to 21 read 0 until
pinModeturns the input buffer on, which is the chip's reset state.pinModealways does it, so a sketch never notices.
The RGB LED
The board has no plain LED. It has an addressable RGB LED, a WS2812-type
part, on GPIO 48 on the first boards and on GPIO 38 on v1.1, which
Espressif lists as the only difference between the two revisions. The board's
revision property picks which one is on your breadboard.
LED_BUILTIN on this board is not a GPIO number: as in the Arduino core, it is
the GPIO count plus the LED's pin, and digitalWrite(LED_BUILTIN, HIGH) sends
the LED a frame that lights it white at a quarter brightness. For color,
rgbLedWrite(RGB_BUILTIN, red, green, blue). Both go out through the chip's
RMT peripheral, 24 bits green first, every bit inside the WS2812B
datasheet's timing, and the LED on the board lights with whatever color the
frame carries.
The examples are built for GPIO 48, as the Arduino core's board definition is.
On a v1.1 board the LED is on GPIO 38, so the same sketch leaves it dark, which
is what would happen on a desk. The pin is also on the header, so a ws2812
strip wired to 48 sees the same frames.
analogRead: ten channels, and 2.9 V is the top
ADC1's ten channels are GPIO 1 to 10: channel n is GPIO n + 1. Twelve
bits. At the default 12 dB attenuation the datasheet's measurement range ends at
2.9 V, and Mokxi reads 4095 from there up, so a potentiometer across the
3.3 V rail reads 4095 over the top eighth of its travel. The knob example
prints the raw number so that is not a mystery.
That straight line up to 2.9 V is an approximation: a real S3 keeps a little headroom above the range and bends at both ends, corrected from calibration burned into the chip. ADC2 is not modeled.
analogWrite is LEDC, and it costs the core nothing
analogWrite(pin, 0..255) attaches one of LEDC's eight channels to the pin:
eight bits at 1 kHz, on any GPIO, through the GPIO matrix.
ledcAttach(pin, frequency, bits) and ledcWrite(pin, duty) are there when the
frequency matters. On the S3, LEDC settings only take effect when an update bit
is written, and the runtime writes it; a fading LED costs the core nothing.
Serial, and the two USB sockets
A real DevKitC-1 has two micro-USB sockets. "UART" goes through a
USB-to-UART bridge to UART0: that is Serial, as in the Arduino core with USB
CDC On Boot switched off, its default for this board. "USB" is the chip's
own USB Serial/JTAG controller: that is USBSerial, which sends a 64-byte
packet at a time, at the end of each line.
The serial monitor here listens to both at once, so either one prints in the same place, and what you type goes to both.
One core, not two
A real S3 has two Xtensa LX7 cores, and Mokxi runs one. A sketch written
around setup() and loop() never notices. Anything that starts a task on core
1 will not run.
What is modeled
The Xtensa LX7, which for everything a compiler emits from C is the classic
ESP32's LX6 instruction set: the same windowed ABI, and the S3 compiler's output
was checked byte for byte against the ESP32 compiler's. Around it: 416 KB of
SRAM seen through both buses, the GPIO matrix and IO MUX with the manual's reset
pulls on every pin, UART0, the USB Serial/JTAG serial port, SYSTIMER behind
millis() and micros(), ADC1, LEDC, the RMT's four transmit channels, the
clock gates, and as much of the interrupt matrix as four sources need.
WiFi, simulated
There is no radio. What there is is Mokxi's simulated network, the same
one the classic ESP32 and the ESP32-C3 have, behind a block that is Mokxi's own
rather than the chip's, at an address the S3 leaves unmapped. WiFi.h,
HTTPClient.h and WebServer.h work the way a tutorial expects: the board
joins an access point whose name and password are properties of the board,
fetches a page from a made-up address under .mokxi, or serves one to the Web
panel. There is no 802.11, no TCP, no TLS and no real internet. Bluetooth
is not simulated at all.
WiFi, simulated is how to use it; Simulated WiFi is the contract.
What is not
A radio of any kind, and Bluetooth. The second core. The FPU and the
S3's vector instructions: both fault rather than returning a wrong number, and
the runtime is soft float. SRAM0, the cache, flash and PSRAM. The RTC, the
ULP coprocessors and deep sleep. ADC2, the touch sensor and the
temperature sensor. The timer groups and the watchdogs. UART1 and UART2,
the I2C and SPI controllers, I2S, the camera interface, TWAI and USB OTG.
Wire and SPI in the runtime are software on ordinary pins, as on every board
here: SDA on 8, SCL on 9, and SPI on 10 to 13.
Vendor ESP-IDF and Arduino-core binaries will not run here: the runtime is ours.
Compiling your sketch
Edit the sketch and press Run: it compiles in the tab with Espressif's clang
for Xtensa, the same toolchain as the classic ESP32 and the ESP8266 (clang-v3,
about 80 MB, downloaded once). Nothing is uploaded. An untouched example runs
its prebuilt program, built with Espressif's GCC for the S3; nothing of GCC is
linked into it.
Avoid floating-point arithmetic: this model has no FPU, so a float multiply
faults with a message in the serial monitor rather than returning a wrong
number. Serial.print(1.5) works. Compiling in the browser
has the full account.
The examples
Blink, Rainbow, Button, Serial, USB serial, Fade, Knob, and the four WiFi ones: WiFi: join the network, WiFi: fetch the weather, API lab: fetch JSON and WiFi: a lamp on a web page.
Elsewhere
- The board page: /boards/esp32-s3
- The contract document: the ESP32-S3 model, whose section 6 lists the few numbers that are believed rather than checked
- The other Xtensa boards: the ESP32 DevKit and the ESP8266 NodeMCU