Skip to content

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):

  1. 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.
  2. 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.
  3. 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.08P1.02/P1.03/P1.10/P1.08 (now all-P1 → SPIM22 binds cleanly).
  • ACC INT1/INT2 move from P2.08/P2.09P1.11/P1.13 (GPIOTE20 wake-capable).
  • Service button moves from P2.06P0.04 (GPIOTE30 wake-capable).
  • UART0 RX moves from P2.07P0.03 (UARTE30 same-port with P0.02 TX).
  • Six total pins relocated. Schematic version bumps 230220A2230220B1.

232200 / 232201 Station Anchor

  • Same UART0 RX + button move as 230220.
  • P1.02/P1.03/P1.10/P1.08/P1.11/P1.13 are mux-configured per 230220 ACC pinout but peripheral is not populated (current behaviour preserved).
  • On 232201 only: P2.03 DC_PRESENTP1.13, P2.04 CHARGE_STATUSP1.14. P2.05 CHARGE_ENABLE stays.

232202 Station Gateway

  • Same UART0 RX + button move.
  • UART1 to ESP32 moves from P0.03/P0.04P1.02/P1.03 (now UARTE22, P1-only).
  • ESP32_READY moves from P2.08P1.11 (GPIOTE20 wake-capable). Replaces the previous polled-only handshake.
  • ESP32_RESET stays on P1.10.
  • Coex stays on P2.00/P2.01/P2.02 — Wirepas has no MPSL coex driver, so polling is acceptable. Output COEX_GRANT on 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, now P1.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:

  1. Master GPIO mux table in docs/firmware-compatibility.md — update rows for every changed pin; this is the single source of truth.
  2. 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. Frontmatter current_rev: B1-draft.
  3. 232200–232204 PCB docs — pin tables §4.2 (each board has its own copy that mirrors 230220). Frontmatter current_rev: B1-draft on each.
  4. Firmware spec (docs/firmware/station/tag-anchor.md) — pin references for the firmware build.
  5. revisions.md per board — add a B1 (Draft) row to the summary table and a "Rev B1 — In Design" detail section listing the moves. Keep A2 — Current until release.
  6. PR review by HW lead + FW engineer.
  7. Merge to main when design is locked.
  8. Wait for EMS release of B1 hardware.
  9. At EMS release: bump frontmatter to current_rev: B1, released: <date>. Mark A2 as Superseded. Tag pcb-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