# Expansion

The two connectors on a Kode Dot: the 20-pin header where modules and your circuits plug in, and the four magnetic pads that carry USB and power to a dock.

## What it is

Two ways to connect something to a Kode Dot without opening it.

The **expansion header** is a two-row header of 20 pins, 2.54 mm apart, the
pitch of every breadboard and jumper wire. It brings 14 of the P4's own GPIOs
out of the case, with 3.3 V, 5 V and ground beside them. It is where your own
hardware goes, and it is what every Kode module plugs into. The 14 pins are
the P4's, straight through: no expander, no multiplexer. Each one passes a
small series resistor and an ESD clamp on its way out, which protect the chip
from a static touch and nothing more.

The **magnetic connector** is four pads that a dock or a cable with pogo
pins snaps onto. It carries 5 V, ground and the P4's own USB, so a Kode Dot
on a dock charges and talks to a computer exactly as it does on the USB-C
cable. The charging base is one such dock: a passive USB-C passthrough.

## How it is connected

```mermaid
flowchart LR
  p4["ESP32-P4"] -- "GPIO8..GPIO21, 68 Ω + ESD each" --> hdr["20-pin header"]
  rail33["3.3 V, 2 A"] --> hdr
  rail5["5 V, fused 2 A"] --> hdr
  p4 -- "GPIO26 D-, GPIO27 D+, 68 Ω" --> mag["4 magnetic pads"]
  rail5 -- "fused 2 A, on the antenna board" --> mag
```

*Fourteen GPIOs and two rails on the header; USB and 5 V on the magnetic pads*

The header's 3.3 V rail is a buck of its own with 2 A to spare. Its 5 V is
the USB input, or the charger's boost when there is no cable, through a
resettable fuse. Three of the GPIOs, `GPIO8` to `GPIO10`, double as the lines
that flash the C5 through this header.

The magnetic pads are `GPIO26` and `GPIO27`, the P4's native USB data pair,
plus 5 V through a second fuse on the antenna board, and ground. All four
pass an ESD clamp. Power can go either way on that 5 V: a dock charges the
Kode Dot through it, and the charger's boost can put 5 V out on it.

## Specifications

The header:

| Thing | Value |
| --- | --- |
| Connector | 2 by 10, 2.54 mm pitch, right-angle female on the board |
| GPIOs | 14: `GPIO8` to `GPIO21` |
| Analog | `GPIO16` to `GPIO21` read on ADC1. The other eight are digital only |
| Per line | 68 Ω in series and an ESD clamp |
| 3.3 V | Two pins, from a 2 A buck. Always on |
| 5 V | Two pins, from USB or the charger's boost, through a 2 A resettable fuse. About 1.5 A at 60 °C inside the case |
| Ground | Two pins |
| Second job | `GPIO8`, `GPIO9`, `GPIO10` also flash the C5 through this header |
| Validated | `Kode-Dot-Val/14-EXPANSION`: all 14 GPIOs and both rails on a board |

Pin to signal. The numbering stops being sequential at pin 12, so read the
table rather than counting along the row.

| Pin | Signal | Pin | Signal |
| --: | --- | --: | --- |
| 1 | 5 V | 2 | 3.3 V |
| 3 | `GPIO8` | 4 | `GPIO9` |
| 5 | `GPIO10` | 6 | `GPIO11` |
| 7 | `GPIO12` | 8 | `GPIO13` |
| 9 | `GPIO14` | 10 | GND |
| 11 | GND | 12 | `GPIO21` |
| 13 | `GPIO19` | 14 | `GPIO20` |
| 15 | `GPIO17` | 16 | `GPIO18` |
| 17 | `GPIO15` | 18 | `GPIO16` |
| 19 | 3.3 V | 20 | 5 V |

The magnetic connector:

| Pad | Signal |
| --- | --- |
| 5 V | `+VBUS_5V`, through a 2 A resettable fuse on the antenna board. In and out |
| D− | `GPIO26`, the P4's native USB, through 68 Ω |
| D+ | `GPIO27`, the P4's native USB, through 68 Ω |
| GND | Ground |
| Which pad is which | **TBD**: the schematic gives the nets, not the layout |
| Dock | The charging base, KDBAS001: a USB-C receptacle wired straight to the four pads |

## Gotchas

> **WARNING**
>
> **A 5 V module works on the desk and dies when you unplug.** The header's
> 5 V is the USB input unless your firmware asks the charger to boost the
> battery onto it. Ask for the boost, see `device/power`, or the module is off
> on battery.

> **WARNING**
>
> **The pin that moved is not the one you set.** The header is numbered from
> its own side and the sequence breaks after pin 12. Wire by GPIO name and the
> table above, never by counting.

> **NOTE**
>
> **Something on `GPIO8` to `GPIO10` blocks flashing the C5 from the header.**
> Take it off before anyone reflashes the C5 that way.

## Apps that use it

On the marketplace, apps that put this part to work. Install one from
`start/first-app` and see it before you write a line.

- https://apps.kode.diy/app/bb9d0aee-914c-45b6-9395-49c3a5f6fbff
- https://apps.kode.diy/app/dbbf2b68-3e2c-4bba-9ae3-81122e839b00
- https://apps.kode.diy/app/d860a23e-8339-4d3f-98e8-d809eee501ab
- https://apps.kode.diy/app/8a8ba702-aba2-43ee-9ce2-23520afca103
- https://apps.kode.diy/app/3e9fda89-e638-47c8-849e-ba8b81fd380a

## Example code

Blink `GPIO12`, pin 7 of the header. Put an LED and a resistor from pin 7 to
pin 10 and it blinks once a second.

```c
/*
 * header_blink.c - 2026-09-18 - from Kode with love
 *
 * Blinks GPIO12, pin 7 of the Kode Dot's expansion header, once a second.
 * The pin is the P4's own, so this is the plain ESP-IDF GPIO call. An LED and
 * a resistor from pin 7 to pin 10 blink along.
 */
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

/* Output, then high and low forever. */
void app_main(void)
{
    gpio_set_direction(GPIO_NUM_12, GPIO_MODE_OUTPUT);

    while (1) {
        gpio_set_level(GPIO_NUM_12, 1);
        vTaskDelay(pdMS_TO_TICKS(500));
        gpio_set_level(GPIO_NUM_12, 0);
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}
```

Compiled on the date in the header with ESP-IDF v6.1. **TBD**: a run on a
V1 board.

## In the SDK

- [`khal_gpio_esp.c`](https://github.com/kodediy/kode-sdk/blob/main/components/khal/khal_gpio_esp.c): the GPIO layer in `kode-sdk`.
- `modules/overview`: what plugs into the header.
- [`charging_base`](https://github.com/kodediy/charging_base): the dock that uses the magnetic pads.
