ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_lpm_safe_boot.h File Reference

Self-healing LPM register reset for very early boot. More...

#include <stdint.h>
Include dependency graph for ra8_lpm_safe_boot.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  ra8_lpm_safe_boot_prcr_t : uint16_t {
  k_ra8_lpm_safe_boot_prcr_unlock = 0xA502U ,
  k_ra8_lpm_safe_boot_prcr_relock = 0xA500U
}
 PRCR keyed values used by ra8_lpm_safe_boot. More...
enum  ra8_lpm_safe_boot_addr_t : uintptr_t {
  k_ra8_lpm_safe_boot_prcr_addr = 0x4001E3FAUL ,
  k_ra8_lpm_safe_boot_sbycr_addr = 0x4001E00CUL ,
  k_ra8_lpm_safe_boot_lpscr_addr = 0x4001EA90UL ,
  k_ra8_lpm_safe_boot_dpsbycr_addr = 0x4001EA00UL
}
 Absolute addresses of the four SYSC LPM registers this restores. More...
enum  ra8_lpm_safe_boot_val_t : uint8_t {
  k_ra8_lpm_safe_boot_lpscr_sleep = 0x00U ,
  k_ra8_lpm_safe_boot_sbycr_reset = 0x40U ,
  k_ra8_lpm_safe_boot_dpsbycr_reset = 0x14U
}
 Cold-reset values for LPSCR / SBYCR / DPSBYCR. More...

Functions

static void ra8_lpm_safe_boot (void)
 Restore LPSCR / SBYCR / DPSBYCR to cold-reset values.

Detailed Description

Self-healing LPM register reset for very early boot.

Tag
[Ring 3 / HAL] {World: S}

SYSRESETREQ on the RA8D2 resets the Cortex-M85 core but NOT the SYSC LPM register block (LPSCR / SBYCR / DPSBYCR live in a separate reset domain). If a previous firmware wrote LPSCR.LPMD = 0x4 (software standby) and executed WFI, the standby configuration survives a debugger-issued SYSRESETREQ.

On the next boot, the very first WFI – including those inside J-Link's RAMCode helper – re-enters software standby, hanging the flash sequence. The board appears bricked until a true PORST (full power loss) clears LPSCR.

ra8_lpm_safe_boot() is the antidote: it unlocks PRCR.PRC1, restores LPSCR / SBYCR / DPSBYCR to their cold-reset values, then relocks PRCR. Calling it as the first instruction of Reset_Handler (before .data copy and before SystemInit) guarantees the chip is in a sane LPM state by the time any other code runs.

The helper is intentionally:

  • header-only (callable before .data is copied – no globals);
  • free of dependencies on other HAL headers;
  • inlined so a stale s_tag symbol or logging path cannot reach it from another translation unit.
Since
0.1.0

Definition in file ra8_lpm_safe_boot.h.

Enumeration Type Documentation

◆ ra8_lpm_safe_boot_addr_t

enum ra8_lpm_safe_boot_addr_t : uintptr_t

Absolute addresses of the four SYSC LPM registers this restores.

uintptr_t, per the project rule for address enums: on the 32-bit RA8D2 target it is uint32_t, while on the 64-bit unit-test host a uint32_t enum would truncate the cast and produce a wrong pointer. This header predates ra8_sysc_regs.h and is deliberately self-contained – it is included from the reset path, before any register-bank header is available.

Invariant
Each value is the absolute address of the register its name gives; the HUM chapters are cited on the accesses in ra8_lpm_safe_boot().
See also
ra8_lpm_safe_boot()
Since
0.1.0
Enumerator
k_ra8_lpm_safe_boot_prcr_addr 

SYSC.PRCR, 16-bit.

k_ra8_lpm_safe_boot_sbycr_addr 

SYSC.SBYCR, 8-bit.

k_ra8_lpm_safe_boot_lpscr_addr 

SYSC.LPSCR, 8-bit.

k_ra8_lpm_safe_boot_dpsbycr_addr 

SYSC.DPSBYCR, 8-bit.

Definition at line 76 of file ra8_lpm_safe_boot.h.

◆ ra8_lpm_safe_boot_prcr_t

enum ra8_lpm_safe_boot_prcr_t : uint16_t

PRCR keyed values used by ra8_lpm_safe_boot.

HUM Ch 11.2.18 p 456: PRCR key = 0xA5 in bits 15:8, PRC1 = bit 1 gates the LPM/SYSC register group.

Enumerator
k_ra8_lpm_safe_boot_prcr_unlock 

Key + PRC1 = 1.

k_ra8_lpm_safe_boot_prcr_relock 

Key only, PRC1 = 0.

Definition at line 55 of file ra8_lpm_safe_boot.h.

◆ ra8_lpm_safe_boot_val_t

enum ra8_lpm_safe_boot_val_t : uint8_t

Cold-reset values for LPSCR / SBYCR / DPSBYCR.

Per HUM Ch 11.2.18 / 11.2.20 / 11.2.21. Restoring these guarantees the next WFI is plain Sleep, not Software Standby.

Enumerator
k_ra8_lpm_safe_boot_lpscr_sleep 

LPMD = Sleep mode.

k_ra8_lpm_safe_boot_sbycr_reset 

OPE = 1, rest 0.

k_ra8_lpm_safe_boot_dpsbycr_reset 

DCSSMODE = 01b.

Definition at line 91 of file ra8_lpm_safe_boot.h.

Function Documentation

◆ ra8_lpm_safe_boot()

void ra8_lpm_safe_boot ( void )
inlinestatic

Restore LPSCR / SBYCR / DPSBYCR to cold-reset values.

HUM Ch 11.2.18 p 456 specifies the PRCR (Protect Register) write sequence for the SYSC LPM group: write 16-bit value 0xA502 (key 0xA5 in bits 15:8 plus PRC1 = 1 in bit 1) to unlock, do the protected writes, then write 0xA500 to relock.

Cold-reset values per HUM:

  • SBYCR = 0x40 (OPE = 1)
  • LPSCR = 0x00 (LPMD = 0 – Sleep mode, not standby)
  • DPSBYCR = 0x14 (DCSSMODE = 01b, all else 0)
Precondition
Callable from Reset_Handler before .data / .bss init.
Interrupts are masked (vendor reset state).
Postcondition
LPSCR = 0; next WFI enters plain Sleep, not Software Standby.
SBYCR / DPSBYCR restored to documented reset values.
Note
No-op on host (RA8_OFF_TARGET).
See also
HUM Ch 11.2.18 "SBYCR / PRCR" p 456.
HUM Ch 11.2.20 "LPSCR" p 457.
HUM Ch 11.2.21 "DPSBYCR" p 458.
Since
0.1.0

Definition at line 124 of file ra8_lpm_safe_boot.h.

References k_ra8_lpm_safe_boot_dpsbycr_addr, k_ra8_lpm_safe_boot_dpsbycr_reset, k_ra8_lpm_safe_boot_lpscr_addr, k_ra8_lpm_safe_boot_lpscr_sleep, k_ra8_lpm_safe_boot_prcr_addr, k_ra8_lpm_safe_boot_prcr_relock, k_ra8_lpm_safe_boot_prcr_unlock, k_ra8_lpm_safe_boot_sbycr_addr, and k_ra8_lpm_safe_boot_sbycr_reset.

Referenced by Reset_Handler().