diff options
| author | Gabriel Schneider <[email protected]> | 2026-08-26 12:40:03 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-26 12:40:03 -0300 |
| commit | fbc194068687e49a8490c85c9f1257a2f2bb9079 (patch) | |
| tree | 4fdb314f9e2c0e25bb1faca7e93fefe108023a66 /build | |
| parent | 3b8ee10301e0b83013a38d93516a345622a93aaa (diff) | |
| download | pardes-fbc194068687e49a8490c85c9f1257a2f2bb9079.tar.gz pardes-fbc194068687e49a8490c85c9f1257a2f2bb9079.zip | |
A Gpio word that flips one pin, JP1 drawn in ASCII, and these words only on the P4
## Gpio
`Gpio 33` flips one pad and answers on the message row with what it did:
GPIO 33: 0->1
GPIO 33: 1->0
Bare `Gpio` draws the header instead, because the first question about a header is which pins it
has. The pin number is DECIMAL and it is the only literal in board_memory.zig that is - every
other one is an address, and addresses come off datasheets and linker maps that print hex, which
is why that file made everything hex two commits ago. A GPIO number is not an address, it is part
of a NAME: the schematic says GPIO47, the datasheet's pin table says 47, and `Gpio 20` meaning pin
32 would be a trap laid for the one argument anybody types from memory.
## The toggle is the host's, not the editor's
New `Host.VTable.pull_gpio_toggle`, and a `GpioFn` in the p4 ABI (hence version 2), rather than
board_memory reaching for GPIO_OUT the way `Poke` two functions above it would happily do.
Writing that register is not the job. A pad has to be pointed at the GPIO function in the IO MUX,
routed in the GPIO matrix, given drive strength and an input buffer with its pulls cleared, and
only then driven - four register files behind a per-pin table. That code already exists in
`05-zig-p4/src/hal/gpio.zig`, it is the same `configureOutput` the blink demo has always used, and
its register numbers are checked against ESP-IDF's own headers on the die by `zig build diff`. A
second copy inside the editor object would be a second copy under no test, and getting it wrong on
a pin that boots as something else is how you lose the console you are typing on.
Reported levels are the OUTPUT bits, before and after, because that is what a toggle means: the
level this board is driving. A pad's input buffer on an unconnected header pin reads the air.
## JP1, read off the schematic rather than remembered
The diagram is the vendor's own wiring, from sheet 2 "Expand IO" of
`01-esp32p4-m3/docs/JC-ESP32P4-M3_schematic.pdf` - the only document that carries this mapping. The
specification PDF's "Interface Description" page turned out to be a marketing render, and there is
no board user guide; the chip datasheet has a package pinout, which is not a header.
That sheet is a 872x1168 raster (`pdfimages -list` - the PDF embeds no vectors, so rendering it
larger adds nothing), and at that size the rows around pin 14 are genuinely ambiguous by eye. So
the mapping came from the drawing's geometry instead: thirteen wires leave each side of the symbol,
a net wire runs ~100 px to its label and a power stub ~21 px. Pin 8's wire is 21 px, which is what
identifies it as unconnected rather than as the first of the GPIO4x labels - the reading that had
GPIO47 one row higher and shorted GPIO45 to the ground bracket.
Cross-checked against a second source that has been in the tree all along: `05-zig-p4/build.zig`
documents `-Dled=20` as "JP1 pin 17", and GPIO20 lands on pin 17 here. Both facts are asserted in
the test, so the diagram cannot drift from either.
## Peek, Poke, Hexdump and Gpio are now the P4 build's alone
`board_memory.enabled` was `os.tag == .freestanding and !isWasm()`, on the argument that these
words are a property of having no operating system rather than a product configuration, and that a
predicate spelled out of `builtin` cannot drift the way a hand-maintained enum can.
Tidy, and it answered the wrong question. A word only exists if some shell offers it, and the
shells are the platforms. `Gpio` settles it beyond argument: its whole content is one board's
header, and a second freestanding port would need its own pinout rather than inheriting this one.
"Bare metal" was never the requirement, "this board" was, and the two only looked identical
because there is currently one of them. The old predicate's real work was excluding wasm -
`freestanding` too, where an address is an offset into a linear memory the engine owns - and naming
`p4` excludes it by construction instead of by a term somebody has to keep remembering. The target
is now the witness rather than the gate.
Absent means not compiled: the tty binary contains no `+Gpio`, no `+Hexdump`, no `ES_I2C_SDA` and
no `MisalignedAddress`.
## The boot buffer's lines are checked, not eyeballed
Three times now a line in that tour has been one or two characters too long for a 56-column grid,
and every time it was found by reading the die's screen - the expensive way to measure a string
literal. The text is a named `boot_buffer` with a test over it, six lines came down to fit with
margin, and the tour gained `Gpio`.
Tests: the pinout's width, its thirteen aligned pin rows, GPIO20-on-17 and pin-8-unconnected; the
decimal-versus-hex distinction; every boot-buffer line. Full suite green - unit-test, snap 95/95,
hxdiff 481/0, hxparity 561/0, image-harness, pdf-harness, mupdf-check - and tty, p4, gui,
p4 at 80x24, p4 with the fade forced on. On the die `p4-bench --check` is 5/5, the fifth being a
new one: three `Gpio 33` runs must report 0->1, 1->0, 0->1, because the alternation is the only
oracle a hardcoded string could not fake.
Diffstat (limited to 'build')
0 files changed, 0 insertions, 0 deletions
