examples/
One runnable program per peripheral. Each replaces src/main.c for the build — just name it.
- gpio_button.cRead the onboard BOOT button and show its state on the RGB LED
- i2c_scan.cScan the bus for devices, then read a register from each
- led_blink.cCycle the onboard RGB LED through red, green, blue, and off
- pwm_fade.cAn LED breathing on one channel, a servo sweeping on another
- spi_loopback.cA loopback self-test that also exercises the multi-chunk path
- uart_echo.cA loopback self-test, then an echo server
One program per peripheral. Each replaces src/main.c for the build — just
name it:
make list # what is here
make i2c_scan # build it
make i2c_scan flash monitor # build it, flash it, watch itmake EXAMPLE=i2c_scan is the same thing spelled out, if you prefer. Either
form works with every target — all, flash, size, clean.
Outputs are named after the program (build/i2c_scan.bin), so switching
between examples never flashes the previous one by mistake. Plain make still
builds src/main.c into build/main.bin.
Every example prints to the USB-C console, so make monitor shows what it is
doing. That console is the USB-Serial-JTAG peripheral, which has nothing to do
with the UART on the pins — console_print() talks to your PC, uart_print()
talks to whatever is wired to GPIO5.
| Example | Shows | Needs |
|---|---|---|
| gpio_button.c | Input pins, pull-ups, debouncing | nothing |
| uart_echo.c | Serial TX/RX, FIFO, baud rate | one jumper wire |
| i2c_scan.c | Bus scan, register reads, error returns | an I2C device + 2 pull-ups |
| spi_loopback.c | Full duplex, chunk splitting, CS | one jumper wire |
| pwm_fade.c | Duty cycles, frequency/resolution trade | an LED, or a servo |
Three of the five verify themselves and need no parts, which is the point: when something does not work, you want to be sure the bus is right before you start suspecting the device.
Wiring
gpio_button — nothing. The BOOT button and the RGB LED are both onboard.
uart_echo — one wire, GPIO5 to GPIO6. That ties TX to RX so the port talks to itself; the example reports whether what it sent came back. Remove the wire and attach a real device to those pins to watch its traffic instead.
spi_loopback — one wire, GPIO11 (MOSI) to GPIO13 (MISO). SPI shifts a bit out and a bit in on the same edge, so with those tied together every byte sent arrives back in the same transfer. Tests one byte, one full 64-byte hardware transfer, and a 200-byte transfer that the driver has to split.
i2c_scan — a device on GPIO8 (SDA) and GPIO9 (SCL), plus 4.7k resistors from each line to 3V3. The internal pull-ups the driver enables are around 45k, which sometimes carries one device on a short breadboard bus at 100 kHz and is not enough beyond that.
pwm_fade — an LED and a 330R resistor from GPIO6 to ground, and optionally a servo signal wire on GPIO7. The onboard RGB LED cannot be used: it is a WS2812, which wants a serial data stream rather than a duty cycle.
Pin choices
The pins above are arbitrary. Nearly every one of these peripherals can appear
on nearly any pad, because none of them is hard-wired: a peripheral emits a
numbered signal and the GPIO matrix decides which pad carries it. Change the
#defines at the top of an example and it will work the same.
Two constraints on this board: GPIO33–GPIO37 are not broken out (they are the
PSRAM interface), and GPIO19/GPIO20 are the USB port. board_pins.h has the
full list.