Rev B1 ECN-01 — nRF54L15 GPIO remap (draft)¶
Draft — for design-session review
This document is the proposed B1 pin map for the nRF54-family PCBs. It has not been approved or implemented. The currently released revision is A2 (locked at git tags pcb-230220-A2 and pcb-23220x-A2). Approval required before any board file is updated.
1. Background¶
The May 2026 nRF54L15 datasheet review identified three hard silicon constraints that the A2 PCBs violate (see Firmware Compatibility for full analysis):
- SPI port lock — each SPIM instance is bound to one GPIO port. The A2 accelerometer SPI is split across P0 (SCK/MISO) and P1 (MOSI/CS) — no SPIM instance can bind it.
- UART port lock — each UARTE instance is bound to one GPIO port. The A2 UART0 is split across P0.02 (TX) and P2.07 (RX) — no UARTE can bind it.
- No GPIOTE on P2 — only GPIOTE20 (P1) and GPIOTE30 (P0) exist. The A2 service button (P2.06), accelerometer INTs (P2.08/P2.09), AC-loss sense (P2.03), and ESP32_READY (P2.08) cannot generate interrupts or wake the MCU.
Rev B1 reroutes all affected signals to compliant ports. A2 is deprecated when B1 ships.
Station-only mechanical changes (screw mount, daughter-board slots) ship in the same B1 respin — see ECN-02 enclosure mounting. PAN611 antenna keep-out on Station boards — see ECN-03 PAN611 antenna keep-out. PAN611 stepped footprint — see ECN-08 stepped footprint. Tag (230220): Rev B1 ECN-01 — Tag GPIO remap, Rev B1 ECN-04 — PAN611 keep-out, Rev B1 ECN-09 — PAN611 stepped footprint.
2. Scope¶
All six nRF54L15-based boards go to Rev B1 simultaneously to preserve the shared-pinout rule (230220 is the pin-out reference for the entire family):
| Board | Family | Variant |
|---|---|---|
| 230220 | Tag | Base (battery, accelerometer) |
| 232200 | Station | Base Std |
| 232201 | Station | Base Bat |
| 232202 | Station | Base WiFi (gateway) |
| 232203 | Station | Base Bat+WiFi (gateway+battery) |
| 232204 | Station | Base Bat+Radar (anchor+sensor) |
3. Hard constraints (silicon rules)¶
Per the nRF54L15 product spec v1.0:
| Peripheral | Allowed ports |
|---|---|
| SPIM30 / UARTE30 / TWIM30 | P0 only |
| SPIM20/21, SPIM22, UARTE20/21, UARTE22, TWIM20/21/22 | P1 only (SPIM20/21 + UARTE20/21 can also use dedicated P2 pins via cross-domain, requires Constant Latency power mode) |
| SPIM00 / UARTE00 | dedicated P2 only (HS, 32 MHz) |
| GPIOTE30 | P0 only — 4 channels |
| GPIOTE20 | P1 only — 8 channels |
| (no GPIOTE for P2) | — |
4. Design principles applied¶
| Principle | Rationale |
|---|---|
| Functions needed on every board → P0 | UART0 + Button — central, used by all 6 variants |
| Variant-specific peripherals → P1 | SPI accelerometer (Tag), UART1 (gateway), sensor SPI (232204) — all fit P1's larger pin count |
P2 reserved for available, outputs, and polled-only inputs |
No interrupts on P2 — only Coex (which Wirepas doesn't drive anyway), CHARGE_ENABLE, NFC.VCC, COEX_GRANT |
| Direction must match across boards | Same physical pin always has same direction, function may differ per variant (existing rule from firmware-compatibility.md §3) |
| Wirepas coex pins stay polled | Wirepas has no MPSL coex driver; arbitration deferred → no INT needed → P2 OK |
5. GPIO budget¶
| Port | Total pins | Active in A2 | Active in B1 | Notes |
|---|---|---|---|---|
| P0 | 5 (P0.00–P0.04) | 5 | 5 | Fully used by platform-wide functions |
| P1 | 16 (P1.00–P1.15) | 13 | 16 (excl. LFXO) | All 5 free A2 pins claimed in B1 |
| P2 | 11 (P2.00–P2.10) | 6 | 5 | Mostly freed by interrupt moves |
P0 budget is fully committed in B1. P1 has 7 active pins for variant-specific use (P1.02, P1.03, P1.06, P1.08, P1.10, P1.11, P1.13, P1.14). P2 retains only outputs and polled-only inputs.
6. Proposed pin allocation (master table)¶
Pins that change function in B1 are bolded. Pins listed as "available" are mux-configured (direction set) but the peripheral is not populated on that variant.
| Pin | Dir | 230220 Tag | 232200 Anchor | 232201 Bat-Anch | 232202 Gateway | 232203 Bat+GW | 232204 Bat+Radar |
|---|---|---|---|---|---|---|---|
| P0.00 | in | B_VARIANT | B_VARIANT | B_VARIANT | B_VARIANT | B_VARIANT | B_VARIANT |
| P0.01 | out | LED_DATA | LED_DATA | LED_DATA | LED_DATA | LED_DATA | LED_DATA |
| P0.02 | out | UART0 TX | UART0 TX | UART0 TX | UART0 TX | UART0 TX | UART0 TX |
| P0.03 | in | UART0 RX | UART0 RX | UART0 RX | UART0 RX | UART0 RX | UART0 RX |
| P0.04 | in | Service button | Service button | Service button | Service button | Service button | Service button |
| P1.00 | – | LFXO | LFXO | LFXO | LFXO | LFXO | LFXO |
| P1.01 | – | LFXO | LFXO | LFXO | LFXO | LFXO | LFXO |
| P1.02 | out | ACC SCK | available | available | UART1 TX | UART1 TX | sensor SCK |
| P1.03 | in | ACC MISO | available | available | UART1 RX | UART1 RX | sensor MISO |
| P1.04 | out | I2C SCL | I2C SCL | I2C SCL | I2C SCL | I2C SCL | I2C SCL |
| P1.05 | I/O | I2C SDA | I2C SDA | I2C SDA | I2C SDA | I2C SDA | I2C SDA |
| P1.06 | ADC | (reserve) | (reserve) | BAT_VOLTAGE | (reserve) | BAT_VOLTAGE | BAT_VOLTAGE |
| P1.07 | ADC | V_SAMPLE | V_SAMPLE | V_SAMPLE | V_SAMPLE | V_SAMPLE | V_SAMPLE |
| P1.08 | out | ACC CS | available | available | available | available | sensor CS |
| P1.09 | in | NFC GPO | NFC GPO | NFC GPO | NFC GPO | NFC GPO | NFC GPO |
| P1.10 | out | ACC MOSI | available | available | ESP32_RESET | ESP32_RESET | sensor MOSI |
| P1.11 | in | ACC INT1 | available | available | ESP32_READY | ESP32_READY | sensor INT |
| P1.12 | ADC | EXT_DETECT | EXT_DETECT | EXT_DETECT | EXT_DETECT | EXT_DETECT | EXT_DETECT |
| P1.13 | in | ACC INT2 | available | DC_PRESENT | available | DC_PRESENT | DC_PRESENT |
| P1.14 | in | available | available | CHARGE_STATUS | available | CHARGE_STATUS | CHARGE_STATUS |
| P1.15 | in | NFC LPD | NFC LPD | NFC LPD | NFC LPD | NFC LPD | NFC LPD |
| P2.00 | in | available | available | available | COEX_REQUEST (polled) | COEX_REQUEST (polled) | available |
| P2.01 | in | available | available | available | COEX_PRIORITY (polled) | COEX_PRIORITY (polled) | available |
| P2.02 | out | available | available | available | COEX_GRANT | COEX_GRANT | available |
| P2.03 | – | available | available | (freed) | available | (freed) | (freed) |
| P2.04 | – | available | available | (freed) | available | (freed) | (freed) |
| P2.05 | out | available | available | CHARGE_ENABLE | available | CHARGE_ENABLE | CHARGE_ENABLE |
| P2.06 | – | (freed) | (freed) | (freed) | (freed) | (freed) | (freed) |
| P2.07 | – | (freed) | (freed) | (freed) | (freed) | (freed) | (freed) |
| P2.08 | – | (freed) | (freed) | (freed) | (freed) | (freed) | (freed) |
| P2.09 | – | (freed) | (freed) | (freed) | (freed) | (freed) | (freed) |
| P2.10 | out | NFC VCC | NFC VCC | NFC VCC | NFC VCC | NFC VCC | NFC VCC |
7. What this changes per board¶
230220 Tag¶
- SPI accelerometer moves from
P0.03/P0.04/P1.10/P1.08→P1.02/P1.03/P1.10/P1.08(now all-P1 →SPIM22binds cleanly). - ACC INT1/INT2 move from
P2.08/P2.09→P1.11/P1.13(GPIOTE20 wake-capable). - Service button moves from
P2.06→P0.04(GPIOTE30 wake-capable). - UART0 RX moves from
P2.07→P0.03(UARTE30 same-port withP0.02TX). - Six total pins relocated. Schematic version bumps
230220A2→230220B1.
232200 / 232201 Station Anchor¶
- Same UART0 RX + button move as 230220.
P1.02/P1.03/P1.10/P1.08/P1.11/P1.13are mux-configured per 230220 ACC pinout but peripheral is not populated (current behaviour preserved).- On 232201 only:
P2.03 DC_PRESENT→P1.13,P2.04 CHARGE_STATUS→P1.14.P2.05 CHARGE_ENABLEstays.
232202 Station Gateway¶
- Same UART0 RX + button move.
- UART1 to ESP32 moves from
P0.03/P0.04→P1.02/P1.03(nowUARTE22, P1-only). - ESP32_READY moves from
P2.08→P1.11(GPIOTE20 wake-capable). Replaces the previous polled-only handshake. ESP32_RESETstays onP1.10.- Coex stays on
P2.00/P2.01/P2.02— Wirepas has no MPSL coex driver, so polling is acceptable. OutputCOEX_GRANTon P2.02 is fine (no INT needed for outputs).
232203 Station Bat+Gateway¶
- Inherits all of 232201 and 232202 changes.
- No new conflicts — DC_PRESENT/CHARGE_STATUS (P1.13/P1.14) are mutually exclusive with the gateway-only functions on those pins.
232204 Station Bat+Radar¶
- UART0 RX + button move (same as all).
- DC_PRESENT/CHARGE_STATUS move from P2 → P1.13/P1.14.
- Sensor pins re-allocated: previously
P1.11/P1.13/P1.14/P1.08/P2.09, nowP1.02/P1.03/P1.10/P1.08/P1.11(all on P1 →SPIM22-capable, sensor INT on P1.11 is GPIOTE20 wake-capable). - Sensor SPI is now identical to 230220's accelerometer SPI assignment, which means a sensor variant could share that physical PCB area in a future revision.
8. Wake-source / GPIOTE budget verification¶
GPIOTE30 (P0) has 4 channels. GPIOTE20 (P1) has 8 channels.
| Variant | GPIOTE30 (P0) channels used | GPIOTE20 (P1) channels used | Status |
|---|---|---|---|
| 230220 Tag | 1 (button) | 3 (NFC GPO, ACC INT1, ACC INT2) | ✓ ¾, ⅜ |
| 232200 Anchor | 1 (button) | 1 (NFC GPO) | ✓ |
| 232201 Bat-Anchor | 1 (button) | 2 (NFC GPO, DC_PRESENT) | ✓ |
| 232202 Gateway | 1 (button) | 2 (NFC GPO, ESP32_READY) | ✓ |
| 232203 Bat+GW | 1 (button) | 3 (NFC GPO, ESP32_READY, DC_PRESENT) | ✓ ⅜ |
| 232204 Bat+Radar | 1 (button) | 3 (NFC GPO, DC_PRESENT, sensor INT) | ✓ ⅜ |
Headroom on every variant. CHARGE_STATUS is intentionally polled (slow-changing signal) to keep GPIOTE channels free for higher-priority wake sources.
9. Direction-rule verification¶
Every pin has a single direction across all 6 boards (input or output). Function changes per board, but the physical pin's mux direction is preserved. This means the existing firmware compatibility rule from firmware-compatibility.md §3 (rule 1) continues to hold.
Spot-check on the most cross-cutting pins:
| Pin | Direction | Functions (all input or all output?) |
|---|---|---|
| P1.02 | output | ACC SCK / UART1 TX / sensor SCK — ✓ all output |
| P1.03 | input | ACC MISO / UART1 RX / sensor MISO — ✓ all input |
| P1.10 | output | ACC MOSI / ESP32_RESET / sensor MOSI — ✓ all output |
| P1.11 | input | ACC INT1 / ESP32_READY / sensor INT — ✓ all input |
| P1.13 | input | ACC INT2 / DC_PRESENT — ✓ all input |
10. Conflicts resolved during this design¶
| Conflict | Resolution |
|---|---|
| ACC SPI on P0+P1 (split port) | All four ACC SPI pins moved to P1 → SPIM22 |
| UART0 on P0+P2 (split port) | UART0 RX moved from P2.07 → P0.03 → UARTE30 same-port |
| UART1 on P0 conflicts with new P0.03 (UART0 RX) | UART1 moved to P1.02/P1.03 → UARTE22 (P1-only) |
| Button needs wake but P2.06 has no GPIOTE | Button moved to P0.04 → GPIOTE30 |
| ACC INT1/INT2 need wake but P2 has no GPIOTE | INTs moved to P1.11/P1.13 → GPIOTE20 |
| ESP32_READY on P2.08 = ACC INT1 collision | Both move to P1.11 (same pin reused with same direction) |
| DC_PRESENT/CHARGE_STATUS need wake | Move to P1.13/P1.14 → GPIOTE20 |
| 232204 sensor pins overlap with new ACC SPI | Sensor moved to match ACC SPI footprint on P1 (P1.02/P1.03/P1.08/P1.10/P1.11) — single SPI lane shared by accelerometer and radar sensor concepts |
| P0 over-allocated (5 pins, 5 functions) | Acceptable — all P0 pins are platform-wide (variant-independent) functions |
11. Open questions for the design session¶
These are real decisions to make in the meeting:
| # | Question | Default if no objection |
|---|---|---|
| 1 | Confirm UARTE22 (P1.02/P1.03) for gateway UART1 — any 921600 baud headroom concerns? Datasheet says 1 Mbps capable. |
Accept |
| 2 | ESP32_READY on P1.11 as GPIOTE20 wake — required, or do we accept polled-only handshake? Polling is fine functionally but uses an extra timer slot. |
INT (P1.11) |
| 3 | Should CHARGE_STATUS (P1.14) be GPIOTE20 wake or remain polled? Charging is a slow-changing state. |
Polled |
| 4 | 232204 sensor's previous pin set (P1.11/P1.13/P1.14) is now reused for ACC/bat/INT functions. If Acconeer A121 SPI radar is the selected sensor, its INT pin behavior needs confirming — A121 supports host-driven SPI polling (no INT required). | A121 with polling |
| 5 | The schematic version bumps to B1 for the schematic field across all 6 board index.md files. Confirm naming style. |
230220B1, 232200B1, etc. |
| 6 | Should we also bump the manufacturing panel article? 230222 was the A2 panel for 230220. New panel article number for B1? |
See Rev B1 mixed-variant panel — proposed 232205 (10-up, 2× each 232200–232204) |
12. Implementation plan (after design approval)¶
The implementation work happens on this branch (rev-b/nrf54l15-gpio-remap) in the following order:
- Master GPIO mux table in
docs/firmware-compatibility.md— update rows for every changed pin; this is the single source of truth. - 230220 PCB doc (
docs/tag-nrf54/pcb/230220-base/index.md) — pin table §3.1, peripheral summary §3.2, block diagram §2, schematic field A2 → B1. Frontmattercurrent_rev: B1-draft. - 232200–232204 PCB docs — pin tables §4.2 (each board has its own copy that mirrors 230220). Frontmatter
current_rev: B1-drafton each. - Firmware spec (
docs/firmware/station/tag-anchor.md) — pin references for the firmware build. revisions.mdper board — add aB1 (Draft)row to the summary table and a "Rev B1 — In Design" detail section listing the moves. KeepA2 — Currentuntil release.- PR review by HW lead + FW engineer.
- Merge to main when design is locked.
- Wait for EMS release of B1 hardware.
- At EMS release: bump frontmatter to
current_rev: B1,released: <date>. MarkA2asSuperseded. Tagpcb-230220-B1,pcb-232200-B1, ...pcb-232204-B1. Create matching GitHub Releases.
Steps 1–6 can happen this/next week. Steps 7–9 are gated by the PCB respin and EMS turnaround.
13. Approval¶
Sign-off below before any board file is touched.
| Role | Name | Decision | Date |
|---|---|---|---|
| HW lead | Olov Hisved | ☐ Approve ☐ Revise | |
| FW engineer | (name) | ☐ Approve ☐ Revise | |
| PCB designer (Altium) | (name) | ☐ Approve ☐ Revise | |
| 232204 sensor owner | (name) | ☐ Approve ☐ Revise |
Related¶
- Revisions Policy — tag naming and lock procedure
- Rev B1 ECN-02 — Enclosure mounting — Station-only mechanical B1 (232200–232204, 232210)
- ECN-03 — Station PAN611 antenna keep-out — Station 232200–232204
- Rev B1 ECN-08 — PAN611 stepped footprint — Station 232200–232204
- Rev B1 ECN-09 — Tag PAN611 stepped footprint — 230220
- Rev B1 ECN-05 — Mixed-variant panel — Station EMS panel 232205
- Rev B1 ECN-04 — Tag PAN611 keep-out — 230220
- Rev B1 ECN-01 — Tag GPIO remap — 230220-only view
- Firmware Compatibility — current master GPIO mux table (A2)
- 230220 Revisions — A2 release record + known limitations leading to this B1 proposal