After every reset the boot ROM reads one register before all others: RST_CAUSE. A driver that reprograms the DMA without checking whether the reset was a wake, losing its buffers, or that clears the cause before logging it, turns recoverable events into mysteries. This lesson walks the RSTPWR file in the order software uses it and gives the decoder every boot image shares. Its one job is the software view; the source details belong to the first lesson.
The file sits in a secure-only 4 KB slot at 0x4000_6000, so only secure software resets, gates or repowers the chip. RST_CAUSE at 0x00 carries POR, PAD, SW and WAKE as write-1-to-clear bits, reset only by POR so that no later reset destroys the evidence. SWRST at 0x04 is write-only with the 0xA5 key in bits 15 down to 8: without the key the write is ignored, which keeps stray pointer writes from resetting the chip. PLL_CTRL and PLL_STATUS hold the enable and the lock flag; PWR_CTRL and PWR_STATUS hold the power-down request and the switch state; CLK_EN holds the two block enables, reset to both on; PWR_IRQ collects lock and power-up events behind a single level interrupt at the highest controller priority.
# Boot decoder shared by ROM and firmware: cause bits to boot action.
# RST_CAUSE is W1C and POR-sticky: read it first, log it, then clear.
CAUSE_ACTION = {0: "POR: full boot, reload image over SPI",
1: "PAD: full boot, SRAM0 may hold a stale image, reload",
2: "SW: sys+cpu reset only, peripherals live, reprogram DMA",
3: "WAKE: resume retained SRAM0 image, skip the SPI load"}
def boot_action(cause):
hits = [CAUSE_ACTION[b] for b in range(4) if cause & (1 << b)]
assert len(hits) >= 1, hex(cause) # a reset always leaves a cause
return hits
assert boot_action(0x1) == [CAUSE_ACTION[0]]
assert boot_action(0x8) == [CAUSE_ACTION[3]]
assert boot_action(0x4) == [CAUSE_ACTION[2]]
# SWRST key check: bits [15:8] must read 0xA5 or the write is ignored.
SWRST_KEY = 0xA5
assert (0xA500 | 0x1) >> 8 == SWRST_KEY
assert 0x0001 >> 8 != SWRST_KEY # the stray write that must not reset
print("PASS: 4 causes decode to boot actions; SWRST key gate holds")The boot image reads RST_CAUSE before any clear, and the log proves it: field returns carry the cause.
Every SWRST write carries the key; the test suite includes the missing-key write that must not reset.
Secure-only access is tested from both states: non-secure writes refused, secure writes honoured.
Walk every register from both security states and confirm the access rules, then fire each reset source and confirm the cause bit before clearing it. A cause that never sets points at the W1C wiring or at a POR-scoped clear on the wrong path; a software reset that fires without the key points at a decoder that dropped the key check. For the power registers see the power architecture section, described in words; the reset-relevant halves are covered here.
So every later reset adds its bit without destroying earlier evidence: a pad reset after a wake still shows both. Only the supply loss that truly restarts history clears the record.