|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Self-healing LPM register reset for very early boot. More...
#include <stdint.h>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. | |
Self-healing LPM register reset for very early boot.
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:
Definition in file ra8_lpm_safe_boot.h.
| 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.
Definition at line 76 of file ra8_lpm_safe_boot.h.
| 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.
| 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.
|
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:
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().