feat: add SPI extension documentation and integration details for Tiny SoC

- Introduced the separately approved SPI extension (2026-10-04) for the Tiny SoC, detailing the addition of SPI0 as a master-only controller with 8/16-bit capabilities.
- Updated documentation to reflect the SPI phases (SPI-P0 to SPI-P5) and their respective requirements, including DMA V2.2 pacing and fixed-MMIO requests.
- Specified GPIO assignments for SPI functionality, including the use of previously reserved Gen1 ALT routes.
- Clarified the integration boundaries and dependencies on existing R2 and PIO-lite phases, emphasizing the need for complete implementation before qualification.
- Documented the implications of SPI integration on existing GPIO and DMA channels, ensuring no additional resources are allocated without proper validation.
- Updated the verification ledgers to track pending evidence and implementation gaps for both SPI and PIO-lite extensions.
This commit is contained in:
maksyuki committed 2026-10-05 07:49:51 +08:00
1 parent dad28f0c39
commit 2a07ebcdb1
11 files changed
+1407 -28

No files matched your search

+6
View File
@@ -17,6 +17,12 @@ the root README and subsystem guides.
requests 14/15. Its `PIOLITE-P0..P5` phases preserve the historical
performance-only R2 boundary; the [verification ledger](ip/piolite-verification.md)
retains all implementation, application and physical evidence gaps.
- [Independent SPI/display master](ip/spi.md) freezes the separately approved
future Tiny controller, four Gen1 GPIO ALT additions, segmented CS/D/C,
packed 8/16-bit frames and DMA V2.2 requests16/17. Its stable `SPI-P0..P5`
order and [verification ledger](ip/spi-verification.md) distinguish sequential
snapshot/display/SD requirements from implementation and physical evidence;
the legacy XPI LCD path and prior R2/PIO phases remain separate.
- [Tiny Gen1 datasheet](../publications/datasheets/tiny/README.md) describes the
current 24 MHz implementation, registers, software and qualification boundary;
it does not yet describe the QFN64 Gen1 target.
+6
View File
@@ -13,6 +13,12 @@ implemented or enabled on Mini by this document. The historical I2S/DVP rules
below do not substitute for PIO-lite's packing, ownership or reset contract;
the existing [Crypto](ip/crypto.md) streams retain their own framing rules.
The separately frozen [Tiny SPI master](ip/spi.md) uses DMA V2.2 paced fixed
MMIO requests16/17, not new AXI4-Stream ports. Its source-qualified admission,
credits, R/B drain and exact serial-frame completion must not be substituted
with stream VALID/TLAST rules. PIO14/15 and the stream-direction count remain
unchanged by that SPI extension.
## Interface Contract
All three links use `DATA_WIDTH=32`, one-bit ID, destination, and user fields,
+205 -4
View File
@@ -34,6 +34,14 @@ are requirements for subsequent implementation, not delivered capabilities.
Mini is an affected compatibility consumer of shared DMA changes, not a
PIO-lite rollout target. Existing phase IDs and evidence remain unchanged.
The [SPI contract](spi.md) freezes the separate **TINY-only standard-product
SPI integration target** and the additive DMA V2.2 extension below. V2.2 adds
paced fixed-MMIO requests, not AXI4-Stream endpoints or an AXI master. It
preserves the V2.1 PIO request allocation and lifecycle obligations without
requiring the PIO block to be integrated before SPI. Neither extension is
implemented by the current V2.0 RTL/HAL. SPI phases own V2.2 implementation
and evidence; Mini remains a compatibility consumer with SPI disabled.
## Scope and limits
- Eight independent channel contexts share one AXI4 master (`ID=0`) in the
@@ -89,7 +97,7 @@ compares both definitions.
| Offset | Register | Access | Description |
| ---: | --- | --- | --- |
| `000` | `IP_ID` | RO | `DMA4` identification |
| `004` | `IP_VERSION` | RO | Current V2.0 `0x00020000`; frozen V2.1 target `0x00020001` |
| `004` | `IP_VERSION` | RO | Current V2.0 `0x00020000`; frozen V2.1 `0x00020001` and V2.2 `0x00020002` targets |
| `008` | `CAPABILITY` | RO | channel count, data width, maximum burst, stream count, descriptor=1 |
| `00c` | `GLOBAL_CTRL` | WO | bit 0 global reset |
| `010` | `GLOBAL_STATUS` | RO | any channel busy |
@@ -97,8 +105,8 @@ compares both definitions.
| `018` | `IRQ_ENABLE` | RW | one enable bit per channel |
| `01c` | `IRQ_TEST` | RW | software interrupt test bits |
| `020` | `ERROR_SUMMARY` | RO/W1C | bit 0 valid/W1C, bits 3:1 channel, bits 15:7 status, bits 31:16 error-address upper half |
| `024` | `REQUEST_STATUS` | RO | peripheral pacing availability |
| `028` | `SUPPORTED_REQUESTS` | RO | V2.1 target only: static implemented request bitmap; absent in V2.0 |
| `024` | `REQUEST_STATUS` | RO | live peripheral pacing availability; V2.2 extends the bitmap to 32 bits |
| `028` | `SUPPORTED_REQUESTS` | RO | V2.1/V2.2 targets: static implemented request bitmap; absent in V2.0 |
Each channel occupies `0x80` bytes beginning at `0x100 + channel * 0x80`.
@@ -108,7 +116,7 @@ Each channel occupies `0x80` bytes beginning at `0x100 + channel * 0x80`.
| `04` | `CH_CFG` | RW idle | kind, width, increment bits, priority |
| `08`, `0c` | `SRC_ADDR`, `DST_ADDR` | RW idle | source and destination addresses |
| `10` | `BYTE_COUNT` | RW idle | byte length; MM-to-MM permits a partial final beat, stream requests are word based |
| `14` | `REQUEST_SEL` | RW idle | software or peripheral selector |
| `14` | `REQUEST_SEL` | RW idle | software or peripheral selector; V2.0/V2.1 use bits 3:0, V2.2 uses bits 4:0 |
| `18` | `BURST_CFG` | RW idle | requested 1–16 beat maximum |
| `1c` | `EVENT_ENABLE` | RW | done, half, error interrupt enables |
| `20` | `STATUS` | RO | busy, suspended, done, aborted, error, incoming stream `TLAST` seen |
@@ -200,6 +208,10 @@ before start and after completion; no cache snoop or IOMMU is implied.
## Frozen V2.1 PIO-lite extension
This section preserves the V2.1 contract. V2.2 extends only its request
encoding and bitmap width as specified below; PIO endpoint IDs, transfer
kinds, binding and cancellation rules remain unchanged.
### Scope and discovery
V2.1 MUST retain the existing direct-register offsets, four-bit request
@@ -337,6 +349,195 @@ Tiny end-to-end and affected Mini regressions for the implemented phase. The
existing verification described below is baseline coverage; it does not
establish these new V2.1 properties or a new PIO frequency/physical result.
## Frozen V2.2 SPI extension
### Scope and compatibility
V2.2 MUST report `IP_VERSION=0x00020002`. It retains the `DMA4` identity,
4 KiB register aperture, all register offsets, 32-bit data path, eight-channel
Tiny target, one AXI master, aggregate IRQ20 and existing completion/error
semantics. Existing request IDs 0-15 and their transfer kinds MUST NOT change.
In particular, PIO-lite keeps 14/15; omitted I2C1 requests 9/10 remain
unsupported on the future Tiny integration and MUST NOT be reassigned.
| Request | ID | Transfer kind | Peripheral address and increments |
| --- | ---: | --- | --- |
| `SPI_TX` | 16 | MM-to-MM | Incrementing memory source to fixed SPI DMA-only TX FIFO address |
| `SPI_RX` | 17 | MM-to-MM | Fixed SPI DMA-only RX FIFO address to incrementing memory destination |
The SPI specification owns the exact FIFO offsets, segment configuration,
serial framing and pin lifecycle. SPI and its DMA request/admission interface
run in PCLK; the existing central-DMA AXI crossing to SYS is retained. No new
asynchronous stream, cyclic descriptor, narrow DMA width or private master is
introduced. Shared SPI ports and grants MUST default disabled. Mini keeps
SPI support bits clear, its current channel owners and its existing endpoints.
V2.2 MUST preserve valid legacy direct jobs and TCDs with the new request bit
clear. This compatibility does not make an extended job safe on older
hardware: current V2.0 hardware truncates direct request 16 to request 0 and
ignores the new TCD request bit. Software MUST check DMA identity/version,
product metadata, static request support and the SPI block capability before
programming a SPI job or publishing an extended TCD to DMA. An old version or
absent endpoint returns `RS_ENOTSUP` before channel programming; V2.0 MUST
also be rejected before reading its nonexistent `SUPPORTED_REQUESTS` offset.
Only V2.2 or an explicitly compatible later contract permits requests 16/17.
V2.2 inherits the V2.1 complete-job ownership and descriptor cancellation
requirements, including abort/error precedence over fetch and activation.
Implementing those shared-DMA obligations does not require a PIO instance;
PIO support bits remain clear until its own complete integration is present.
Existing PIO phase IDs and evidence requirements remain unchanged.
### Selector and discovery ABI
`REQUEST_SEL[4:0]` is the V2.2 request ID. Bits 31:5 are reserved zero and
MUST be checked before narrowing; a nonzero reserved field or unsupported ID
causes a channel configuration error without issuing its payload transaction.
IDs 18-31 are unassigned and MUST fail validation in this version.
TCD control bit 25 supplies request bit 4, while bits 15:12 retain request
bits 3:0. The request is `{control[25], control[15:12]}`. Kind 10:8, priority
17:16, burst 24:20, all other defined fields, and the 64-byte TCD
size/alignment are unchanged. Words 14/15 remain reserved. HAL request
encoding/decoding and validation MUST use this split field consistently;
shifting a five-bit ID into bit 12 would corrupt priority and is forbidden.
`RequestMask`, `REQUEST_STATUS` and `SUPPORTED_REQUESTS` use 32-bit request
bitmaps. Bits 16/17 describe SPI TX/RX; bits 31:18 read zero for V2.2. Static
support uses effective implementation, direction logic and actual wiring,
not a reservation or tied-off port. `SUPPORTED_REQUESTS` remains read-only
and static across runtime binding/closing; `REQUEST_STATUS` reports live
pacing availability and cannot establish support or ownership. Reset clears
SPI bindings and credits, so its live readiness bits are initially zero.
`CAPABILITY[30:28]` retains V2.1's exact population count of implemented
stream requests 1, 2, 11, 12, 13, 14 and 15, at most seven. SPI requests 16/17
are fixed-MMIO requests and MUST NOT increase that count. No extended
capability register or reinterpretation of this field is introduced. The
remaining capability fields keep their layout and encoding. Handwritten
SVH/C register constants, request values and TCD masks require parity checks.
### Endpoint admission and FIFO credits
The SPI block owns one explicit binding per DMA direction. Two enabled
bindings MUST select distinct implemented channels, reserved by the product
application profile. A binding owns the entire direct transfer or finite
TCD chain, including descriptor fetch/parse, non-SPI descriptors, suspension
and all accepted work through abort/error drain. No driver may steal a
binding during a FIFO-service gap. Rebind, disable, reset and new START
admission follow the V2.1 registered-binding and pending-START precedence
rules, independently of unrelated channels.
Direct START and every TCD activation MUST validate static request support,
the matching enabled channel binding, MM-to-MM kind, 32-bit DMA width, the
correct SPI DMA-only FIFO address, fixed peripheral address, incrementing
memory address, alignment, padded byte count and the armed segment's remaining
word budget. SPI requests used with another address, reversed increments or
a stream kind MUST fail before payload access. Descriptor reads needed to
identify an invalid job still drain normally. Enabling a binding alone does
not authorize FIFO access before its segment is armed. Conversely, any DMA
request or channel attempting the SPI DMA-only FIFO addresses without the
matching SPI request and binding MUST fail before issuing that access. This
includes SOFTWARE request 0 and non-SPI descriptors in a mixed chain.
CPU and DMA use separate FIFO access ports defined by the SPI specification.
While a DMA direction is bound, CPU FIFO service in that direction MUST be
rejected. A DMA-only port requires its matching admitted DMA transaction and
credit; a CPU access to that address MUST NOT consume the reservation.
Tiny's target fabric/bridge MUST carry a private latched DMA-origin qualifier
to the SPI APB wrapper through the same admission, CDC and response lifecycle
as the transaction. CPU and SDIO-private-DMA accesses to these ports return
an error. APB address and a live credit alone do not identify the initiator.
This private qualification adds no AXI master/ID and does not reinterpret
APB `PPROT` or introduce a general access-control subsystem. Ordinary SPI
control/status accesses remain subject to their documented access rules.
Each peripheral FIFO transaction reserves one TX slot or one RX word when
the DMA admits that transaction, before its AXI address is offered. The
reservation remains associated with the channel, direction, segment and
transaction through its terminal response. FIFO commit consumes that credit
exactly once. Pending admissions MUST be included in available capacity and
word-budget accounting; readiness is not an unreserved snapshot of `!full`
or `!empty`. Closing rejects further admissions. Existing reservations cannot
be stolen by another channel, CPU access, rebind or FIFO reset.
An admitted peripheral transaction MUST finish through bounded APB service
without waiting for SCK edges, FIFO production/consumption or a later CPU
action. Invalid/uncredited accesses return `PSLVERR` without FIFO mutation.
The SPI implementation supplies the local bound and the product verifies
its bridge/CDC behavior. No software/DMA FIFO loop may retain the DMA's sole
AXI write transaction while awaiting serial progress and thereby prevent
unrelated channels from draining.
### Packing, counts and completion
SPI DMA uses aligned full 32-bit words and full FIFO write strobes. For a
logical segment of `N` bytes, software validates checked arithmetic and
DMA-visible padded capacity for `4 * ceil(N / 4)` transport bytes. Zero
length, unsupported frame sizes or insufficient capacity fail before launch.
The SPI block unpacks four 8-bit frames or two 16-bit frames per FIFO word,
low lane first, with bit order defined by the SPI contract. Its exact logical
frame count suppresses padded tail lanes; DMA padding MUST NOT create extra
serial clocks, frames or CS transitions. RX pads the unused final lanes as
defined by SPI and writes only within the validated padded buffer. Arbitrary
short CPU packets use the CPU ports and do not imply narrow DMA support.
DMA `BYTE_COUNT`, progress, half and DONE count transport bytes. TX DMA DONE
means the FIFO writes and their responses completed, not that the final
serial frame left the shifter. RX DMA DONE requires the memory write
responses. SPI separately owns segment/transaction completion, exact frame
counts, D/C transitions and CS release after the final edge and hold interval.
Neither DMA DONE nor a TCD boundary may directly terminate CS. SPI completion
and DMA completion/error must both agree before successful session release.
Both the incrementing memory leg and fixed FIFO leg retain the current
single-beat scheduling for these requests. FIFO accesses use one-beat FIXED
transactions; memory accesses retain their proper incrementing addresses.
The MVP MUST measure this path, especially mapped-PSRAM command overhead,
rather than claim burst memory reads. A later, separately approved scheduling
optimization may decouple memory bursts from paced FIFO beats; it is not an
implicit part of V2.2. Native SPI AXI4-Stream endpoints remain deferred.
### Close, abort and reset
Closing first blocks new SPI admissions and new STARTs on the bound channels,
retains their bindings and records the SPI terminal error/abort state. The
SPI contract defines safe serial stop and CS timing. Every already admitted
FIFO operation must receive its terminal response: an operation committed
before closing retains its result; a pending uncommitted operation is
error-completed without changing FIFO contents. A closing endpoint MUST NOT
wait for serial progress or withdraw an accepted bus transaction.
Software aborts the bound channels and uses a bounded complete-job drain.
Accepted payload and descriptor reads drain through RLAST, writes through B;
canceled queued fetch/parse work cannot activate a descriptor or clear abort.
Only after those responses, all admission credits and complete ownership have
drained may the integration acknowledge endpoint reset, flush residual data,
change binding or gate clocks. A timeout retains the closed bindings and
buffer ownership and reports failure. It MUST NOT turn into successful reset,
memory reuse or a global DMA reset that disrupts unrelated channels.
### Required implementation evidence
The [SPI development order](spi.md) owns V2.2 gates. It starts with the
committed `configs/ci/ihp130-tiny.mk` / IHP130 baseline and explicitly enables
the future integration only in its applicable phase. Required checks include
legacy direct/TCD compatibility; old-version rejection before programming;
ID, version, register and TCD parity; request 16/17 and reserved-ID rejection;
truthful masks/counts; default-disabled Mini ports; correct FIFO addresses,
directions and bindings; and full-word packing with every legal tail length.
Exercise delayed FIFO requests/responses, CPU attempts on both port classes,
credit exhaustion, simultaneous START/rebind/reset, mixed TCD chains, suspend,
abort during fetch/parse/activation, close before/after FIFO commit, stopped
serial progress, timeout retention and unrelated-channel progress. Assertions
must cover stable accepted AXI payloads, exactly-once credit/word consumption,
no uncredited FIFO mutation, bounded endpoint response and no premature
binding/buffer release. Verify DMA DONE before final SPI edge without early
CS release and no padding on the wire. Reuse the shared-DMA host/parity/RTL/
formal checks and affected Tiny/Mini regressions; a reserved endpoint or a
passing old regression is not V2.2 evidence.
## Validation boundary
`tests/rtl/dma_error_tb.sv` uses a native AXI4 BFM for exact counts, 4 KiB
+70 -2
View File
@@ -15,6 +15,10 @@ reset values, ALT0/ALT1 assignments and lock semantics. This is not an ALT2,
new-pad, QFN64 change or a Mini PIO integration. Existing evidence and Tiny R2
phase IDs remain unchanged; PIO-lite has its own development order.
The separately frozen [SPI master](spi.md) adds four reserved Gen1 ALT routes
and native-owner readiness/session requirements below. This is also a future
Tiny integration, not a change to GPIO V2.0 register offsets or a Mini rollout.
## Integration
| Property | Value |
@@ -107,8 +111,10 @@ a change to a locked bit complete with `resp_err` and do not update state.
Software output and output-enable aliases avoid read-modify-write races. ALT0
and ALT1 outputs are selected per pin. Setting `USER_SELECT` changes the source
to `user_gpio_if`; every ownership transition forces the physical output
enable low for one complete SoC clock before the new owner can drive. Open
to `user_gpio_if`; every `USER_SELECT` transition forces the physical output
enable low for one complete SoC clock before the new owner can drive. Native
GPIO/ALT0/ALT1 changes do not receive that automatic handoff: disable the old
and new peripheral output drivers before changing those routes. Open
drain is applied after this mux: logical zero drives low, while logical one
releases the pad.
@@ -246,6 +252,68 @@ cannot hide selected pins from the RCU veto or restart a stale transport.
Check unrelated pins and affected Mini consumers throughout. The existing tests
below remain baseline evidence and do not establish these new PIO properties.
## Frozen Tiny SPI native ownership
The [SPI contract](spi.md) fills GPIO27 ALT0 SCK, GPIO28 ALT1 MOSI, GPIO30 ALT1
MISO and GPIO31 ALT1 CS_N after the approved Gen1 migration. In the display
personality GPIO30 is ordinary software D/C output, not MISO. All other Gen1
ALT definitions and dedicated boot/debug pads remain unchanged. Current
executable GPIO30/31 PWM capture routing is superseded only by the separately
approved R2-P6 Gen1 mapping, not by pretending it was unused.
SPI remains an ALT owner; PIO remains the sole USER owner and has mux priority.
SPI acquisition must reserve its complete session mask, check USER_LOCK and
CONFIG_LOCK, stop/drain conflicting native/PIO clients, and prepare safe
software GPIO fallback levels and disabled output drivers before changing
ALT. GPIO OUTPUT_ENABLE controls software output only; clearing it does not
stop an ALT peripheral's OE. Keep SPI OE0 until all native guards pass.
Export read-only USER handoff, ALT_ENABLE/ALT_SELECT and relevant pad/OE state
alongside USER_SELECT and GPIO lifecycle readiness to the Tiny SPI guard.
No new GPIO APB offsets or version are introduced. Native-ready requires
`USER_SELECT=0` and `handoff=0` on each session pin, the exact selected ALT or
D/C software mode, supported electrical configuration and running/released
GPIO. USER_STATUS=0 alone cannot establish readiness immediately after user
release. Guard the prospective mask before ENABLE and the latched mask after
it; unrelated PIO-owned pads do not block SPI.
SCK/MOSI/CS_N and D/C require push-pull mode, not OPEN_DRAIN, which GPIO applies
after mux selection. DISPLAY_DC reserves GPIO30 software-output mode and OE,
but permits its DATA_OUT level to change between clean segments. The HAL must
order/read back that write and honor setup/hold before clocking the next
segment. SPI never receives MISO from a D/C-configured pin. GPIO interrupts
and electrical changes on session pins require explicit coordination.
SPI receives the existing raw ALT MISO route and owns its synchronous external
capture timing; it does not use or change the USER input synchronizer/filter
pipeline. Input filtering therefore cannot be presented as SPI sampling-delay
compensation. Loss of active native routing/readiness suppresses SPI OE and
sampling, invalidates its transaction and closes DMA admission; restoring the
guard does not resume old data. Another owner may drive the pads, so this
does not grant SPI authority to clamp PIO or another peripheral's outputs.
SPI latches its session ownership from ENABLE through checked RELEASE, including
prefill, armed, held-CS, closing and disabled-awaiting-handback. DISABLE and
RECOVER retain that reservation. GPIO gate/reset veto is the OR of actual PIO
USER_SELECT ownership and latched SPI session ownership, including multi-target
commands. Resetting or clearing SPI configuration cannot conceal an unreleased
session. A whole-system reset remains the separate all-domain traffic reset.
Normal handback stops/drains the SPI segment and bound DMA, disables SPI OE,
prepares native software OE0/ALT-disabled state on the mask, verifies locks,
readback and handoff, then issues SPI RELEASE. Intentional handback while
SPI is safely DISABLED is allowed; it is not an active-route fault. On failure
retain the safe reservation and report the error. Do not reset GPIO to clear
locks or reactivate the old client automatically. Restore another peripheral
only through its explicit owner restart.
Required tests include all four routes, unchanged non-SPI rows, native versus
USER handoff, false USER_STATUS readiness, source driver OE sequencing,
pre-existing locks, D/C changes only at clean boundaries, raw MISO timing,
open-drain rejection, lost routing during DMA prefill, recovery ledger
retention, GPIO gate/reset veto and unchanged Mini/PIO behavior. These are
future requirements, not coverage supplied by historical GPIO tests.
## Pad capabilities
Digital functionality is identical for every PDK, but pad electrical controls
+143
View File
@@ -0,0 +1,143 @@
# SPI Verification and Evidence Ledger
This ledger accompanies [spi.md](spi.md), targeting TINY/IHP130 and the
approved `SPI-P0..P5` roadmap dated 2026-10-04. It records required evidence,
not existing hardware capability. At freeze, SPI RTL, DMA V2.2, native routing,
HAL/display software and physical qualification are not delivered. Historical
Tiny, SPI-SD, XPI, DMA and PIO evidence does not automatically cover this IP.
## Configuration and Identity
- Starting profile: `configs/ci/ihp130-tiny.mk`, TINY, IHP130, 24 MHz/no PLL,
current four-channel DMA and no SPI.
- Target: SPI0 at `0x1001D000`, IRQ25, RCU16; modes 0-3, 8/16-bit frames,
TX/RX 8x32, PCLK execution, GPIO27/28/30/31, DMA V2.2 requests 16/17.
- Gen1 native routes require the approved R2-P6 migration; higher PCLK and
lifecycle require R2-P7. Camera/PSRAM application cases require R2-P8/P9.
- Record source SHA, dependency/configuration digests, profile, PDK, variant,
tools, command/log/result paths, clocks/divider/mode/direction, FIFO owners,
buffer addresses/capacities/counts, panel/board models and limitations.
- Artifacts belong below the existing timestamped configuration-hash build
root. A dry-run, tied-off capability or skipped fixture is not evidence.
- Mini tests validate shared-DMA/GPIO compatibility with SPI support disabled.
Full qualification must use the same SPI/PIO-inclusive source and netlist
as any shared R2-P11/PIOLITE-P5 campaign.
## Required Case Matrix
All cases currently have status **required, not run**. Later phase records
must add scoped evidence without deleting unmet conditions.
| Case | Requirements | Required observation / phase |
| --- | --- | --- |
| SPI-V01 | SPI-01/03 | Modes 0-3, 8/16-bit frames, both bit orders, TX-only/full-duplex/RX-only, dummy values; independent pin BFM; P1 |
| SPI-V02 | SPI-03/04 | Exactly 2*FRAME_BITS edges, CPHA=0 final trailing edge, first-bit setup, divider 1/65535, CS delays 1/65535 and rejection of 0; P1 |
| SPI-V03 | SPI-02/04 | Low-lane-first order, counts 1/3/4/5 at 8 bits and 1/2/3 at 16 bits, nonzero TX padding ignored, RX padding zero, no extra wire frames; P1 |
| SPI-V04 | SPI-02/06 | Count 0 and checked round-up overflow, including FRAME_COUNT=0xFFFFFFFF at both widths; no ARM/state/payload effects on rejection; P1/P2 |
| SPI-V05 | SPI-02/04 | FIFO 0/1/7/8, simultaneous push/pop with frozen pre-edge rules, no mid-frame pause, RX capacity reservation and TX-only discard; P1 |
| SPI-V06 | SPI-03/04 | ARM before preload, START without data, HOLD_CS8-bit command to 16-bit pixels, clean/pending distinction, D/C setup/hold and explicit END; P1/P3 |
| SPI-V07 | SPI-02/07 | All CSR access/reset/field/source/owner checks, unsupported strobes/addresses, one-shot FIFO effects, SVH/C mirror and bounded APB responses; P1 |
| SPI-V08 | SPI-03/08 | ABORT at every wire state, bound independent of empty/full FIFO, emergency ownership-loss truncation, no success event for aborted transfer, set-over-W1C; P1/P2 |
| SPI-V09 | SPI-06 | Old selectors/TCDs unchanged, full 5-bit encode/decode and control 25, V2.0/V2.1 rejection before writes, 32-bit support/status and reserved 18..31 rejection; P2 |
| SPI-V10 | SPI-06 | Distinct bound channels, direct/finite TCD jobs, wrong address/kind/increment/count, default-disabled Mini, exact unchanged stream count; P2 |
| SPI-V11 | SPI-02/06 | CPU denied DMA aliases; central DMA denied CPU aliases/control; wrong-request/channel DMA denied its aliases; no credit stealing; P2/P3 |
| SPI-V12 | SPI-06/08 | Latched origin with AW/W and AR, CDC/backpressure, reserve-at-admission through R/B, bounded unavailable/closing FIFO error, CPU abort progress and unaffected DMA writes; P2/P3 |
| SPI-V13 | SPI-06/08 | DMA DONE before wire end, RX final B after wire end, exact quotas/tails, residual pending segment cannot ARM/rebind/change D/C/END; P2/P3 |
| SPI-V14 | SPI-06/08 | Descriptor fetch/parse/activation cancellation, simultaneous abort/start/rebind, suspended jobs, accepted-read/write drain and timeout ownership retention; P2 |
| SPI-V15 | SPI-05 | Exactly four Gen1 ALT additions, legacy PWM migration, other ALT/QFN/power pins unchanged, USER priority, native-ready handoff and raw MISO capture; P3 |
| SPI-V16 | SPI-05/08 | GPIO/ALT switch with old driver OE off, USER_STATUS0 while handoff active, locks/open-drain rejection, D/C ownership/mutable value, external CS bias model; P3 |
| SPI-V17 | SPI-05/08 | Route/readiness loss during prefill/armed/held/closing, RECOVER and DISABLE retain session, verified handback RELEASE, no auto restart or hidden global reset; P3 |
| SPI-V18 | SPI-03/08 | GPIO/SPI gate/reset and PCLK-change veto while session retained, multi-target requests, WFI/debug/hart reset, new clock rediscovery and no stale epoch; P3 |
| SPI-V19 | SPI-07 | HAL64-bit length math, alignment/capacity canaries, timeout/lock/error propagation, CPU full-duplex simultaneous service and no heap; P3/P4 |
| SPI-V20 | SPI-04/09 | Panel color bars/gradients and odd rectangles, command/data timing, 8-to-16-bit packing, cold reset/init/rotation, error injection and exact pixel oracle; P4 |
| SPI-V21 | SPI-09/10 | 153600-byte QVGA frame in initialized PSRAM, DVP validity/final-write drain, data/pixel/save checksums and sequential resource handoff; P4 |
| SPI-V22 | SPI-06/09/10 | SRAM versus PSRAM source timing, CPU cycles, wire utilization, FIFO/longest-service gaps, unrelated channel/PIO and existing XPI LCD regressions; P4 |
| SPI-V23 | SPI-03/05/10 | Block/full synthesis, FIFO mapping, netlist, reset/CDC/RDC, MISO/output PVT timing, Pad/board/package/power qualification; P5 |
The BFM must decode observed pins independently of the DUT shifter/model code.
Directed recovery cases must include initial ENABLE's inactive gap without a
spurious DONE, normal DISABLE revoking both bindings, pending DMA admission
preventing teardown, fault/ABORT versus START/FIFO ordering, and emergency
wire-close plus RECOVER with a persistently invalid route. Verify RECOVER
does not immediately re-fault while performing DISABLED GPIO handback.
Assertions/formal cover finite quota/credit conservation, stable origin and
response ownership, no stolen FIFO word, no next frame after close, legal FSM,
no stale descriptor activation, and source/clock isolation. State proof bounds
and external-response fairness assumptions; formal digital properties do not
establish analog CDC/Pad safety or arbitrary board/device liveness.
## Application Acceptance
Use an ST7789VI-style four-wire display reference in 320x240 landscape RGB565,
not the legacy 240x135/GPIO2/XPI transport. No display MISO, TE, touch or GPIO
backlight control is assumed. A separate general SPI profile covers MISO and
all four modes; the display profile uses GPIO30 D/C and validates its own mode.
1. Independent SPI slave BFM: deterministic/ramp/pseudorandom words, short
transfers, RX-only dummy clocks, TX-only discard, stalls and held-CS chains.
2. Display-only patterns: color bars, gradients, odd widths/pixel counts,
window endpoints and byte/pixel order. Framebuffer/pixel capture from the
panel model must match the reference, not just an APB or DMA byte counter.
3. PSRAM-source display: initialized and capacity-checked NSS1, immutable
source buffer, explicit aligned/padded extent, measured single-beat cost.
4. Sequential snapshot: DVP capture -> full frame/DMA-write validation ->
PSRAM readback/optional bounded processing -> SPI display -> SD save and
data verification. Use 153600 logical bytes for 320x240 RGB565. Keep the
source owned and immutable until display/save complete; no hidden 150 KiB
buffer in 128 KiB SRAM and no simultaneous next-frame capture requirement.
Record actual configured/readable SCK, frame time, CPU cycles, DMA stalls,
FIFO high/low watermarks and qualified device limits. Run PCLK 24 first;
PCLK 48/60 cases await executable R2 profiles and physical inputs. Ideal
12/24/30 MHz ceilings and pixel-only timing arithmetic are not measured FPS.
Legacy LCD/LVGL behavior, PIO14/15 and unaffected Tiny/Mini users must remain
separate compatibility checks, not silently moved to SPI.
## Commands and Verdicts
Documentation freeze checks use:
```sh
git diff --check
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc TINY --dry-run
python3 scripts/regress.py --root . --suite nightly --soc TINY --dry-run
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc MINI --dry-run
```
Verify local links/anchors, newly added files' whitespace, documented profile
and commands, unchanged phase IDs/package, and exactly the four authorized ALT
cell changes. These commands do not compile or simulate SPI.
P1/P2 add focused tests and existing lint/style/formal/synthesis integration;
do not invent working Make targets before those phases land. P3/P4 use the
main specification's SDK, firmware and regression commands plus affected
DMA/GPIO cases. Both Verilator and Icarus exercise pin-level protocol and
recovery. Tiny success requires exit 0, TEST_STATUS/`SIM_TEST_PASS` and no
`FAILED`, `FATAL`, `assertion failed`, `%Error`, `SIM_TEST_FAIL` or
`SIM_TEST_TIMEOUT`. UART output is diagnostic only. Mini retains its own
configured verdict; never substitute Mini coverage for missing Tiny support.
## Freeze Record and Gaps
| Phase | Evidence status |
| --- | --- |
| SPI-P0 | Documentation freeze complete; link/anchor, command dry-run, phase/package/ALT structure and whitespace checks passed on 2026-10-04 |
| SPI-P1 | Not started; standalone RTL/model, CSR mirror, BFM and synthesis evidence absent |
| SPI-P2 | Not started; V2.2 request/credit/cancellation implementation and shared compatibility evidence absent |
| SPI-P3 | Not started; actual routing/source qualification/GPIO/RCU/HAL integration absent |
| SPI-P4 | Not started; panel adapter, pixel oracle, snapshot/save and performance evidence absent |
| SPI-P5 | Not started; SPI/PIO-inclusive physical, Pad/package and silicon qualification absent |
Executed P0 checks: `git diff --check`; 151 local Markdown links and two
anchors; new-file ASCII/fence/whitespace validation; all 25 existing Tiny/R2
phase headings and the complete QFN64 package section unchanged; 32 GPIO rows
with only four approved reserved ALT cells filled; PIO-lite specification and
ledger unchanged; all 11 changed/added files are Markdown. The three regression
dry-runs above passed using the local `python` executable. Independent
specification review closed the completion, credit, binding-release and
emergency-recovery ambiguities; that review is not behavioral validation.
No implementation, full regression, EDA or silicon result is implied by P0.
No MISRA deviation, warning-baseline update, metrics promotion, new dependency,
PDK or security/safety claim is approved. Later records must retain missing
tool/model/Pad/macro/board evidence and the exact claim it prevents.
+698
View File
@@ -0,0 +1,698 @@
# Tiny Independent SPI Master and Display Interface
## Purpose and Research Boundary
This is the approved `spi` design freeze dated 2026-10-04 for **TINY only**.
The controller is a future standard Tiny product feature, not implemented
hardware or qualified silicon. `SPI-P0` delivers documentation only; P1-P5
require separate implementation approval and evidence. The authoritative
product, sharing and process inputs are [Tiny](tiny-soc.md), [DMA](dma.md),
[GPIO](gpio.md), [PIO-lite](piolite.md),
[engineering](../engineering.md) and [RTL policy](../rtl-coding-style.md).
The problem is to drive a display without placing its serial traffic on the
physical XPI bus used by boot NOR and optional PSRAM. SPI payload reads from
PSRAM still use XPI and contend there; a separate screen clock/data bus does
not eliminate framebuffer-memory cost. The first application is sequential
capture, verify, display and SD save, not simultaneous double-buffer video.
The committed profile remains 24 MHz/no PLL, four-channel DMA and no SPI.
Eight DMA channels, the Gen1 pin map, faster PCLK and new IP are target
contracts. This freeze does not change RTL, firmware, profiles, dependencies,
warning baselines, metrics policy or readiness. It does not implement a new
GUI framework or replace the legacy XPI LCD transport.
## Target SoCs and Integration Scope
| Item | Frozen contract |
| --- | --- |
| Target / status | TINY future standard product; MINI/STD/PRO integration deferred |
| Starting profile / PDK | `configs/ci/ihp130-tiny.mk` / IHP130, existing 24 MHz/no-PLL baseline |
| Product sources | `rtl/tiny/top`, `rtl/tiny/integration/soc_topology.json`, `clock_reset_domains.json`, `rtl/tiny/address_map/memory_map.json`, `rtl/tiny/pin_map/pin_map.json` |
| Filelists | Existing `rtl/tiny/filelist` ownership, especially `ip.fl`, `inc.fl`, `top.fl` and `tb.fl` |
| Instance / control | SPI0, APB4 `0x1001D000..0x1001DFFF`, 32-bit aligned control/FIFO words |
| IRQ / lifecycle | Tiny CPU IRQ25 and Tiny RCU target 16, additive allocations only |
| DMA | Shared V2.2, `SPI_TX=16`, `SPI_RX=17`, paced fixed-MMIO; no private AXI master or new stream endpoint |
| Pins | GPIO27 ALT0 SCK, GPIO28 ALT1 MOSI, GPIO30 ALT1 MISO, GPIO31 ALT1 CS_N; display uses GPIO30 ordinary output for D/C instead of MISO |
| Clock | PCLK for APB, core, packing/FIFOs and DMA pacing; SCK is an output, not an internal clock domain |
| SDK / application | New `rs_spi_*` freestanding HAL; Tiny display adapter in `app/board`, scenarios in existing application composition |
Preserve QFN64 and Pad count, 128 KiB main SRAM, same-frequency CPU/main-SRAM
SYS, private Crypto storage, eight-channel DMA target and three external AXI
owners. The two new 8x32 FIFOs contain 64 B local payload storage, not an
allocation from user SRAM. No managed dependency upgrade is approved.
The Gen1 map already moves legacy PWM capture from GPIO30/31 ALT1 to GPIO24/25
ALT0. SPI fills four reserved **Gen1** ALT cells only after TINY-R2-P6 implements
that routing. Current executable GPIO30/31 are not silently repurposed.
TINY-R2-P7 supplies qualified lifecycle/domain integration. Mini is a shared
DMA/GPIO compatibility consumer, not a new SPI product rollout.
R2's original performance-only scope and all TINY/PIOLITE phase IDs and titles
remain unchanged. This separate feature approval extends the future product.
Full extended-product release needs the actual SPI/PIO-inclusive netlist and
source evidence, not an earlier R2 result relabeled as covering new logic.
## Commercial References
The research was checked on 2026-10-04. Reuse architecture lessons, not vendor
RTL, binary ABI, clock limits, PPA figures or qualification claims.
| Primary reference | Evidence and selected lesson |
| --- | --- |
| [RP2040 datasheet, section 4.4](https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf), build 2025-02-20 | Modes 0-3, 4-16-bit frames, separate 8x16 FIFOs and DMA demonstrate a small MCU controller. Its CPHA=0 hardware-CS word pulses are not adopted: Tiny CS is transaction controlled. Slave/TI/Microwire modes are outside this MVP. |
| [ST AN5543](https://www.st.com/resource/en/application_note/an5543-enhanced-methods-to-handle-spi-communication-on-stm32-devices-stmicroelectronics.pdf), Rev 5 November 2025 | Exact counters, FIFO/packing boundaries and distinct DMA versus BSY/EOT/TXC completion motivate explicit wire and transport status. Peripheral-clock arithmetic is not external-pad qualification. |
| [NXP MCXA153 SDK](https://mcuxpresso.nxp.com/mcuxsdk/latest/html/api/devices/MCXA153/index.html), SDK 26.09 | Continuous PCS, programmable CS delays, FIFO/DMA and separate completion events inform the transaction API. The current [MCX A data sheet](https://www.nxp.com/docs/en/data-sheet/MCXAP064M096F30.pdf), Rev 5.2 May 2026, makes SPI limits pad/mode dependent; those rates are not Tiny targets. Exact login-gated reference-manual stall semantics were not verified. |
| [Newhaven ST7789VI module](https://newhavendisplay.com/content/specs/NHD-2.4-240320CF-BSXV-FT.pdf), Rev 4 November 2023 | A 240x320 panel documents 4-wire 8-bit command/data SPI, separate D/C, optional MISO, reset and external backlight power. It provides a concrete 320x240 landscape RGB565 reference without promising pin-free reset/backlight/TE/readback. |
These vendor documentation/product families were active at the research date.
No reference establishes Tiny area, power, MTBF, Pad rate, display compatibility
or IHP130 timing closure. The existing [SPI-SD](spisd.md) is a mode 0 SD host
with its own protocol/private DMA, not this general SPI controller. Reuse
owned Common registers/FIFOs and single-clock phase-enable conventions without
changing SPI-SD or XPI's ABI or adopting their unrelated command machinery.
## Requirements and Non-goals
| ID | Normative requirement |
| --- | --- |
| SPI-01 | MUST provide one single-lane SDR master, modes 0-3, 8/16-bit frames, MSB/LSB first, TX-only, full-duplex and dummy-TX RX-only. |
| SPI-02 | MUST provide separate TX/RX 8x32 FIFOs, bounded APB access, exact packing/tail rules and CPU/DMA ownership. |
| SPI-03 | MUST run in PCLK, generate SCK with integer enables, count wire frames and distinguish segment, CS and DMA completion. |
| SPI-04 | MUST support retained-CS command/data segments with checked software D/C changes, no partial-frame starvation or fake data. |
| SPI-05 | MUST preserve the package and existing non-reserved Gen1 ALT assignments; native-ready and retained session ownership guard all activity. |
| SPI-06 | MUST use compatible DMA V2.2 requests 16/17, static discovery, source-qualified reserved MMIO credits and full job/descriptor drain. |
| SPI-07 | MUST expose a handwritten SVH/C ABI mirror, bounded `rs_status_t` HAL and static caller-owned buffers; preserve the old XPI LCD path. |
| SPI-08 | MUST close admission on error/abort, preserve accepted bus responses, retain ownership on timeout and require explicit recovery/reacquisition. |
| SPI-09 | MUST validate generic SPI and sequential QVGA capture/verify/display/SD data integrity without claiming a whole frame fits in main SRAM. |
| SPI-10 | MUST bind functional/performance/physical evidence to source, product, profile, PDK, clocks and board/slave constraints. |
DEFER slave, 9-bit/in-band D/C, three-wire bidirectional SPI, dual/quad, XIP,
CRC, I2S, multiple hardware chip selects, display command queues, strict
gapless SCK guarantees and autonomous low-power operation. Also defer
simultaneous capture/display, full-profile external PIO demonstrations,
SPI-specific burst-prefetch optimization, other PDKs and other SoC rollouts.
MUST NOT add a DMA channel/master or assume unused GPIO for reset/backlight/TE.
No architecture question blocks P1; unqualified operating points remain gates.
## Selected Architecture
### Module and data flow
Planned owned modules are `apb4_spi`, `spi_reg`, `spi_master_core`,
`spi_phase_ctrl`, `spi_word_packer`, `spi_dma_pacing` and `spi_gpio_guard`.
`spi_ctrl_if` is the new internal interface; do not repurpose the existing
SPI-SD `spi_if` contract. Names describe future sources, not current filelists.
CPU/DMA word ports feed TX FIFO and a low-lane-first unpacker, then an 8/16-bit
shifter and registered SCK/MOSI/CS outputs. The raw alternate MISO input enters
the controller's clock-enable capture path and RX packer/FIFO. FIFO payload
arrays are small local register/inferred stores; valid state, not reset of
every payload bit, hides old data. Synthesis must confirm the intended mapping.
CPU and central DMA are exclusive per FIFO direction. TX-only never places
MISO data in RX FIFO. RX-only generates the configured dummy frame and needs
no TX FIFO word. Full-duplex consumes and produces the same number of frames;
MISO must be enabled for either receive mode.
### Session, arm and segment sequencing
ENABLE establishes a latched session/pin reservation after native-ready checks,
drives CS inactive/SCK=CPOL and applies CS_INACTIVE before entering IDLE. This
initial GAP does not emit DONE. Configuration/pin preparation must
precede ENABLE. No FIFO transfer implicitly claims pins.
ARM latches FRAME_COUNT, frame width, direction, dummy value, HOLD_CS and FIFO
owners before any preload or DMA admission. It requires a positive count,
valid derived lengths, an IDLE or clean HELD boundary, empty FIFOs/packers and
fully drained old jobs/credits. TX-only requires RX binding off; RX-only
requires TX binding off. It resets per-segment counts and opens only the
directions the segment uses. CPU prefill and DMA start are allowed after ARM.
START accepts only ARMED, asserts CS if needed, applies setup delay and starts
the finite segment. It may wait for the first TX word or RX capacity without
generating clocks. Exactly FRAME_COUNT frames are transmitted. After the last
frame and hold time, SEGMENT_DONE is set. HOLD_CS=1 enters HELD with CS active;
HOLD_CS=0 deasserts CS, completes the inactive gap and sets DONE in IDLE.
END from a clean HELD boundary releases CS and applies the inactive gap.
Wire state and SEGMENT_PENDING are distinct. A segment remains pending after
its last wire edge while RX data, packers, FIFO data, DMA jobs, reserved credits
or accepted responses remain. It becomes clean only when its successful wire
completion and all data/transport obligations are satisfied. CPU RX service
and bound RX DMA may therefore continue after SEGMENT_DONE/DONE. A new ARM,
owner/configuration change, D/C change or END cannot bypass pending cleanup.
Across clean HELD boundaries only SEG_CONFIG, FRAME_COUNT, DUMMY and idle
DMA bindings may change. CPOL/CPHA, bit order, divider, all CS delays and
MISO-versus-display pin personality remain fixed for the session. Every
segment applies setup delay before its first edge, including held-CS segments,
so checked D/C changes can meet setup time. Segment hold time precedes
SEGMENT_DONE and also protects D/C hold. Software serializes the complete
session, not isolated FIFO writes; there is no hardware descriptor for D/C.
### Serial timing and starvation
DIV=N is 1..65535; `SCK_HZ=PCLK_HZ/(2*N)`. Outputs are registered in PCLK;
SCK is never used as an internal clock. The leading edge moves SCK away from
CPOL, and the trailing edge returns it. CPHA=0 presents the first MOSI bit
before the first leading edge, samples on leading edges and advances output
on trailing edges. CPHA=1 launches on leading and samples on trailing edges.
Both modes complete a frame only after exactly `2*FRAME_BITS` transitions,
including CPHA=0's final trailing edge after its final sample.
CS_SETUP, CS_HOLD and CS_INACTIVE are 1..65535 PCLK periods, reset 1. No first
SCK edge occurs earlier than CS_SETUP after START; frame preparation may add
delay, and each active half-period is at least N periods. The hold timer starts
only after the final trailing edge. CS_INACTIVE is counted from deassertion.
No output/clock edge is generated by a rejected command or timing write.
Before each frame reserve its complete TX data and potential RX word slot.
At a frame boundary, insufficient TX data or RX capacity pauses SCK at CPOL
with CS asserted; do not begin a frame that would later overflow its RX word.
The current frame never stretches internally because FIFO service is late.
RX-only can stall for RX capacity; TX-only ignores RX. Pauses can be arbitrarily
long until software timeout/ABORT, so devices with bounded interframe gaps
need separate qualification and are not promised gapless service.
FIFO eligibility uses pre-edge occupancy, without empty fall-through or full
look-ahead. At full, a push is ineligible even if a same-edge pop occurs; at
empty a pop is ineligible even if data arrives on that edge. At intermediate
levels simultaneous eligible push/pop preserves level and removes the old head.
STALL flags count waiting at frame boundaries, not intentional setup/hold gaps.
## Interfaces
### APB4 and source-qualified word ports
The APB4 target uses 32-bit data, little-endian aligned words, full-word writes
(`PSTRB=0xF`) and the repository registered response convention. Unmapped,
unaligned, partial-strobe, wrong-direction, reserved-bit and illegal-state
accesses return PSLVERR without the requested side effect. Reserved read bits
are zero. Each accepted access acts once, not once per cycle of PSEL.
FIFO accesses never wait for SCK or an external device. A CPU full-TX write or
empty-RX read returns bounded error. A qualified DMA access consumes its
reserved credit or error-completes if closing invalidated it; it cannot wait
for a future byte. This includes pending accesses at abort, allowing CPU
control and the central DMA's other writes to make progress.
Four aliases separate CPU_TXDATA/CPU_RXDATA from DMA_TXDATA/DMA_RXDATA.
Separation by address alone is insufficient. Tiny fabric/bridge integration
must deliver private latched request-origin qualification (CPU, central DMA,
other) to the SPI wrapper. CPU may use control/CPU ports but never DMA aliases;
central DMA may use only its properly credited DMA aliases; other origins
are rejected. Thus request 0 cannot bypass ownership through a CPU FIFO alias.
Capture origin with actual AXI admission, keep AW-origin associated with its
write data, and retain it through APB bridging, CDC and response backpressure.
Do not use a current arbiter grant, mutable channel register or untrusted
PPROT as origin. This private target qualifier adds no AXI master or ID and
does not replace the SoC's general access policy. P1/P2 test it as a standalone
interface; P3 must wire it through the real Tiny path before advertising DMA.
SPI has no AXI memory interface. Central DMA retains 32-bit data, at most one
read and one write outstanding, existing response/order rules and 4 KiB burst
boundaries. For this MVP, fixed-MMIO jobs retain the current single-beat policy
on both legs; a PSRAM source can incur one XPI serial setup per word. No
prefetch/stream performance is claimed by this document.
### Packing, quotas and tails
Derive in checked 64-bit arithmetic:
```text
payload_bytes = FRAME_COUNT * (FRAME_BITS / 8)
transport_words = (payload_bytes + 3) / 4
transport_bytes = 4 * transport_words
```
ARM rejects zero count or transport_bytes greater than `0xFFFFFFFC`, before
changing state or authorizing payload. This applies to CPU and DMA modes so
register counters cannot wrap. Count `0xFFFFFFFF` is invalid in both widths:
even 8-bit mode rounds beyond 32-bit DMA capacity. TX-only has no RX quota;
RX-only has no TX quota. Enabled-direction quotas equal transport_words.
Each TX word supplies low byte first in 8-bit mode or low halfword first in
16-bit mode. Frame bit order is separately selected. RX places the first
received frame in the corresponding low lane. A final partial TX word's
unused lanes are ignored regardless of value and produce no extra frame or
clock. The final RX word zero-fills unused high lanes and is published after
its final frame completes; unused packer state is cleared at the boundary.
Accepted plus reserved TX words cannot exceed the segment quota. RX removals
cannot exceed produced words or its quota. CPU/DMA attempts beyond quota error;
surplus data cannot become the next segment's first word. Increment successful
CPU/qualified APB enqueue/pop counters once; credit reservations remain
separate from FIFO acceptance and release only with terminal bus completion.
DMA uses 32-bit width and transport_bytes, not the unrounded payload length.
Buffers must be 4-byte aligned with explicit accessible capacity at least
transport_bytes; TX padding must be initialized and readable, RX padding is
within caller-owned storage. Reject inadequate or unaligned DMA buffers; do
not implicitly overread, overwrite an adjacent object or allocate a hidden
whole-frame bounce buffer. CPU helpers handle arbitrary short 8/16-bit packets.
For RGB565, a low-halfword-first word contains pixel 0 in `[15:0]` and pixel 1
in `[31:16]`;16-bit MSB-first sends each pixel's high byte then low byte.
The panel still parses ordinary 8-bit data bytes with D/C high. Validate DVP
sensor byte-order configuration and host pixel layout instead of blindly
reusing the legacy LCD driver's high-halfword-first conversion.
### GPIO, board and D/C ownership
The fixed Tiny routes are 27/ALT0 SCK, 28/ALT1 MOSI, 30/ALT1 MISO and 31/ALT1 CS_N.
MISO_ENABLE reserves the receive route; DISPLAY_DC instead reserves GPIO30 as
ordinary push-pull software output. The two personalities are mutually
exclusive. Without either, TX-only SPI uses 27/28/31. Core route capability is
`0xD8000000`; the latched session mask reflects the selected personality.
Acquire via checked board/HAL ownership. Stop and drain conflicting PIO,
I2C alternate route, CLKOUT and XPI CS2/3 users; reject incompatible locks and
external drivers. Preserve GPIO29 NSS1 and dedicated boot/debug pins. Prepare
the prior native driver's OE inactive and SPI OE0 before changing ALT. GPIO's
automatic one-PCLK handoff applies to USER_SELECT transitions, not arbitrary
GPIO/ALT0/ALT1 changes; OUTPUT_ENABLE=0 alone does not disable an ALT driver.
Prepare safe CS-high/SCK-CPOL software fallback, change routes with drivers
disabled, and verify stable routing before ENABLE.
Read-only integration status must include USER_SELECT, USER handoff mask,
ALT_ENABLE/ALT_SELECT, relevant electrical/OE state and GPIO clock/reset
readiness. Native-ready for the session requires USER_SELECT=0 and handoff=0
on those pins, correct routes and push-pull drive (OPEN_DRAIN=0). Checking
USER_STATUS=0 alone is insufficient during USER-to-native handoff. D/C must
remain ordinary software output with OE enabled; its value is intentionally
mutable between clean segments, not an immutable guard field.
PIO remains the sole USER owner and retains mux priority; SPI is an ALT owner.
Continuous guards cover prefill, DMA-armed, active, held-CS and closing sessions.
Loss suppresses SPI's own OE/sampling, closes admission and latches fault;
another GPIO owner may still drive the pad, so this is not a claim that SPI can
force every owner high-impedance. Guard restoration never resumes stale work.
GPIO30 D/C changes occur through checked GPIO access only at a clean segment
boundary, with ordering/readback before the next START/setup delay. HAL owns
this ordering; arbitrary same-hart GPIO writes are not a security boundary.
GPIO interrupts/electrical changes on session pins require coordination.
The complete camera profile plus write-only display uses all 32 GPIO. General
SPI full-duplex and the write-only display are different pin personalities;
do not promise LCD MISO alongside D/C without another released pin. Reference
board reset is shared only with compatible panel power/reset timing; backlight
uses an external fixed current driver, not an SoC Pad. TE/touch/backlight PWM
are not MVP features. IHP130 lacks internal pull-ups: CS needs an external
inactive-high bias during reset and handoff. No board schematic is qualified
merely by this allocation.
## DMA and Interrupt Contract
### V2.2 and channel ownership
[DMA V2.2](dma.md#frozen-v22-spi-extension) is normative for shared
encoding: IP_VERSION `0x00020002`, `SPI_TX=16`/`SPI_RX=17` as MM_TO_MM, direct 5-bit
selector, TCD low request bits `[15:12]` plus high bit `control[25]`, unchanged
64 B TCD size/alignment/priority/burst fields. Request masks/status/support
become 32-bit;18..31 are reserved/unsupported. Requests 0..15 and PIO14/15 retain
meaning. SPI adds no stream endpoint, so the V2.1 stream-direction count stays
at most 7. Mini defaults SPI support off.
Probe DMA major 2/minor>=2 and the requested static support bit before writing
extended configuration or submitting a TCD. Older hardware can alias 16 to 0
or ignore bit 25; never rely on its eventual payload error. Old valid jobs
remain valid on V2.2; this is not forward compatibility of new jobs with V2.0.
No unknown future major is assumed compatible.
TX_BIND/RX_BIND each select one implemented channel and enable. Two enabled
bindings use distinct channels. Default TX borrows 3 only after bulk/PIO release;
RX borrows 2 only after DVP/PIO release. Full-duplex with active camera is not
required. Keep UART/I2C and Crypto/audio reservations; no hidden channel theft.
Binding changes require a clean IDLE/HELD boundary and complete old/new job
drain. An accepted DMA START locks the registered binding and rejects a
simultaneous rebind. The whole chain belongs to the SPI session, including
descriptor fetch/parse/suspend; it cannot contain another client's work.
SPI-P2 must inherit/implement the V2.1 complete descriptor-cancellation and
drain obligations; it need not wait for the whole PIO peripheral to be
integrated. This shared prerequisite does not mark PIOLITE-P3 complete.
### MMIO credits and completion
ARM fixes the enabled directions, FIFO owners and finite quotas. Only an armed
segment with valid GPIO/session state grants the bound channel SPI admission.
TX requires incrementing memory source and fixed DMA_TXDATA destination;
RX requires fixed DMA_RXDATA source and incrementing memory destination.
Addresses, 32-bit width, positive word-multiple count and remaining quota must
match. Other requests/channels targeting either DMA alias must be rejected,
not merely the wrong configuration of requests 16/17. Payload count across
the owned job cannot exceed the segment's remaining transport words.
Pacing readiness reserves one word at actual DMA transaction admission.
Exclusive ownership and pending-credit accounting preserve that slot/data
until the qualified APB access acts; the reservation remains tracked through
R/B completion. DMA's private address/request/channel check and the wrapper's
latched source qualifier must both agree. A credit is not permission for an
arbitrary CPU/SDIO access to consume it. Rebind/reset cannot occur while an
accepted request or its terminal response remains.
On close, stop new admissions. Already accepted writes/reads complete or
error-complete boundedly without waiting for serial data; do not fabricate RX
payload. Drain AXI/APB requests and responses plus descriptors before flushing
FIFO/packer state. This is fixed MMIO, not AXI4-Stream: no stream VALID reset
exception may replace accepted R/B completion.
Transfer success requires exact wire frames, exact word quotas, expected empty
tails, no error, and successful DMA completion including final memory responses.
Display D/C transitions also wait for this clean boundary. Transaction success
additionally requires DONE after CS release/gap. Failed partial buffers may
be reclaimed after full drain/recovery but cannot be published as valid data.
### IRQ and diagnostics
IRQ_STATE bits 0..5 are sticky SEGMENT_DONE, DONE, ABORTED, FAULT, TX_STALL and
RX_STALL. IRQ_ENABLE has the same bits plus bit 8 TX level<=TX_LOW and bit 9 RX
level>=RX_HIGH. IRQ_STATUS is the enabled sticky/level combination; its nonzero
value drives Tiny IRQ25. Watermarks are level conditions, not W1C state.
Hardware event set wins concurrent clear. RX discard does not set RX_STALL.
Mask IRQs while idle when a low-watermark condition would otherwise persist.
Expose live wire state, CS-active, session ownership, pending/clean segment,
GPIO readiness, quota/word/frame counts, FIFO levels, DMA jobs/credits,
first fault and saturating stall-cycle counters. A diagnostic read is live,
not a coherent multi-register snapshot; after completion/recovery software can
capture a stable result before beginning another segment.
## Register and Software ABI
### APB1.0 register map
Offsets below are hexadecimal relative to SPI0. Registers are 32 bits; reset
is zero except listed constants/defaults. RO writes/WO reads error. Reserved
offsets/bits error on writes and read bits are zero. Commands are one-hot WO
pulses; zero is a no-op, multiple command bits error without partial action.
| Offset | Name | Access / fields |
| --- | --- | --- |
| `000`, `004` | IP_ID, IP_VERSION | RO `0x53504930` (SPI0), `0x00010000` |
| `008` | CAPABILITY | RO bits 0 master, 1 full-duplex, 2 TX-only, 3 RX-only, 4 bit-order-select, 5 held-CS, 6 display personality, 8 frame 8, 9 frame 16; mode mask `[13:10]=0xF`; bit 7 DMA iff the complete integrated admission path is wired |
| `00C` | FIFO_CAPABILITY | RO TX depth `[7:0]=8`, RX depth `[15:8]=8`, word bits `[23:16]=32` |
| `010`, `014` | CLOCK_HZ, ROUTABLE_MASK | RO current PCLK Hz / Tiny `0xD8000000` |
| `018` | COMMAND | WO bits 0 ENABLE, 1 DISABLE, 2 ARM, 3 START, 4 END, 5 ABORT, 6 RECOVER, 7 RELEASE, 8 RESET |
| `01C` | STATUS | RO wire state `[3:0]`, CS_ACTIVE4, SESSION_OWNED5, SEGMENT_PENDING6, SEGMENT_CLEAN7, TX_WAIT8, RX_WAIT9, BUS_IDLE10, TRANSPORT_IDLE11, GPIO_READY12 |
| `020` | SESSION_CFG | RW CPOL0, CPHA1, LSB_FIRST2, MISO_ENABLE3, DISPLAY_DC4; bits 3/4 mutually exclusive |
| `024` | DIV | RW `[15:0]` 1..65535, reset 1 |
| `028`, `02C`, `030` | CS_SETUP, CS_HOLD, CS_INACTIVE | RW `[15:0]` 1..65535, each reset 1 |
| `034` | SEG_CONFIG | RW FRAME16 bit 0 (clear=8 bits), direction `[2:1]` TX_ONLY0/FULL_DUPLEX1/RX_ONLY2, HOLD_CS3 |
| `038`, `03C` | FRAME_COUNT, DUMMY | RW positive 32-bit frames / low 16 dummy; DUMMY reset `0xFFFF`, use low 8 for 8-bit frames |
| `040`, `044` | TX_BIND, RX_BIND | RW channel `[2:0]`, enable 31; disabled reset 0 |
| `048` | WATERMARKS | RW TX_LOW `[3:0]` 0..8, RX_HIGH `[11:8]` 1..8, reset `0x00000100` |
| `04C`, `050` | CPU_TXDATA, CPU_RXDATA | CPU-only WO push / RO pop, when that direction is CPU-owned and armed/pending |
| `054`, `058` | DMA_TXDATA, DMA_RXDATA | Qualified central-DMA-only WO push / RO pop with reserved credit |
| `05C` | FIFO_LEVELS | RO TX `[3:0]`, RX `[11:8]`, 0..8 |
| `060`, `064`, `068` | IRQ_STATE, IRQ_ENABLE, IRQ_STATUS | W1C sticky / RW mask / RO masked sticky+level |
| `06C`, `070` | FAULT_CODE, FAULT_FRAME | RO first low 8 code / completed-frame index at first fault |
| `074` | FRAMES_DONE | RO completed wire frames in current/last segment |
| `078` | TRANSPORT_WORDS | RO derived quota per enabled direction |
| `07C`, `080`, `084` | TX_WORDS_ACCEPTED, RX_WORDS_PRODUCED, RX_WORDS_REMOVED | RO successful FIFO events, excluding uncompleted reservations |
| `088`, `08C` | TX_STALL_CYCLES, RX_STALL_CYCLES | RO saturating 32-bit PCLK wait counters |
| `090` | SESSION_PINS | RO latched claim mask, retained through local disable/recovery until RELEASE |
| `094` | DMA_STATUS | RO bits 0 TX job, 1 RX job, 2 TX credit/response pending, 3 RX credit/response pending |
| `098` | PINS_READY | RO mask of session pins satisfying native/electrical/readiness checks |
| `09C` | PAYLOAD_BYTES | RO checked logical payload size for current/last segment |
Wire state encoding is DISABLED0, IDLE1, ARMED2, SETUP3, SHIFT4, HOLD5, HELD6,
GAP7, CLOSING8. SHIFT includes frame-boundary waits. BUS_IDLE means inactive
CS, SCK=CPOL and IDLE/DISABLED; HELD and ARMED are not lifecycle idle.
TRANSPORT_IDLE includes all bound jobs, pending DMA START/admission,
reservations, accepted requests and terminal responses, including descriptors.
It excludes the current CPU control access whose legality is being checked.
SEGMENT_CLEAN requires successful
wire completion and all enabled quotas fulfilled/removed, empty packers/FIFOs
and TRANSPORT_IDLE; before the first ARM, an empty session is also clean.
SESSION_CFG/timing writes require DISABLED, no session ownership and transport
idle. Segment configuration/bindings are writable in that initial state or a
clean IDLE/HELD session. FRAME_COUNT reset 0 is unconfigured; writing 0 or ARM
with invalid derived size fails. RESET defaults do not imply an armed segment.
WATERMARKS/IRQ controls remain writable while active. FIFO ports require the
correct source/owner and finite quota, and CPU ports reject CLOSING accesses.
ARM clears per-segment counts/packer state, not sticky IRQ history. Successful
FIFO access updates its counter once. Clear old event state deliberately before
ARM; clearing an event does not retire a pending segment or recover a fault.
Closing permits diagnostics/IRQ and recovery controls, not data/config/START.
Priority on a PCLK edge is system reset, new emergency guard fault, other
transfer fault/ABORT, accepted lifecycle/configuration command, then normal
wire/FIFO progress. Close prevents same-edge START or fresh DMA admission;
already accepted transactions from earlier edges remain drain obligations.
A FIFO request invalidated by close error-completes without its data side
effect. Valid accepted DMA admission wins only against a competing ordinary
rebind/idle command, which rejects; no speculative new binding authorizes it.
### HAL and compatibility
Handwrite future `spi_define.svh` and `crt/include/retrosoc/hal/spi_regs.h`,
with parity tests for offsets, fields, resets and enums. No register generator.
Use `crt/include/retrosoc/hal/spi.h` and matching HAL implementation ownership.
Product-generated presence, APB/IRQ/RCU wiring and SPI/DMA discovery must agree;
do not invent an ARCHINFO bit or probe an unmapped peripheral on old Tiny/Mini.
`rs_spi_*` APIs cover discovery/configuration, acquire/release, CPU or DMA
segment transfer, held-CS sessions, end, status, bounded wait and abort/recover.
They return `rs_status_t`, take caller-owned storage and `rs_timeout_t`, and
do not use heap, OS or hosted-library dependencies. Use RS_EINVAL for invalid
arguments/capacity/alignment, RS_ENOTSUP for absent/version/mode support,
RS_ETIMEOUT for wait expiry and RS_EIO for hardware/ownership failure. Report
busy/closing/lock detail through status without inventing a global status enum.
Frequency selection rounds DIV upward so actual SCK never exceeds the requested
rate or declared board/slave limit; reject an unrepresentable divider rather
than silently speeding up. Validate all 64-bit length/round-up arithmetic before
narrowing and before any DMA register write. Poll/IRQ helpers do not call DMA
APIs with unaligned or unpadded objects. Full-duplex RX draining must run while
TX progresses; waiting for all TX before reading RX can deadlock at FIFO full.
The Tiny ST7789VI adapter belongs in `app/board`; board reset/backlight policy,
panel initialization, rotation/address offsets and D/C belong there, not in a
generic bus HAL. Keep existing `crt/src/hal/lcd.c`, its GPIO2/XPI behavior,
240x135 board configuration and LVGL users unchanged unless separately scoped.
Do not copy that driver's ignored errors or pixel-halfword ordering. New
examples propagate every fallible result and use existing bringup/ci_smoke
composition, not a new APP or mandatory GUI/library dependency.
## Clock, Reset, CDC/RDC, and Lifecycle
All SPI state and pacing run in PCLK. CPU/SYS requests and source qualification
cross the existing domain bridge together. DMA payload reaches SYS through
its existing AXI bridge. MISO uses raw ALT input with controller-owned capture;
GPIO's two synchronizers plus registered filter/bypass path are not inserted
into this half-cycle timing path. There is no external internal-logic clock.
Constrain the generated SCK output and returned MISO against the selected
CPOL/CPHA/divider and board/slave timing: output Pad delay, clock flight time,
slave clock-to-data, input flight/Pad delay and setup/hold must fit the capture
window. Include CPHA=0 first-bit CS setup. A raw route or ideal digital BFM
does not establish synchronous external timing; do not mask it with blanket
false paths. PCLK 24/48/60 ideal SCK maxima 12/24/30 MHz are arithmetic ceilings,
not qualified read/write rates.
| Command / transition | Contract |
| --- | --- |
| ENABLE | DISABLED, unowned and clean only; verify native-ready, latch SESSION_PINS/SESSION_OWNED, enable inactive outputs and apply initial GAP before IDLE, without DONE |
| DISABLE | Clean IDLE only; CS inactive, no pending segment/jobs/credits/admission; revoke both bindings/grants, OE0 and DISABLED, retain session reservation until RELEASE |
| ARM / START | Clean boundary -> ARMED with latched finite quotas; ARMED -> SETUP/SHIFT; no implicit DMA or pin acquisition |
| END | Clean HELD only; release CS, apply inactive gap and set DONE; no new frame |
| ABORT | Any acquired nonclosing session; close admissions immediately, stop new frames, bounded phase-safe CS termination, enter CLOSING; repeated ABORT in CLOSING is idempotent |
| RECOVER | CLOSING only after CS inactive and complete transport drain; flush FIFO/packers/runtime/events/fault, disable bindings, enter DISABLED with configuration and session reservation retained |
| RELEASE | DISABLED, bindings/grants disabled, all jobs/credits/admission drained, FIFOs empty and verified GPIO handback; clear SESSION_OWNED/PINS, not another owner's GPIO configuration |
| RESET | DISABLED/unowned/transport-idle only; clear configuration/runtime/FIFOs/bindings/IRQ to reset defaults; complete its own APB response |
Normal ABORT during ARMED, setup, boundary wait, hold or HELD produces no new
frame; during SHIFT it finishes only the phase needed to return SCK to CPOL,
with no further receive sampling or next frame. Apply hold and inactive timing,
release CS and set ABORTED, never successful segment/transaction DONE. The
wire-close bound is at most `2*DIV + CS_HOLD + CS_INACTIVE + 2` running PCLK
cycles from accepted ABORT, independent of FIFO/DMA progress. Bus cleanup has
its own bounded software wait and external-response assumptions.
Ownership/readiness loss or unexpected reset is an emergency fault, not a
graceful waveform completion: suppress SPI OE/sampling immediately and allow
the invalid transaction to truncate. Set internal SCK=CPOL and CS inactive
without driving an unowned Pad, and mark invalid wire-close complete. RECOVER
may then run after transport drain even if the external route/readiness guard
remains invalid. It atomically disables active guard monitoring before entering
DISABLED, preventing the persistent fault level from re-entering CLOSING on
that edge. Intentional DISABLED handback is not an active-route fault.
Normal control remains reachable where
PCLK runs; closing accepted MMIO must error-complete, never await serial data.
After wire stop, abort only the bound DMA jobs and wait for payload plus
descriptor drain before RECOVER. Cancellation dominates descriptor activation.
Timeout retains the closed bindings/session and buffer ownership for later
recovery; do not reset the common DMA or reuse still-owned memory. Bound DMA,
MMIO-credit or internal quota/FIFO faults also close automatically through the
phase-safe wire-termination path; they do not require firmware to issue ABORT
before admission stops. Only ownership/readiness loss uses the emergency clamp.
Normal release disables SPI OE, sets native software GPIO OE0/ALT-disabled
fallback on the session mask, checks locks/readback/handoff, then RELEASEs
the reservation. A handback failure retains the safe reservation and returns
failure; do not reset GPIO to clear locks or automatically restart an old ALT
client. RECOVER cannot silently relinquish this ledger or enable a new session.
Do not escape CLOSING through DISABLE, START, event clearing or guard restoration.
GPIO gating/reset is vetoed by PIO USER ownership OR any latched SPI session,
including prefill, armed, held-CS, disabled-awaiting-release and closing states.
This applies to multi-target commands too. SPI target 16 gate/reset and PCLK
rate changes require released session, disabled core, inactive CS, no pending
segment or accepted transport. FIFO empty or DMA DONE alone is insufficient.
Recompute timing from CLOCK_HZ and reacquire/restart explicitly after change.
CPU-only WFI, debug halt and hart reset do not implicitly stop SPI or release
DMA memory. Restarted firmware must inspect/adopt/recover existing sessions
before programming them. A whole-system reset discards the whole traffic epoch,
clears ownership and forces user Pads high impedance; peripheral-local reset
cannot strand accepted traffic. Retain Tiny's staged local reset release.
## Errors, Recovery, Security, and Observability
FAULT_CODE values are 0 none, 1 native route/ownership lost, 2 GPIO readiness/reset
lost, 3 bound DMA error, 4 MMIO credit/protocol violation, 5 internal quota/FIFO
violation. First code and FRAMES_DONE index latch until RECOVER/RESET; for
simultaneous faults readiness precedes routing, then lowest remaining code.
Control/configuration APB misuse returns PSLVERR without changing the active
session unless it exposes an actual transport/guard violation. Fault/event
set wins clearing. Normal ABORT is reported separately, not as successful data.
TX/RX stall counters saturate and count PCLK cycles spent in the respective
frame-boundary wait. They measure service pressure, not fabricated byte-loss
counts. Snapshot output, exact pixel counts, DMA memory responses and error
state together determine valid results. A held-CS session is active even when
no clocks toggle and every FIFO is empty.
Origin-qualified FIFO ports protect functional ownership, not arbitrary
malicious firmware, secure boot or a complete bus firewall. Pin checks cannot
remove external electrical contention. No functional-safety, hotplug,
ESD/current-drive or security certification follows from this contract.
## MVP and Commercial-grade Roadmap
The exact MVP includes this master, GPIO/session guard, DMA V2.2 pacing,
freestanding HAL, independent protocol tests and the sequential display path.
Use the ST7789VI-style four-wire mode with software 8-bit commands and 16-bit
MSB-first RGB565 pixel frames, CS preserved across the command/data boundary.
The panel interprets two ordinary data bytes per pixel, not a new 16-bit panel
interface. Verify the selected panel's initialization and landscape offsets;
do not reuse 240x135 constants for the 320x240 reference.
First display color bars, gradients and odd-width/odd-pixel rectangles. Then
capture a 320x240 RGB565 frame (153600 bytes) to initialized, capacity-checked
XPI NSS1 PSRAM, wait for valid DVP frame and final DMA writes, verify/read back,
display that immutable buffer, and save/check the SD data sequentially. The
panel BFM's pixel stream must match the intended frame and the saved data.
Use bounded line/processing workspaces; do not allocate a 150 KiB main-SRAM frame.
Camera/audio exclusion and all existing pin/channel owners remain in force.
Measure actual SCK, frame time, CPU cycles, payload utilization, FIFO levels
and longest DMA stall for SRAM and PSRAM sources. At the ideal 12/24/30 MHz
serial rates, raw payload ceilings are 1.5/3/3.75 MB/s and the QVGA pixel-only
times are 102.4/51.2/40.96 ms; real transfers are slower. These are bounds, not
FPS guarantees or evidence that those physical clocks work.
Later changes may qualify double-buffer capture/display, SPI_TX memory burst
prefetch, tighter interframe deadlines or richer panels. They require an
explicit new performance/scope decision. Do not hide them inside P1-P5 or
claim the full camera/display pin profile has spare external PIO pins.
## Verification and Software Validation
The [verification ledger](spi-verification.md) maps requirements to directed,
randomized, formal, host, integration and physical cases. P1 supplies the
standalone APB/core reference behavior and independent pin BFM; P2 covers DMA
encoding/credits/cancellation; P3 covers actual source qualification and GPIO
handoff; P4 covers firmware and the sequential application.
Required coverage includes all modes/widths/bit orders; first/final edges;
DIV and CS-count boundaries; counts 0/1 and rounding overflow; nonzero TX tail
padding and zero RX tail; exact FIFO quotas; separate source/owner errors;
stall/resume without mid-frame stretch; held CS and 8-to-16-bit transitions;
DMA_DONE before wire end and RX B-response after it; ABORT at every state;
descriptor fetch/parse/activation cancellation; lost route/readiness, lock
failures, retained session after recovery and unrelated-channel/PIO progress.
New self-owned C follows MISRA C:2012 Amendment 2 with no deviation approved
here. Host-test deterministic packing/length/divider/session logic. Preserve
managed panel/library boundaries and avoid unnecessary dependencies. Tiny
firmware success requires exit 0, SYSCTRL TEST_STATUS/`SIM_TEST_PASS` and no
`FAILED`, `FATAL`, `assertion failed`, `%Error`, `SIM_TEST_FAIL` or
`SIM_TEST_TIMEOUT`; UART boot text is diagnostic only.
After relevant phase approval, use existing tooling plus the tests added by
that phase, not invented already-working SPI Make targets:
```sh
ruff check .
python3 -m pytest -q
make sw-format-check sw-policy-check sw-host-test
make CONFIG=configs/ci/ihp130-tiny.mk firmware
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc TINY --dry-run
python3 scripts/regress.py --root . --suite nightly --soc TINY --dry-run
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc TINY
python3 scripts/regress.py --root . --suite nightly --soc TINY
python3 scripts/regress.py --root . --suite pr --pdk IHP130 --soc MINI
```
Both Verilator and Icarus must exercise independent pin-level models. Existing
Tiny profiles do not acquire new IP merely because these commands parse.
Missing R2 prerequisites, unavailable tools/models and skipped cases remain
explicit gaps, not substituted products or passing tests.
## Synthesis, Timing, and Physical Evidence
Record source SHA, lock/config digests, TINY/IHP130 variant, PCLK/SYS/MEM,
serial divider/mode/direction, Pad/board/slave loads and payloads for every
measurement. Require block/full synthesis, register/FIFO mapping, area/cells,
reset fanout/release, netlist simulation, CDC/RDC, PVT/MMMC and extracted STA.
Qualify SCK/MOSI/CS/D/C output and MISO return timing, simultaneous switching,
external CS bias, QFN64 routing and power. Review DFT/storage-test coverage;
no inferred-FIFO MBIST/ECC or production silicon status is implied.
PCLK 24 is the executable starting frequency, not existing SPI timing evidence;
48/60 require the corresponding R2 platform and physical inputs. Keep CPU/main
SRAM same-frequency qualification and existing XPI MEM constraints intact.
SPI-P5 may share a campaign with TINY-R2-P11 and PIOLITE-P5 only when the same
complete source/netlist/configuration satisfies all contracts. Missing Pad,
SRAM, clock, vendor or board evidence remains blocking for the affected claim.
Do not alter observe-mode metrics or warning baselines through this freeze.
## Development Order
Every phase targets TINY. Mini testing is shared-IP compatibility, not a rollout.
Stable IDs/titles below do not rename, reuse or advance R2/PIO phases.
| ID / title | Dependencies, scope and completion |
| --- | --- |
| SPI-P0 - Contract and DMA Extension Freeze | Approved research; freeze this specification/ledger, Tiny resources/routes, DMA/GPIO contracts and indexes. Validate links/commands/consistency/whitespace only; no implementation result. |
| SPI-P1 - SPI Core and Register Implementation | P0; owned master/APB/packing/phase/guard interfaces, register mirror and standalone protocol/negative tests. All four modes, widths, ordering, quotas, held-CS lifecycle, lint/style/formal and block-synthesis evidence. No real Tiny capability until wiring exists. |
| SPI-P2 - DMA V2.2 Paced FIFO Integration | P1 and V2.1 cancellation/compatibility obligations, implemented here if not already delivered;5-bit encoding, port/source-qualified credit interfaces, exact packing/counts, jobs/drain and old-Mini regression. Retain single-beat MMIO policy; no PIO peripheral completion prerequisite or hidden burst optimization. |
| SPI-P3 - Tiny GPIO RCU and SDK Integration | P2 plus applicable TINY-R2-P6/P7; topology/address/IRQ/RCU/filelists, four Gen1 ALT additions, latched source qualifier through fabric/CDC, GPIO readiness/ownership, bounded HAL. Firmware/simulations and unaffected Mini/PIO compatibility; no layout/source swap of legacy LCD. |
| SPI-P4 - Display and Snapshot Application Qualification | P3; board display adapter, independent panel/data oracle and three stages of display patterns, PSRAM-source display and sequential camera/verify/display/SD. Camera/PSRAM cases require R2-P8/P9. Both simulators, host boundaries, error recovery and current-source regression/measurements pass. |
| SPI-P5 - IHP130 Timing and Physical Qualification | P4 and applicable R2 system/PIO-inclusive product prerequisites; complete-netlist synthesis/netlist/STA/CDC/RDC/physical/Pad campaign. Publish only measured qualified operating points with residual gaps, optionally joint R2-P11/PIOLITE-P5. |
### Next-phase preflight handoff
```text
Use $retrosoc-feature-implementation. Stage: preflight. Feature slug: spi. Target SoCs: TINY.
Phase: SPI-P1 - SPI Core and Register Implementation.
Read docs/ip/spi.md and docs/ip/spi-verification.md. The executable starting profile is configs/ci/ihp130-tiny.mk, PDK IHP130, 24 MHz/no PLL; it has no SPI integration yet.
Plan only the frozen standalone master/APB1.0 core, packing/phase/lifecycle and source-qualified interface contracts, handwritten SVH/C parity, reference behavior, independent pin BFM and focused tests. Preserve all modes/8-16-bit packing, FIFO sizes, exact quotas, CS/D-C boundaries and bounded close/recovery semantics.
Do not implement DMA V2.2, Tiny routing/RCU/fabric integration, the SDK/display application, new profiles or later phases. Do not change the frozen ABI, increase storage/pads, alter the legacy XPI LCD path, upgrade dependencies, change quality policy, commit or push. Return SPEC_CONFLICT rather than weakening an unmet contract, and provide the scoped preflight and validation plan for explicit approval before implementation.
```
## Commercial Delivery Gaps
At freeze there is no SPI controller, DMA V2.2 implementation, origin-qualified
Tiny path, HAL/display adapter, independent panel model or SPI performance
evidence. Coverage closure, reset/CDC/RDC/DFT, extracted timing, power/Pad/board
qualification, release artifacts and silicon validation remain required. A
documentation freeze is not RTL freeze, physical signoff or approval to advance
implementation stages. No MISRA deviation, new PDK or safety/security claim is
granted here.
+53 -1
View File
@@ -17,12 +17,16 @@ frozen IO/power-pad budget are outside the original performance-only R2
refreeze. PIO-lite is now a separately approved standard-product extension
under [piolite.md](piolite.md), with its own pending evidence matrix below;
it does not renumber or retroactively expand the R2 phase results.
SPI is also a separately approved standard-product extension under
[spi.md](spi.md), with pending evidence below. The original performance-only
exclusions remain in force for historical R2 work; the separate SPI approval
does not turn older results into SPI acceptance.
The executed historical sections describe the 2026-09-25 initial baseline,
with two UARTs, two I2C controllers and the legacy pad mapping. The working
tree was uncommitted when that evidence was collected and its readiness
remains `prototype`. Those results do not validate the later package,
shared-IP/clock/reset, DVP/framebuffer, R2 performance or PIO-lite freezes.
shared-IP/clock/reset, DVP/framebuffer, R2 performance, PIO-lite or SPI freezes.
## PIO-lite planned extension evidence
@@ -67,6 +71,54 @@ Firmware uses SYSCTRL `TEST_STATUS` and the strict `SIM_TEST_PASS`/result-file
policy. Hardware, pad-speed and PPA claims remain pending until the specific
source/profile/PDK evidence passes.
## SPI planned extension evidence
Target SoCs: `TINY`; feature slug: `spi`; approval date: 2026-10-04.
The future standard product adds SPI0: an 8/16-bit PCLK master with separate
8 x 32-bit TX/RX FIFOs, a bounded display transaction queue and DMA V2.2
paced fixed-MMIO requests. Slave operation and continuous double-buffer
camera/display are deferred. The committed IHP130 24 MHz/no-PLL profile has
no SPI implementation; every implementation, simulator, proof, firmware,
workload, synthesis, timing, physical and silicon result below is pending.
The detailed matrix and documentation checks belong to the
[SPI verification ledger](spi-verification.md).
| SPI phase / area | Required evidence and completion boundary | Status |
| --- | --- | --- |
| SPI-P0 - Contract and DMA Extension Freeze | Approved SPI/transaction ABI and DMA V2.2 contract; only the four reserved Gen1 ALT cells added; all 64 perimeter assignments, existing assigned alternates and legacy/R2/PIO phase IDs/titles preserved; linked address/IRQ/RCU/request values and documentation checks. | Documentation freeze only; no implementation result |
| SPI-P1 - SPI Core and Register Implementation | All CPOL/CPHA and 8/16-bit cases, first/last bits, TX/RX FIFO boundaries, partial words, timing changes, CS setup/hold/inactive and retained-CS behavior; invalid register access, W1C races, timeout/abort, stale-session isolation and handwritten register parity. | Pending |
| SPI-P2 - DMA V2.2 Paced FIFO Integration | Requests 16/17 and truthful capability support, stable grants, single-beat FIFO MMIO, memory-side bursts/boundaries, TX/RX tails, no FIFO double-pop/push, complete descriptor/accepted-response drain and no stale restart; regress existing PIO14/15 and other consumers. | Pending |
| SPI-P3 - Tiny GPIO RCU and SDK Integration | Accepted R2-P6 frozen Gen1/eight-channel routing and R2-P7 lifecycle prerequisites; APB `0x1001D000..0x1001DFFF`, IRQ25, target16, native-ready/USER handoff, raw MISO capture, complete HAL queue/error/recovery behavior and truthful absent capabilities. | Pending |
| SPI-P3 / GPIO and lifecycle | Preserve sole PIO USER ownership and its synchronizer/filter path. Reject GPIO gate/reset while PIO USER_SELECT or latched SPI sessions remain, including prefill, CS-held and closing state and combined masks; no native-ready inference from zero USER_STATUS; guard loss closes admissions, invalidates work and requires explicit recovery. Gate/reset/PCLK changes need inactive CS and complete wire/DMA/MMIO/descriptor drain. | Pending |
| SPI-P4 - Display and Snapshot Application Qualification | Pin-level display command/data checks, D/C ordering and setup, source/pixel conversion, exact counts/guards/readback, zero early wire completion, deterministic error recovery and explicit board reset/backlight/TE solution. Camera/PSRAM cases require R2-P8/R2-P9 and execute capture, verify, display, then SD save. | Pending |
| SPI-P4 / shared ownership and throughput | TX3 only after bulk/PIO release and RX2 only after full DVP/PIO release; no theft of Crypto4/5 or I2S6/7. Measure actual wire rate, source conversion/staging, payload throughput and worst admitted service gaps; strict Tiny terminal verdict in Icarus and Verilator. Nominal PCLK/SCK or double-buffer assumptions are insufficient. | Pending |
| SPI-P5 - IHP130 Timing and Physical Qualification | Same SPI- and PIO-inclusive source/profile/PDK/corner/netlist as applicable final product gates; actual PCLK STA, SCK/MOSI/CS/D-C output and MISO round-trip setup/hold, GPIO guard/handoff, CDC/RDC, local reset, gate behavior, area/power/IO/package and board evidence. | Pending |
SPI0 is allocated at `0x1001D000..0x1001DFFF`, IRQ25 and RCU target16;
`SPI_TX=16` and `SPI_RX=17` are DMA request IDs, not new channels. Keep those
capabilities absent until complete implementation. Planned RCU support is
the actual implemented target mask; `0x0001FFFF` is valid only when every
target0-16 path exists. GPIO gate/reset veto is based on actual PIO ownership
OR the hardware-latched SPI session, not mutable claims or FIFO-empty alone.
The four changed Gen1 rows are GPIO27 ALT0 SCK, GPIO28 ALT1 MOSI, GPIO30
ALT1 MISO and GPIO31 ALT1 CS_N. GPIO30 ordinary D/C replaces MISO in the
write-only display profile. R2-P6 first migrates the legacy executable PWM
capture routes from GPIO30/31 ALT1 to the already frozen GPIO24/25 ALT0.
The complete camera profile plus display consumes all 32 GPIO and preserves
GPIO29 NSS1. Board control pins and external CS/reset bias need explicit
evidence; changing the internal mux cannot prevent external contention.
`SPI-P5` can share physical runs with `PIOLITE-P5` and `TINY-R2-P11` only
when all applicable contracts are satisfied on the same SPI- and
PIO-inclusive source revision, configuration, physical inputs and netlist.
Earlier baseline/R2 or PIO-only evidence does not qualify the new product.
PCLK24/48/60 and arithmetic SCK12/24/30 MHz are target cases, not measured
payload rates or qualified pad operation. Preserve the existing 128 KiB
CPU-rate main SRAM, eight DMA channels, three external AXI owners and fixed
QFN64/power budget. Record documentation validation separately from these
pending implementation gates.
## R2 pending phase acceptance
The following is the active monotonically increasing sequence. Every phase
+180 -21
View File
@@ -21,6 +21,13 @@ main SRAM, eight-channel DMA target and three external AXI owners. Its
phase sequence. PIO-lite is required by the extended product target but is
not implemented or qualified by this documentation freeze.
The separately approved 2026-10-04 [SPI extension](spi.md), feature slug
`spi`, adds SPI0 to the future standard Tiny product. Its master-only
8/16-bit engine and display transaction service use existing GPIO alternates,
PCLK and borrowed central-DMA channels. `SPI-P0` through `SPI-P5` preserve
all legacy, R2 and PIO-lite phase IDs/titles. This is documentation approval;
SPI0, DMA V2.2 pacing and the display application remain unimplemented.
The clock contract retains the 96 MHz no-PLL and 192/240 MHz PLL targets,
now requiring the main SRAM to qualify at those same rates. Both variants
boot from REF24. XPI remains in the divided MEM domain with a 120 MHz ceiling;
@@ -50,6 +57,11 @@ PIO-lite integration in `PIOLITE-P3` requires the applicable accepted R2-P6
DMA/shared-integration and R2-P7 RCU functionality. `PIOLITE-P5` may share a
physical run with R2-P11 only on the same PIO-inclusive source revision and
configuration, with both contracts' evidence requirements satisfied.
SPI integration in `SPI-P3` likewise requires accepted R2-P6 frozen GPIO/DMA
integration and R2-P7 clock/reset behavior. Camera/PSRAM application
qualification in `SPI-P4` requires R2-P8/R2-P9. Final standard-product
qualification must identify the same SPI- and PIO-inclusive source,
configuration and netlist; an earlier R2 or PIO-only result is insufficient.
### Commercial references and reuse boundary
@@ -240,22 +252,50 @@ no commercial implementation or qualification is reused.
requests, IRQ and RCU support MUST remain absent until their complete paths
exist. Functional, DMA/contention and physical evidence MUST identify the
actual PIO-inclusive source, profile and PDK; old R2 results do not qualify it.
- TINY-041: the standard Tiny target MUST include [SPI0](spi.md), an
8/16-bit, four-mode, master-only controller with separate 8 x 32-bit TX and
RX FIFOs in PCLK. SPI0 uses APB4 `0x1001D000..0x1001DFFF`, CPU IRQ25 and
Tiny RCU target bit 16; all remain unsupported until fully integrated.
- TINY-042: SPI0 MUST use GPIO27 ALT0 SCK, GPIO28 ALT1 MOSI, GPIO30 ALT1
MISO and GPIO31 ALT1 CS_N. Write-only display mode uses GPIO30 as ordinary
GPIO D/C instead of MISO. Preserve the other Gen1 alternates, all QFN64
terminals and the dedicated boot/debug/control pads. R2-P6 first applies
the already approved Gen1 migration of legacy PWM captures to GPIO24/25.
- TINY-043: [DMA V2.2](dma.md) MUST provide `SPI_TX=16` and `SPI_RX=17`
as paced fixed-MMIO requests. Default SPI TX borrows channel 3 and RX
borrows channel 2 only after prior owners fully drain and release them.
PIO-lite requests 14/15 and existing channel reservations remain unchanged;
no extra DMA channel, AXI owner or user SRAM is added. SPI payload accesses
retain the existing single-beat MMIO transport contract.
- TINY-044: GPIO gate/reset MUST be rejected while actual PIO USER ownership
or a latched SPI session remains. The SPI reservation includes prefills,
retained CS and closing/drain state; mutable configuration cannot release
it. SPI gate/reset and clock changes require inactive CS, completed wire
timing and complete accepted DMA/MMIO/descriptor drain. Guard loss faults
the session and cannot automatically resume it after routing recovers.
- TINY-045: `SPI-P0` through `SPI-P5` are a separate approved extension.
Display acceptance MUST use bounded transactions; camera/display acceptance
uses the sequential capture, verify, display, then SD-save workflow. Continuous double-buffer
camera/display operation is deferred. Final qualification MUST use the
actual SPI- and PIO-inclusive source/profile/PDK and netlist, not historical
baseline or performance-only evidence.
Deferred: RV32 A atomics, RTOS ports, authenticated boot, retention/power gating,
independent sleep clock, 256-512 KiB SRAM, USB, standalone general SPI, CAN, ADC,
independent sleep clock, 256-512 KiB SRAM, USB, SPI slave operation, CAN, ADC,
multimedia accelerators beyond the selected DVP capture path and other PDK
qualification. I2S, SDIO, DVP and the approved PIO-lite extension are standard
Tiny requirements awaiting integration, not deferred product features. XPI
qualification. I2S, SDIO, DVP and the approved PIO-lite and SPI extensions
are standard Tiny requirements awaiting integration, not deferred product features. XPI
retains four chip selects: CS0_N is dedicated to boot NOR, while CS1_N through CS3_N
use GPIO29 through GPIO31. Additional XPI device configurations still require
their own qualification.
The original performance-only R2 scope MUST NOT add SPI, PIO-lite, a recovery
Boot ROM, caches, atomics, new accelerators or another PDK rollout. That
historical scope boundary remains in force for its phase work. PIO-lite is
now a separately approved standard-product extension governed by
[piolite.md](piolite.md); its phases do not become hidden prerequisites of
R2-P0 through R2-P10. The other listed research ideas remain deferred.
historical scope boundary remains in force for its phase work. PIO-lite and
SPI are separately approved standard-product extensions governed by
[piolite.md](piolite.md) and [spi.md](spi.md); their phases do not become
hidden prerequisites of R2-P0 through R2-P10. The other listed research ideas
remain deferred.
## QFN64 package and power planning
@@ -397,11 +437,18 @@ peripheral functions are unavailable on each pad while PIO-lite owns it.
| GPIO24 | 51 | PWM_CAP0 | UART0_TX | PWM capture 0 or alternate UART TX |
| GPIO25 | 52 | PWM_CAP1 | UART0_RX | PWM capture 1 or alternate UART RX |
| GPIO26 | 11 | WS2812_OUT | I2C0_SCL | LED output or alternate open-drain I2C clock with readback |
| GPIO27 | 12 | Reserved | I2C0_SDA | Alternate open-drain I2C data with readback |
| GPIO28 | 13 | CLKOUT | Reserved | Divided clock observation output |
| GPIO27 | 12 | SPI0_SCK | I2C0_SDA | SPI clock or alternate open-drain I2C data with readback |
| GPIO28 | 13 | CLKOUT | SPI0_MOSI | Divided clock observation or SPI data output |
| GPIO29 | 14 | XPI_CS1_N | Reserved | Second XPI chip select |
| GPIO30 | 15 | XPI_CS2_N | Reserved | Third XPI chip select |
| GPIO31 | 16 | XPI_CS3_N | Reserved | Fourth XPI chip select |
| GPIO30 | 15 | XPI_CS2_N | SPI0_MISO | Third XPI chip select or SPI input; ordinary GPIO D/C in write-only display mode |
| GPIO31 | 16 | XPI_CS3_N | SPI0_CS_N | Fourth XPI chip select or SPI chip select |
Only these four formerly reserved Gen1 cells are assigned by the SPI freeze.
The committed legacy map still has PWM_CAP0/1 on GPIO30/31 ALT1; R2-P6 MUST
first apply the approved Gen1 GPIO24/25 ALT0 capture routes. SPI integration
does not silently replace the executable baseline's capture ABI. GPIO27's
alternate I2C input, GPIO28 CLKOUT and XPI CS2/3 are mutually exclusive with
SPI on their respective pads. GPIO29 NSS1 remains available.
UART and I2C alternate locations connect to the same UART0 and I2C0 instances.
Repeated PWM names are routes for the same four channels, not extra channels.
@@ -486,6 +533,41 @@ two external devices from driving a shared net. Camera and PSRAM voltage/load
requirements must match the fixed 3.3 V IO rail or use qualified board-level
translation; this profile does not add supplies or pads.
### SPI and display profile ownership
The approved SPI extension uses the four remaining camera-profile GPIO:
GPIO27 SCK, GPIO28 MOSI, GPIO31 CS_N and either GPIO30 MISO or ordinary GPIO
D/C. Write-only display mode therefore consumes all 32 GPIO in the complete
camera/SDIO/UART/I2C/WS2812/NSS1 profile with optional controls. It adds no
package terminal. Separate display RESET_N, backlight/PWM, TE or readback
requires an explicit board solution or release of an optional function;
these controls are not implied spare pins. A board must document compatible
reset/bias/control circuitry and preserve inactive-device isolation.
PIO-lite remains the sole `USER_SELECT` owner. SPI uses native ALT routes and
must acquire its native session after USER ownership of every participating
pin is released and its one-clock handoff completes. Zero `USER_STATUS`
alone is insufficient: native-ready requires USER_SELECT and handoff clear
on the SPI session mask, GPIO lifecycle ready and the expected ALT/electrical
configuration. PIO may retain unrelated pads. The display session also
reserves the ordinary GPIO D/C role. Do not change PIO's synchronized-input
contract or its GPIO gate/reset veto to accommodate SPI.
SPI MISO uses the raw alternate-input route with capture timing owned by the
SPI controller. It does not reuse the GPIO two-stage synchronizer plus
registered filter/bypass path. Full-duplex acceptance must qualify the entire
SCK launch, board/device response and MISO setup/hold path at each operating
point. SPI guard loss suppresses unauthorized outputs and input sampling,
invalidates queued/prefilled work and requires explicit drain/reacquisition.
Retained CS and closing sessions keep their hardware-latched pad reservation.
The HAL owns complete display transactions: wait for the preceding wire
segment, update D/C with ordered/readback-checked GPIO access, observe setup
time, then start the next segment. FIFO-empty or DMA done is not wire done.
Command/data CS retention, release and errors follow [SPI](spi.md), including
CS setup/hold/inactive timing. CS_N requires external inactive-high bias when
reset or GPIO handoff makes the pad high impedance.
## Shared IP and product-specific integration
The selected hierarchy is `retrosoc_tiny` plus a Tiny-owned RCU/SYSCTRL,
@@ -608,6 +690,7 @@ linked common contract; do not generate a second set of IP registers.
| SDIO0 | `0x1000F000` | 10 | [SDIO](sdio.md), one host and its private AXI32 DMA master |
| Central DMA | `0x1000A000` | 20 | [DMA V2](dma.md), eight channels and supported request discovery |
| PIO-lite | `0x1001C000` | 24 | [PIO-lite](piolite.md), 4 KiB APB4 window, two state machines in PCLK; separately approved standard-product extension |
| SPI0 | `0x1001D000` | 25 | [SPI](spi.md), 4 KiB APB4 window, master-only 8/16-bit engine in PCLK; separately approved standard-product extension |
Mini's RCU has no separate MMIO region: its software controls are in SYSCTRL
at `0x1000B000`. Tiny retains this base and uses the private bank below for
@@ -623,6 +706,8 @@ All other unallocated IRQ bits are zero. CRC has no fabricated interrupt or
private DMA request; software finishes the CRC session after DMA completion.
PIO-lite's window is `0x1001C000..0x1001CFFF`; IRQ24 remains zero and its
capability absent until the block and complete interrupt path are integrated.
SPI0's window is `0x1001D000..0x1001DFFF`; IRQ25 remains zero and its
capability absent until the block and complete interrupt path are integrated.
### DMA and bus behavior
@@ -630,8 +715,8 @@ capability absent until the block and complete interrupt path are integrated.
| ---: | --- |
| 0 | UART0 |
| 1 | I2C0 |
| 2 | DVP receive; PIO-lite RX or general memory transfers only after camera ownership is released |
| 3 | Serialized bulk clients: XPI, WS2812, CRC and PIO-lite TX |
| 2 | DVP receive; PIO-lite RX, SPI RX or general memory transfers only after camera ownership is released |
| 3 | Serialized bulk clients: XPI, WS2812, CRC, PIO-lite TX and SPI TX |
| 4 | Crypto input |
| 5 | Crypto output |
| 6 | I2S transmit |
@@ -640,6 +725,9 @@ capability absent until the block and complete interrupt path are integrated.
Retain Crypto request IDs 12/13, I2S request IDs 1/2 and DVP request ID 11.
The PIO-lite extension adds requests `PIOLITE_TX=14` and `PIOLITE_RX=15` without
renumbering existing requests or increasing the eight-channel target.
The separate SPI extension adds DMA V2.2 paced fixed-MMIO requests
`SPI_TX=16` / `SPI_RX=17`, preserving existing request meanings and the
64-byte TCD layout. Selector/ABI and capability changes follow [DMA](dma.md).
Channel ownership is product integration data, not a different DMA register
ABI. In particular,
Tiny channel 6 is not Mini's HP-boot reservation. Shared drivers use product
@@ -658,6 +746,22 @@ either channel returns boundedly without stealing another client's channel.
PIO-lite has no private AXI master. CPU/FIFO and central-DMA access, selected
state machine, request readiness and completion follow [PIO-lite](piolite.md).
SPI likewise borrows TX channel 3 or RX channel 2 only after the existing
owner fully drains and releases it. SPI and PIO cannot independently own the
same channel or pad. Crypto4/5 and I2S6/7 are not implicit fallback channels.
SPI's central-DMA payload path is paced fixed-MMIO to its APB FIFO ports,
with one MMIO beat per AXI transaction; it is not a new AXI master or a
multi-beat FIXED-burst bridge feature. The memory leg also retains the existing
single-beat behavior for SPI paced-MMIO jobs; burst-prefetch optimization is
deferred. Direction grants, FIFO ownership, admission and complete
descriptor/response drain are defined by [SPI](spi.md) and [DMA V2.2](dma.md).
Requests 16/17 remain unsupported until their complete integration exists.
The SPI wrapper requires transaction-latched CPU/central-DMA/other-origin
qualification through target admission and CDC, so only matching reserved DMA
transactions can consume DMA FIFO credits. CPU and central-DMA FIFO aliases
cannot bypass each other's ownership. This private path changes no AXI master
count, ID or APB PPROT meaning and is not a new general firewall.
Retain the common DMA direct/TCD ABI, 32-bit Tiny datapath, at-most-16-beat
memory bursts, completion/error/W1C and abort-drain behavior. Replace the
baseline's blanket Tiny stream rejection with truthful endpoint capabilities;
@@ -999,6 +1103,14 @@ capture/FPS, a chosen physical sensor/PSRAM part and board timing are deferred
qualification items. This buffer path adds no memory protection, IOMMU,
authenticated image source or security/safety certification.
The separate SPI display extension keeps this single-buffer boundary:
capture into qualified PSRAM, finish and verify the complete frame, release
camera transport ownership, display the verified frame through SPI, then
save through SDIO. Use bounded staging/transaction buffers within existing
SRAM when needed; do not require a whole-frame SRAM copy. Measure the entire
sequence and its source/data-format conversion costs. Continuous capture
with double-buffer display/save is not enabled by the new SPI interface.
## Gen1 clock, reset and board requirements
### Sources, domains and operating profiles
@@ -1050,7 +1162,7 @@ remain clocked while XIN runs and MUST NOT be software-gated.
| AON / REF24 | RCU, CLINT, ArchInfo; RTC/WDG functional clocks | 24 MHz | 24 MHz | 24 MHz | 24 MHz |
| SYS | CPU I/D and slow adapter, actual main-SRAM macros, four bank frontends/control, AXI32 fabric, SDIO including its APB and private DMA | 24 MHz | 96 MHz | 192 MHz | 240 MHz |
| MEM | XPI, including its control interface | 24 MHz | 96 MHz | 96 MHz | 120 MHz |
| PCLK | Eight-channel DMA, GPIO, UART0, I2C0, timers, PWM, RNG, CRC, WS2812, Crypto, I2S/DVP hosts, PIO-lite engine/APB/DMA endpoints; RTC/WDG APB | 24 MHz | 48 MHz | 48 MHz | 60 MHz |
| PCLK | Eight-channel DMA, GPIO, UART0, I2C0, timers, PWM, RNG, CRC, WS2812, Crypto, I2S/DVP hosts, PIO-lite and SPI engines/APB/DMA endpoints; RTC/WDG APB | 24 MHz | 48 MHz | 48 MHz | 60 MHz |
| AUDIO | I2S audio PHY and existing audio-side FIFOs | External | External | External | External |
| PIXCLK | DVP pixel path and existing pixel-side FIFO | External | External | External | External |
| JTAG | TAP/DTM | Separate TCK | Separate TCK | Separate TCK | Separate TCK |
@@ -1088,6 +1200,13 @@ DMA/APB work and satisfy the lifecycle in [PIO-lite](piolite.md). Restart uses
the new committed rate and explicitly initialized timing state; a clock change
does not transparently preserve an in-flight protocol waveform.
SPI shares PCLK and uses integer half-period enables, with
`SCK_HZ = PCLK_HZ / (2 * N)`, `N >= 1`; SCK is not an internal logic clock.
At PCLK24/48/60 the arithmetic ceilings are SCK12/24/30 MHz, respectively.
They are not qualified pad rates or sustained payload guarantees. A clock
change requires SPI wire completion, inactive CS and full transport drain;
software explicitly reinitializes timing from the committed new PCLK rate.
CLINT's counter/control stays in AON with a synchronous 1 MHz tick enable.
Its timebase does not change or lose ticks during SYS transitions. CLINT
interrupt levels cross into SYS through synchronizers. RTC and watchdog
@@ -1169,8 +1288,8 @@ are not ordinary software-gate targets.
1. The product clock service runs from SRAM and disables/quiesces all
frequency-sensitive clients. DMA streams, SDIO/XPI, UART/I2C, I2S/DVP/PWM,
WS2812, CRC sessions, RNG source handshakes and Crypto maintenance must
be idle. Pending GPIO/filter use must be made safe by its owner.
WS2812, SPI sessions, CRC sessions, RNG source handshakes and Crypto
maintenance must be idle. Pending GPIO/filter use must be made safe by its owner.
2. Accept and acknowledge the RCU command before blocking new target admissions
on both CPU local I/D paths and external AXI paths.
Drain accepted reads, writes, local I/D memory operations, all four bank
@@ -1288,6 +1407,7 @@ flow and affected consumer validation, not a patch inside a managed checkout.
| JTAG | Dedicated debug access remains available | Application pinmux must not disconnect the debug path |
| GPIO7 / SD_PWR_EN | External pull-down keeps card power disabled | Drives a load-switch enable, never the SD card supply directly |
| GPIO29 / XPI_CS1_N | High impedance until selected; PSRAM remains deselected | External pull-up; no PSRAM dependency during NOR boot |
| GPIO31 / SPI0_CS_N | High impedance until SPI ALT selection and valid native session | External pull-up keeps the SPI/display device deselected during reset and ownership handoff |
| GPIO23 / CAM_XCLK and GPIO24/25 controls | No clock output after reset; ordinary GPIO high impedance | Board-defined sensor reset/power-down bias and inactive-device isolation |
The current IHP GPIO binding provides no internal pull-up/down capability;
@@ -1336,7 +1456,7 @@ reachable through an acknowledged APB bridge while the system is running.
| `0x14C` | `MEM_HZ` | RO / 24000000 | Committed divided XPI MEM-domain frequency, not main-SRAM frequency |
| `0x150` | `PCLK_HZ` | RO / 24000000 | Committed peripheral frequency |
| `0x154` | `CLINT_HZ` | RO / 1000000 | CLINT tick rate |
| `0x158` | `TARGET_CAPABILITY` | RO / build-dependent | Implemented gate targets; full sets are `0x00003FFF` before DVP/PIO, `0x00007FFF` with DVP but no PIO, and `0x0000FFFF` with DVP and PIO; absent target bits stay clear; reset excludes CPU bit 0 |
| `0x158` | `TARGET_CAPABILITY` | RO / build-dependent | Implemented gate targets; full sets are `0x00003FFF` before DVP/PIO/SPI, `0x00007FFF` with DVP only, `0x0000FFFF` with DVP/PIO, and `0x0001FFFF` with DVP/PIO/SPI; absent target bits stay clear; reset excludes CPU bit 0 |
| `0x15C` | `CLKOUT_CONTROL` | RW / 0 | Source `[2:0]`; half-period divisor `[23:8]`; output is off after reset |
Clock profile 0 is SAFE24. Profile 1 is external XIN at its declared frequency
@@ -1352,14 +1472,17 @@ identity and manifest must identify the model rather than physical qualification
The target-mask bits are Tiny integration identifiers, not Mini register ABI:
0 CPU, 1 GPIO, 2 UART0, 3 I2C0, 4 timer0, 5 timer1, 6 PWM, 7 I2S, 8 SDIO,
9 central DMA, 10 WS2812, 11 RNG, 12 CRC, 13 Crypto, 14 DVP and 15 PIO-lite.
Bits 16-31 are reserved. Bits 14/15 are additive target allocations; existing
offsets/bits and RCU ABI 1.0 semantics remain unchanged. R2-P7 may reserve the
control plumbing
9 central DMA, 10 WS2812, 11 RNG, 12 CRC, 13 Crypto, 14 DVP, 15 PIO-lite
and 16 SPI0. Bits 17-31 are reserved. Bits 14/15/16 are additive target
allocations; existing offsets/bits and RCU ABI 1.0 semantics remain unchanged.
R2-P7 may reserve the control plumbing
but MUST report bit 14 clear and reject its commands until R2-P9 instantiates
the complete DVP idle/reset/CDC path. It MUST report bit 15 clear and reject
its commands until `PIOLITE-P3` instantiates the complete PIO-lite idle/reset
path. No capability is inferred from a tie-off.
SPI target bit 16 MUST stay clear and its commands MUST fail until `SPI-P3`
connects the complete idle/reset/pad-session and DMA drain path. SPI reset
does not release or hide its reservation before accepted work is drained.
CPU gating means permission to gate only while WFI/idle with no pending IRQ or
debug request; it is not an immediate software stop. RCU/REF24, AXI, main
SRAM, XPI, CLINT, ArchInfo and RTC/WDG functional clocks cannot be gated or
@@ -1375,6 +1498,17 @@ stop/drain PIO-lite and explicitly release its pins, then issue the GPIO
command. PIO target-15 gate/reset and CLOCK_APPLY require the PIO-lite
quiesce/drain checks defined in [piolite.md](piolite.md); preserve bounded
failure and continued control access when a machine is stalled on input/FIFO.
The GPIO veto is the OR of actual PIO `USER_SELECT` ownership and any latched
SPI session reservation. SPI reservations include prefilled/armed, active,
CS-held and closing sessions until complete drain and checked release;
configuration changes or temporary guard loss cannot hide that reservation.
This veto also rejects a combined GPIO/SPI or GPIO/PIO/SPI mask without
partial commit. SPI target-16 gate/reset and CLOCK_APPLY require inactive CS,
disabled SPI with its session released, completed final serial edge/setup/hold
timing, and complete accepted
FIFO-MMIO, DMA, descriptor and response drain. Recheck ownership/readiness at
commit. Ordinary reset/gating cannot forcibly discard accepted work or
silently release pads; coordinated system reset remains a separate operation.
After draining associated DMA and accesses, hold each local reset for at
least five running local cycles and apply the five-edge release/barrier
sequence. RESET_DONE acknowledges the reset sequence, not Crypto erasure or
@@ -1521,6 +1655,31 @@ Watchdog provides whole-system recovery from a nonresponsive target; this
baseline makes no unrestricted AXI liveness, secure-boot, production-entropy,
isolation, or safety-certification claim.
## SPI extension development and acceptance
The separately approved [SPI contract](spi.md) owns the following phases;
Target SoCs is `TINY` for every phase. Mini receives only shared-consumer
compatibility checks, not a SPI product rollout. Documentation freeze closes
no implementation or physical gate. The detailed matrix and actual evidence
belong in [SPI verification](spi-verification.md).
| Phase | Tiny integration boundary |
| --- | --- |
| SPI-P0 - Contract and DMA Extension Freeze | Freeze the SPI/transaction ABI, DMA V2.2 paced fixed-MMIO contract, product routes, ownership and qualification boundaries. |
| SPI-P1 - SPI Core and Register Implementation | Implement and verify the PCLK master engine, 8/16-bit words, TX/RX FIFOs, CS timing, errors and register parity. |
| SPI-P2 - DMA V2.2 Paced FIFO Integration | Implement requests 16/17, single-beat MMIO pacing, exclusive grants and complete accepted-transfer/descriptor drain while preserving existing requests. |
| SPI-P3 - Tiny GPIO RCU and SDK Integration | Require accepted R2-P6 frozen Gen1 routes/eight-channel integration and R2-P7 lifecycle behavior; integrate APB/IRQ/RCU16, native/USER guards, transaction-latched source qualification, bounded HAL and software-managed segments. |
| SPI-P4 - Display and Snapshot Application Qualification | Require R2-P8 PSRAM and R2-P9 camera acceptance for capture/verify/display/SD cases; qualify display transactions, channel handback, source conversion and bounded contention. |
| SPI-P5 - IHP130 Timing and Physical Qualification | Qualify the actual SPI- and PIO-inclusive netlist, PCLK/IO timing, CDC/RDC, reset/gating, area, power and package conditions with the corresponding R2-P11/PIO evidence. |
Do not renumber or rewrite historical `TINY-P0..P12`, active
`TINY-R2-P0..P11` or `PIOLITE-P0..P5` titles or evidence. Their original
performance-only exclusions remain historical scope boundaries; SPI is
required only through this separate standard-product approval. Joint final
runs must satisfy each applicable contract on the same source revision,
configuration, physical inputs and netlist. SPI-only, PIO-only or earlier R2
results cannot qualify the completed standard product.
## Development order and acceptance
The active roadmap is `TINY-R2-P0` through `TINY-R2-P11`. R2 is a roadmap
+8
View File
@@ -72,6 +72,14 @@ PIO-inclusive application, timing and physical evidence. Other products remain
outside this feature scope; the [verification ledger](ip/piolite-verification.md)
records the unimplemented and unqualified boundary.
The separately approved 2026-10-04 [SPI extension](ip/spi.md) adds one future
standard Tiny master/display controller using four previously reserved Gen1
ALT routes without adding package pins. It uses packed 8/16-bit transfers,
DMA V2.2 pacing and a separate `SPI-P0..P5` roadmap. Its initial application
is sequential capture/verify/display/SD save, not simultaneous video. The
existing XPI LCD path is unchanged; the [SPI evidence ledger](ip/spi-verification.md)
keeps implementation and qualification gaps explicit alongside R2 and PIO.
### Gen1 Product and Package Target
| Area | Tiny Gen1 target |
+6
View File
@@ -17,6 +17,12 @@ filelists yet. The [verification ledger](../../docs/ip/piolite-verification.md)
keeps model, RTL, integration and physical gates separate from design freeze;
shared DMA/GPIO changes must preserve Mini behavior without enabling PIO there.
The [independent SPI master](../../docs/ip/spi.md) is a separately frozen future
Tiny block, distinct from SPI-SD and XPI. Its APB/packed FIFOs, native GPIO
guard, source-qualified DMA V2.2 MMIO pacing and `SPI-P0..P5` gates are defined
there, with [pending verification](../../docs/ip/spi-verification.md). A
specification or reserved route does not add it to the current RTL/filelists.
experimental contains retained inactive RTL. It is not included by any active
filelist and must not become a build dependency without an explicit integration
change and matching validation.
+32
View File
@@ -65,6 +65,38 @@ require pin-level XPI PSRAM and full-frame readback, not fast-flash or
separate-controller evidence.
No camera/PSRAM rate is qualified by this freeze.
The separately approved [SPI extension](../../docs/ip/spi.md) adds SPI0 to the
future standard Tiny product, with its own `SPI-P0` through `SPI-P5` phases.
It is a PCLK master-only 8/16-bit controller with separate 8 x 32-bit TX/RX
FIFOs, APB4 `0x1001D000..0x1001DFFF`, IRQ25 and RCU target16. DMA V2.2 adds
paced fixed-MMIO requests `SPI_TX=16` / `SPI_RX=17`; payload MMIO retains
single-beat transactions. TX borrows channel3 and RX channel2 only after
prior owners fully drain and release them. No extra AXI master, DMA channel,
SRAM capacity or pad is added. None of these paths exists in the current
24 MHz/no-PLL/four-channel RTL/profile.
The frozen Gen1 routes add only GPIO27 ALT0 SCK, GPIO28 ALT1 MOSI, GPIO30
ALT1 MISO and GPIO31 ALT1 CS_N. Write-only display mode uses ordinary GPIO30
as D/C instead of MISO. Other Gen1 alternates, GPIO29 NSS1 and QFN64 terminal
assignments remain unchanged. `SPI-P3` depends on R2-P6 applying the approved
Gen1 routes, including moving legacy GPIO30/31 PWM capture to GPIO24/25 ALT0,
and on R2-P7 clock/reset behavior. PIO-lite remains the sole USER owner;
SPI native-ready requires USER_SELECT and handoff clear on its session mask
plus valid ALT and GPIO lifecycle state; PIO may retain unrelated pads.
Zero USER_STATUS alone does not prove native readiness.
GPIO gate/reset is rejected while actual PIO ownership or a latched SPI
session remains, including prefill, retained CS and closing/drain state.
SPI gate/reset and PCLK changes require inactive CS and complete wire/DMA drain.
`SPI-P4` camera/PSRAM acceptance depends on R2-P8/R2-P9 and follows capture,
full-frame verification, display, then SD save. It does not add continuous
double-buffer capture/display. The complete camera profile plus display uses
all 32 GPIO; separate display reset/backlight/TE needs an explicit board
solution. `SPI-P5`, PIOLITE-P5 and final R2 physical acceptance must identify
the same SPI- and PIO-inclusive source, configuration and netlist. PCLK24/48/60
and arithmetic SCK12/24/30 MHz ceilings are not qualified pad rates. See the
[SPI evidence ledger](../../docs/ip/spi-verification.md) for pending gates.
`make CONFIG=configs/ci/ihp130-tiny.mk regress-pr` runs only Tiny's IHP130
matrix. The regression runner also accepts `--soc TINY`; leaving it unset
retains the combined Mini/Tiny IHP130 matrix. `netsim-boot` uses the compact