Skip to content

Boot Self-Test & Traceability

Authoritative specification for the EverTag Station boot self-test sequence, traceability record format, and diagnostic error codes. The self-test runs automatically on every boot. Results are reported on UART0 and LED1 during the 5-minute active window.

Design Principle: Diagnostic, Not Protective

The self-test is observational, not gatekeeping. All test results are reported but no test result prevents the device from completing initialization and joining the Wirepas network. The production test station or cloud monitoring system is responsible for acting on error codes. The firmware's role is to detect and report -- not to halt boot.


1. Boot Sequence & Self-Test Timing

The self-test runs as part of the standard boot sequence, after board detection and before peripheral initialization. The entire test phase completes in 2--5 seconds.

graph TD
    BOOT["Boot"] --> V_SAMPLE["1. Read V_SAMPLE (P1.07) — board variant"]
    V_SAMPLE --> EXT["2. Read EXT_DETECT (P1.12) — extension board"]
    EXT --> BAT["3. Read BAT_VOLTAGE (P1.06) — battery variants"]
    BAT --> SELFTEST["4. Run self-test suite for detected variant"]
    SELFTEST --> RECORD["5. Output traceability record on UART0"]
    RECORD --> RESULTS["6. Output self-test results on UART0"]
    RESULTS --> MUX["7. Configure GPIO mux"]
    MUX --> INIT["8. Initialize peripherals for detected board"]
    INIT --> LED["9. LED1 enters active mode (5-min timer)"]
    LED --> DIAG{"Errors detected?"}
    DIAG -->|"Yes"| BLINK["LED1: Diagnostic blink mode (error codes)"]
    DIAG -->|"No"| NORMAL["LED1: Normal status (WHITE → YELLOW → GREEN)"]
    BLINK --> JOIN["10. Join Wirepas network (always, regardless of errors)"]
    NORMAL --> JOIN

UART0 Active Window

UART0 outputs the traceability record and self-test results immediately after the test phase completes (~3 seconds into boot). UART0 remains available for CLI commands throughout normal operation. The 5-minute active window refers to the LED -- UART0 is not time-limited.

LED Diagnostic Window

During the 5-minute active window after boot, LED1 shows either diagnostic blink patterns (if errors exist) or normal status progression (if all tests pass). After 5 minutes, LED1 enters dormant mode regardless of errors. Error flags remain in RAM and are queryable via CLI (status command), NFC, and Wirepas status messages.


2. Traceability Record Format

The traceability record is output on UART0 (115200 8N1) as a flat KEY:VALUE block. Every key is on its own line. No spaces in values. Delimited by ---BEGIN_TRACE--- and ---END_TRACE--- markers.

Format Rules

  • One KEY:VALUE pair per line. Colon separates key from value.
  • Keys are UPPER_SNAKE_CASE. No spaces.
  • Values contain no spaces. Multi-word values use underscores or hyphens.
  • The test station parses by scanning for markers and extracting any key with: grep "^KEY:" | cut -d: -f2-
  • The device does not output a wall-clock timestamp. The test station records its own timestamp when capturing the trace (Option B).

Full Traceability Record

---BEGIN_TRACE---
FW_IMAGE:evertag-anchor-nrf54
FW_VERSION:1.0.0
FW_BUILD:2026-02-24T14:32:05
FW_GIT:a3f7c21
WP_STACK:5.6.0
BOOTLOADER:1.0.0
NRF54_DEVID:7A3B1C4D9E8F2A1B
NRF54_BLEADDR:F4:CE:36:A1:B2:C3
NRF54_FLASH_KB:256
NRF54_RAM_KB:256
NRF54_VARIANT:QFAA
ST25DV_UID:02E3440000160200
ST25DV_MEM_KBIT:4
ESP32_CHIPID:N/A
ESP32_MODEL:N/A
ESP32_REVISION:N/A
ESP32_FLASH_MB:N/A
ESP32_FW_VERSION:N/A
ESP32_FW_BUILD:N/A
BOARD_ARTICLE:232201
V_SAMPLE_RAW:1016
EXTENSION:NONE
EXT_DETECT_RAW:12
BAT_VOLTAGE:3.24
BAT_VOLTAGE_RAW:2654
CHARGER_STATE:CHARGING
AC_POWER:PRESENT
VDD_3V3:3.31
DIE_TEMP_C:27
LFXO:OK
WP_NODE_ADDR:70001
WP_NET_ADDR:0x1234
WP_NET_CHAN:15
SELF_TEST:PASS
ERROR_CODES:NONE
ERROR_COUNT:0
---END_TRACE---

Field Reference

Silicon Identifiers (immutable, factory-programmed)

Key Source Example Description
NRF54_DEVID FICR DEVICEID[0:1] 7A3B1C4D9E8F2A1B 64-bit unique device ID, factory-burned by Nordic
NRF54_BLEADDR FICR DEVICEADDR[0:1] F4:CE:36:A1:B2:C3 48-bit BLE address
NRF54_FLASH_KB FICR INFO.FLASH 256 Flash size in KB
NRF54_RAM_KB FICR INFO.RAM 256 RAM size in KB
NRF54_VARIANT FICR INFO.VARIANT QFAA Chip variant (package + memory)
ST25DV_UID I2C system area read 02E3440000160200 8-byte ISO 15693 unique ID
ST25DV_MEM_KBIT I2C system area read 4 NFC memory size (4 = ST25DV04K)
ESP32_CHIPID esp_efuse_mac_get_default() via UART1 00A1B2C3D4E5 ESP32 48-bit MAC-derived unique ID. N/A on non-gateway.
ESP32_MODEL ESP32 system info via UART1 ESP32-C5 SoC model. N/A on non-gateway.
ESP32_REVISION ESP32 efuse via UART1 0 Silicon revision. N/A on non-gateway.
ESP32_FLASH_MB ESP32 SPI flash detect via UART1 4 Flash size in MB. N/A on non-gateway.

Firmware Identifiers (compiled into the binary)

Key Source Example Description
FW_IMAGE Build system #define evertag-anchor-nrf54 Firmware build name
FW_VERSION Semantic version 1.0.0 Major.Minor.Patch
FW_BUILD __DATE__ + __TIME__ 2026-02-24T14:32:05 Compile timestamp (ISO 8601)
FW_GIT Build system a3f7c21 Short SHA of source commit
WP_STACK Wirepas SDK version 5.6.0 Wirepas mesh stack version
BOOTLOADER Bootloader version area 1.0.0 Secure boot / DFU bootloader version
ESP32_FW_VERSION Queried via UART1 0.8.1 ESP32 firmware version. N/A on non-gateway.
ESP32_FW_BUILD Queried via UART1 2026-02-24T14:35:00 ESP32 firmware build date. N/A on non-gateway.

Hardware Configuration (detected at boot)

Key Source Example Description
BOARD_ARTICLE V_SAMPLE ADC → lookup 232201 Decoded board variant
V_SAMPLE_RAW P1.07 SAADC 1016 Raw 12-bit ADC value
EXTENSION EXT_DETECT ADC → lookup NONE Detected extension board (NONE, 232210, 232211)
EXT_DETECT_RAW P1.12 SAADC 12 Raw 12-bit ADC value

Runtime Measurements (measured during self-test)

Key Source Example Description
BAT_VOLTAGE P1.06 SAADC (via divider) 3.24 Battery voltage in V. N/A on non-battery variants.
BAT_VOLTAGE_RAW P1.06 SAADC 2654 Raw 12-bit ADC value. N/A on non-battery.
CHARGER_STATE P2.03 / P2.04 GPIO + BAT_VOLTAGE CHARGING CHARGING, COMPLETE, STANDBY, or NO_AC. N/A on non-battery.
AC_POWER P2.03 (DC_PRESENT) PRESENT PRESENT or ABSENT. N/A on non-battery.
VDD_3V3 nRF54 internal SAADC VDD channel 3.31 Supply rail voltage in V
DIE_TEMP_C nRF54 internal temp sensor 27 Die temperature in °C
LFXO Clock status register OK OK or FAIL

Assigned Identifiers (programmed or auto-assigned)

Key Source Example Description
WP_NODE_ADDR Config flash 70001 Wirepas node address
WP_NET_ADDR Config flash 0x1234 Wirepas network address
WP_NET_CHAN Config flash 15 Wirepas network channel

Self-Test Summary

Key Source Example Description
SELF_TEST Self-test engine PASS or FAIL Overall result
ERROR_CODES Self-test engine E03,W01 or NONE Comma-separated list of active error/warning codes
ERROR_COUNT Self-test engine 2 Total number of errors and warnings

3. Self-Test Suite

Variant-Aware Test List

The firmware determines the test list based on BOARD_ARTICLE and EXTENSION. Every test in the list runs. There are no skips -- only tests that apply to the detected variant are executed.

Test ID Name Applies To What It Checks
T01 Board variant valid All V_SAMPLE ADC falls within a defined board window
T02 FW/board match All Firmware build type (anchor/gateway) matches V_SAMPLE range
T03 NFC controller present All I2C scan finds ST25DV04K at addresses 0x53 and 0x57
T04 LFXO crystal running All 32.768 kHz oscillator status register confirms running
T05 VDD rail in range All Internal VDD measurement is 3.0--3.6V
T06 Die temperature sane All Internal temp sensor reads -40°C to +85°C
T07 Battery present 232201, 232203, 232204 BAT_VOLTAGE > 1.0V
T08 Battery voltage healthy 232201, 232203, 232204 BAT_VOLTAGE in range 2.5--3.6V
T09 Charger responding 232201, 232203, 232204 Charger state machine is not in FAULT state
T10 AC power present 232201, 232203, 232204 DC_PRESENT (P2.03) reads LOW (5V present)
T11 ESP32 boot 232202, 232203 READY pin (P2.08) goes HIGH within 5 seconds after reset
T12 ESP32 UART comms 232202, 232203 UART1 ping/response received within 2 seconds

Tests per variant:

Variant Tests Run Count
232200 (anchor, no battery) T01--T06 6
232201 (anchor + battery) T01--T10 10
232202 (gateway, no battery) T01--T06, T11--T12 8
232203 (gateway + battery) T01--T12 12
232204 (anchor + bat + radar) T01--T10 10

UART0 Self-Test Output

Follows the traceability record, using the same KEY:VALUE format:

---BEGIN_SELFTEST---
T01:PASS
T02:PASS
T03:PASS
T04:PASS
T05:PASS
T06:PASS
T07:FAIL:E03
T08:FAIL:E04
T09:PASS
T10:PASS
RESULT:FAIL
ERROR_CODES:E03,E04
ERROR_COUNT:2
---END_SELFTEST---

Each test line is Txx:PASS or Txx:FAIL:Eyy (linking the test to its error code). The test station parses RESULT: for the overall verdict and ERROR_CODES: for specific failures.

Battery Detection Logic

The battery presence test (T07) combines two independent checks:

Check Method Pass Condition
Voltage check P1.06 SAADC (BAT_VOLTAGE) Reading > 1.0V
Charger state P2.03 (DC_PRESENT), P2.04 (CHARGE_STATUS) CHARGE_STATUS LOW when DC present

Both checks must indicate "no battery" to trigger E03. This prevents false positives from a noisy ADC reading alone.

BAT_VOLTAGE CHARGE_STATUS (with DC) Interpretation
> 2.5V LOW (charging) or HIGH (idle, bat full) Battery present, healthy
1.0V -- 2.5V LOW (charging) Battery present, deeply discharged (W02)
< 1.0V HIGH (idle) Battery missing (E03)
< 1.0V LOW Ambiguous -- log raw values, report E03

4. Error Code Registry

Errors (assembly/hardware failures)

Code Name Trigger Condition Detection Blink Count Color
E01 Board variant unknown V_SAMPLE ADC outside all defined windows P1.07 ADC 1 long RED
E02 Firmware/board mismatch Gateway FW on anchor board or vice versa V_SAMPLE vs. build type 2 long RED
E03 Battery missing Battery variant detected, BAT_VOLTAGE < 1.0V P1.06 ADC + charger GPIO 3 long RED
E04 Battery fault CHARGE_STATUS LOW for longer than safety timer (4h) P2.04 GPIO + timeout 4 long RED
E05 NFC controller absent ST25DV04K not found at I2C 0x53/0x57 I2C bus scan 5 long RED
E06 ESP32 not responding Gateway variant, READY not HIGH within 5s P2.08 GPIO timeout 6 long RED
E07 Crystal failure 32.768 kHz LFXO not oscillating Clock status register 1 short + 1 long RED

Warnings (non-critical, device operates but should be investigated)

Code Name Trigger Condition Detection Blink Count Color
W01 Battery low BAT_VOLTAGE between 2.5V and 3.0V P1.06 ADC 1 long AMBER
W02 Battery deeply discharged BAT_VOLTAGE between 1.0V and 2.5V P1.06 ADC 2 long AMBER
W03 Unexpected extension Extension board detected on a variant that doesn't use it P1.12 ADC 3 long AMBER
W04 No AC power at boot DC_PRESENT HIGH (running on battery from first boot) P2.03 GPIO 4 long AMBER

Reserved Codes (future expansion)

Code Range Reserved For
E08--E12 Radar sensor, LTE modem, SIM card detection
E13--E99 Future hardware tests
W05--W09 Radar/LTE signal quality warnings
W10--W99 Future non-critical warnings

Extensibility

New tests and error codes are added by extending the test list for the relevant BOARD_ARTICLE + EXTENSION combination. The UART format, KEY:VALUE structure, and blink protocol do not change. Add new Txx / Exx / Wxx entries and update this registry.


The Station inherits the EverTag blink timing defined in the EverTag User Guide — LED Patterns:

Blink Type ON Time OFF Time Slot Duration
Short blink 100 ms 400 ms 500 ms
Long blink 250 ms 250 ms 500 ms

A complete blink sequence is 4 seconds: 3 seconds of active blink slots (6 × 500 ms) followed by 1 second of silence (separator).

Diagnostic Mode

When the self-test detects one or more errors or warnings, LED1 enters diagnostic blink mode for the duration of the 5-minute active window. Diagnostic mode replaces the generic "RED fast blink" (priority 1 in the UI Behavior spec) with specific counted blink patterns that identify each error code.

Each error/warning code is displayed as a counted blink sequence:

  1. Show blink pattern for the error code (N long blinks in the code's color)
  2. 1-second dark pause
  3. Repeat the same pattern (shown twice for readability)
  4. 2-second dark pause
  5. Next error code (if multiple errors)
  6. After all codes are shown: 3-second dark gap, then the full cycle repeats

Color Encoding

Color RGB Value Severity Meaning
RED (255, 0, 0) Error Hardware fault or assembly defect -- production line must act
AMBER (255, 160, 0) Warning Non-critical issue -- device operates but should be investigated
Code Blink Count Color 4s Encoding (EverTag format) Visual
E01 1 long RED 0xFF200000 ──
E02 2 long RED 0xFF220000 ── ──
E03 3 long RED 0xFF222000 ── ── ──
E04 4 long RED 0xFF222200 ── ── ── ──
E05 5 long RED 0xFF222220 ── ── ── ── ──
E06 6 long RED 0xFF222222 ── ── ── ── ── ──
E07 1 short + 1 long RED 0xFF120000 · ──
W01 1 long AMBER 0xFF200000 ── (amber)
W02 2 long AMBER 0xFF220000 ── ── (amber)
W03 3 long AMBER 0xFF222000 ── ── ── (amber)
W04 4 long AMBER 0xFF222200 ── ── ── ── (amber)

0xFF as the repeat byte means "repeat indefinitely" (until the 5-minute window expires).

Timeline Example: E03 + W01

Time:  0s    3s 4s    7s 8s  9s   12s13s  16s17s 19s 20s   23s
       |      | |      | |   |     | |     | |   |   |      |
RED:   ──── ── |──── ──|     |     | |     | |   |   |──── ──
       E03 ×1  |E03 ×2 |     |     | |     | |   |   |E03 ×1
               |       |2s   |     | |     | |   |3s |
               |       pause |     | |     | |   gap  cycle
                       AMBER:|── ──| |── ──| |        repeats
                       W01×1   1s    W01×2
                                    pause

No Errors: Normal Status Progression

When all self-tests pass, LED1 displays the normal UI Behavior status sequence during the active window:

  1. WHITE breathing (booting, ~5--30 seconds)
  2. YELLOW solid (powered, no Wirepas network)
  3. BLUE solid (Wirepas joined, no sink)
  4. GREEN solid (Wirepas operational)

6. Error Reporting Channels

Error flags from the self-test are stored in RAM and available through multiple channels beyond UART0:

Channel How Available On
UART0 Traceability record + self-test output at boot All variants (via TC2030)
UART0 CLI status command reports active errors anytime All variants
LED1 Diagnostic blink patterns during active window All variants
NFC Error flags written to ST25DV04K memory area All variants (phone tap readout)
Wirepas mesh Error flags in periodic status messages All variants (cloud monitoring)
Web UI Device tab shows error codes and descriptions Gateway variants (232202+)

CLI Example

> status
Board: 232201 (Station Bat), Extension: None
FW: evertag-anchor-nrf54 v1.0.0 (a3f7c21)
Wirepas: joined, node 70001, ch 15
NFC: ST25DV04K online
Battery: 3.24V, CHARGING, AC PRESENT
Self-test: FAIL
  E03: Battery missing (BAT_VOLTAGE=0.01V)
Uptime: 00:04:32

7. Production Test Station Integration

The test station workflow uses the traceability record and self-test output for automated pass/fail decisions. The test station provides the timestamp (Option B -- the device does not output wall-clock time).

Workflow

1. Program nRF54 firmware via SWD (TC2030 J1)
2. Program ESP32 firmware via UART (TC2030 J2) — gateway variants only
3. Device boots → self-test runs (~3 seconds)
4. Test station reads UART0 via TC2030 cable
5. Scan for ---BEGIN_TRACE--- / ---END_TRACE--- markers
6. Scan for ---BEGIN_SELFTEST--- / ---END_SELFTEST--- markers
7. Parse RESULT: line
8.   If RESULT:PASS → log trace data → label and box
9.   If RESULT:FAIL → read ERROR_CODES: → log → reject unit
10. Operator sees RED LED = visual confirmation of reject
11. Test station records its own timestamp alongside the captured data
12. Disconnect TC2030, move to next unit

Test Station Data Storage

The test station stores the full KEY:VALUE block for each unit. This creates a manufacturing database where any unit can be traced by its NRF54_DEVID and cross-referenced with BOARD_ARTICLE, FW_VERSION, BAT_VOLTAGE, and all other fields. Raw ADC values (V_SAMPLE_RAW, BAT_VOLTAGE_RAW, EXT_DETECT_RAW) enable post-production quality analytics (e.g., detecting batch-level drift).


8. Continuous Monitoring (Field Operation)

The self-test runs at every boot, not just initial programming. Field reboots (power cycle, watchdog, OTA update) re-run the full test suite for the detected variant. This catches degradation over time (e.g., battery aging, connector oxidation, crystal drift).

Additionally, the firmware periodically re-checks a subset of measurements during normal operation:

Check Interval Error if
BAT_VOLTAGE Every 60 seconds (battery variants) Drops below 2.5V (W01) or below 1.0V (E03)
Charger state Every 60 seconds (battery variants) Enters FAULT state (E04)
VDD rail Every 300 seconds Outside 3.0--3.6V range
Die temperature Every 300 seconds Outside -40°C to +85°C

Runtime-detected errors update the error flags in RAM and are reported via CLI, NFC, and Wirepas status messages. LED1 shows diagnostic blinks on the next button press (active window activation).


Revision History

Revision Date Author Changes
1.0 2026-02-24 CargoBeacon Initial specification