|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Reset cause introspection + software-reset trigger. More...
#include "ra8_reset.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_hw_intrinsics.h"#include "ra8_log.h"#include "ra8_reset_regs.h"Go to the source code of this file.
Data Structures | |
| struct | ra8_reset_state_t |
| File-scope cached snapshot of reset cause + raw registers. More... | |
Enumerations | |
| enum | ra8_reset_clear_layout_t : uint32_t { k_ra8_reset_mask_rstsr0_msk = 0x000000FFUL , k_ra8_reset_mask_rstsr1_shift = 8U , k_ra8_reset_mask_rstsr1_window = 0x7FFFFF00UL , k_ra8_reset_mask_rstsr2_cwsf = 0x80000000UL } |
| Bit layout of the mask argument to ra8_reset_clear_cause. More... | |
Functions | |
| static void | internal_read_raw (ra8_reset_raw_t *out) |
| Read RSTSR0/1/2/3 into out. | |
| static ra8_reset_cause_t | internal_decode_rstsr0 (uint8_t rstsr0) |
| Decode the RSTSR0 byte. | |
| static ra8_reset_cause_t | internal_decode_rstsr1 (uint32_t rstsr1) |
| Decode the RSTSR1 word. | |
| static ra8_reset_cause_t | internal_decode_rstsr3 (uint8_t rstsr3) |
| Decode the RSTSR3 byte. | |
| static ra8_reset_cause_t | internal_decode (const ra8_reset_raw_t *raw) |
| Decode raw RSTSRn words into a single primary cause. | |
| ra8_err_t | ra8_reset_init (void) |
| Snapshot the reset cause at boot. | |
| void | ra8_reset_test_only_reset_state (void) |
| Reset the cached reset-cause snapshot for host tests. | |
| ra8_err_t | ra8_reset_get_cause (ra8_reset_cause_t *out) |
| Decode the latched RSTSRn flags into a single primary cause. | |
| ra8_err_t | ra8_reset_get_raw (ra8_reset_raw_t *out) |
| Read the raw RSTSR0 / RSTSR1 / RSTSR2 / RSTSR3 register words. | |
| ra8_err_t | ra8_reset_clear_cause (uint32_t mask) |
| Clear (write 0 to) the requested set of latched RSTSRn flags. | |
| ra8_err_t | ra8_reset_get_attribution (uint32_t *out) |
| Read the RSTSAR (Reset Security Attribution) register. | |
| void | ra8_reset_software_reset (void) |
| Trigger a software-initiated system reset. | |
| static bool | internal_source_loc (ra8_reset_source_t source, volatile uint8_t **reg, uint8_t *mask) |
| Resolve a reset source to its SYRSTMSKn register + bit mask. | |
| ra8_err_t | ra8_reset_set_source_mask (ra8_reset_source_t source, bool disable) |
| Enable or disable the occurrence of a specific reset source. | |
| ra8_err_t | ra8_reset_get_source_mask (ra8_reset_source_t source, bool *disabled) |
| Read whether a specific reset source is currently masked (disabled). | |
Variables | |
| static const char * | s_tag = "RESET" |
| Logging tag for the reset driver. | |
| static ra8_reset_state_t | s_state |
| File-scope snapshot. | |
Reset cause introspection + software-reset trigger.
Implementation of the public API declared in ra8_reset.h. Reads RSTSR0/1/2/3 to decode the latched reset cause, mirrors the bits out via ra8_reset_clear_cause, surfaces RSTSAR for security attribution, and triggers Cortex-M85 AIRCR.SYSRESETREQ for a software reset.
Every register access carries a HUM Ch 6 citation. The driver does not unlock PRCR – the RSTSRn registers are R/W with no PRCR gate (HUM Ch 6.2.2 p 257 "PRCR write enable" column is absent), and RSTSAR is read-only from this driver's perspective.
Definition in file ra8_reset.c.
| enum ra8_reset_clear_layout_t : uint32_t |
Bit layout of the mask argument to ra8_reset_clear_cause.
The clear mask packs three register selectors into one 32-bit word:
Definition at line 55 of file ra8_reset.c.
|
static |
Decode raw RSTSRn words into a single primary cause.
Priority order: RSTSR0 (POR, LVD, DPSRSTF) -> RSTSR3 (core voltage, overcurrent, temp) -> RSTSR1 (IWDT, WDT, SW, lockup, LM, BUS, CM, WDT1, CLU1, LM1, NW) -> RSTSR2 cold/warm. POR wins over LVD wins over watchdog, matching HUM Ch 6.1 Table 6.1 p 244 reset-source dominance (every higher-priority reset clears the lower-priority flag, so by the time firmware runs only the dominant cause is set).
| [in] | raw | Snapshot of RSTSR0 / RSTSR1 / RSTSR2 / RSTSR3. |
| k_ra8_reset_cause_unknown | No flag was set in any RSTSRn word. |
Definition at line 280 of file ra8_reset.c.
References internal_decode_rstsr0(), internal_decode_rstsr1(), internal_decode_rstsr3(), k_ra8_reset_cause_unknown, k_ra8_reset_cause_warm_start, k_ra8_reset_rstsr2_cwsf_msk, RA8_INTERNAL, ra8_reset_raw_t::rstsr0, ra8_reset_raw_t::rstsr1, ra8_reset_raw_t::rstsr2, and ra8_reset_raw_t::rstsr3.
Referenced by ra8_reset_clear_cause(), ra8_reset_get_cause(), and ra8_reset_init().
|
static |
Decode the RSTSR0 byte.
HUM Ch 6.2.2 "RSTSR0 : Reset Status Register 0" p 257. Returns the highest-priority active flag, or k_ra8_reset_cause_unknown if no RSTSR0 flag is set.
| [in] | rstsr0 | Raw RSTSR0 byte snapshot. |
| k_ra8_ok | Operation succeeded. |
Definition at line 135 of file ra8_reset.c.
References k_ra8_reset_cause_deep_sw_standby, k_ra8_reset_cause_lvd0, k_ra8_reset_cause_lvd1, k_ra8_reset_cause_lvd2, k_ra8_reset_cause_lvd4, k_ra8_reset_cause_lvd5, k_ra8_reset_cause_power_on, k_ra8_reset_cause_unknown, k_ra8_reset_rstsr0_dpsrstf_msk, k_ra8_reset_rstsr0_lvd0rf_msk, k_ra8_reset_rstsr0_lvd1rf_msk, k_ra8_reset_rstsr0_lvd2rf_msk, k_ra8_reset_rstsr0_lvd4rf_msk, k_ra8_reset_rstsr0_lvd5rf_msk, k_ra8_reset_rstsr0_porf_msk, and RA8_INTERNAL.
Referenced by internal_decode().
|
static |
Decode the RSTSR1 word.
HUM Ch 6.2.3 "RSTSR1 : Reset Status Register 1" p 258. Higher-priority causes appear first.
| [in] | rstsr1 | Raw RSTSR1 word snapshot. |
| k_ra8_ok | Operation succeeded. |
Definition at line 182 of file ra8_reset.c.
References k_ra8_reset_cause_bus_peripheral_mpu, k_ra8_reset_cause_common_memory, k_ra8_reset_cause_iwdt, k_ra8_reset_cause_local_memory0, k_ra8_reset_cause_local_memory1, k_ra8_reset_cause_lockup0, k_ra8_reset_cause_lockup1, k_ra8_reset_cause_network, k_ra8_reset_cause_software, k_ra8_reset_cause_unknown, k_ra8_reset_cause_wdt0, k_ra8_reset_cause_wdt1, k_ra8_reset_rstsr1_bussrf_msk, k_ra8_reset_rstsr1_clu1rf_msk, k_ra8_reset_rstsr1_clurf_msk, k_ra8_reset_rstsr1_cmrf_msk, k_ra8_reset_rstsr1_iwdtrf_msk, k_ra8_reset_rstsr1_lm0rf_msk, k_ra8_reset_rstsr1_lm1rf_msk, k_ra8_reset_rstsr1_nwrf_msk, k_ra8_reset_rstsr1_swrf_msk, k_ra8_reset_rstsr1_wdt1rf_msk, k_ra8_reset_rstsr1_wdtrf_msk, and RA8_INTERNAL.
Referenced by internal_decode().
|
static |
Decode the RSTSR3 byte.
HUM Ch 6.2.5 "RSTSR3 : Reset Status Register 3" p 261. Higher-priority causes appear first.
| [in] | rstsr3 | Raw RSTSR3 byte snapshot. |
| k_ra8_ok | Operation succeeded. |
Definition at line 241 of file ra8_reset.c.
References k_ra8_reset_cause_core_voltage, k_ra8_reset_cause_overcurrent, k_ra8_reset_cause_temperature, k_ra8_reset_cause_unknown, k_ra8_reset_rstsr3_cvmrf_msk, k_ra8_reset_rstsr3_ocprf_msk, k_ra8_reset_rstsr3_temprf_msk, and RA8_INTERNAL.
Referenced by internal_decode().
|
static |
Read RSTSR0/1/2/3 into out.
| [out] | out | Destination raw struct (caller-validated non-NULL). |
See implementation.
Definition at line 101 of file ra8_reset.c.
References RA8_INTERNAL, ra8_reset_rstsr0(), ra8_reset_rstsr1(), ra8_reset_rstsr2(), ra8_reset_rstsr3(), ra8_reset_raw_t::rstsr0, ra8_reset_raw_t::rstsr1, ra8_reset_raw_t::rstsr2, and ra8_reset_raw_t::rstsr3.
Referenced by ra8_reset_clear_cause(), ra8_reset_get_cause(), ra8_reset_get_raw(), and ra8_reset_init().
|
static |
Resolve a reset source to its SYRSTMSKn register + bit mask.
Maps each ra8_reset_source_t to the volatile pointer of the owning mask register (SYRSTMSK0/1/2) and the bit mask within it. The accessor calls compute addresses only – no register is dereferenced here, so no HUM citation is required until the caller reads/writes *reg.
| [in] | source | Reset source to resolve. |
| [out] | reg | Receives the owning SYRSTMSKn register pointer. |
| [out] | mask | Receives the bit mask within that register. |
source is valid and resolved; false otherwise. | true | source resolved; *reg and *mask are set. |
| false | source out of range; *reg / *mask untouched. |
reg and mask are non-NULL (caller-provided locals). source is a ra8_reset_source_t value. Definition at line 448 of file ra8_reset.c.
References k_ra8_reset_source_bus, k_ra8_reset_source_clu0, k_ra8_reset_source_clu1, k_ra8_reset_source_cm, k_ra8_reset_source_count, k_ra8_reset_source_iwdt, k_ra8_reset_source_lm0, k_ra8_reset_source_lm1, k_ra8_reset_source_pvd1, k_ra8_reset_source_pvd2, k_ra8_reset_source_sw, k_ra8_reset_source_wdt0, k_ra8_reset_source_wdt1, k_ra8_reset_syrstmsk0_bus_msk, k_ra8_reset_syrstmsk0_clu0_msk, k_ra8_reset_syrstmsk0_cm_msk, k_ra8_reset_syrstmsk0_iwdt_msk, k_ra8_reset_syrstmsk0_lm0_msk, k_ra8_reset_syrstmsk0_sw_msk, k_ra8_reset_syrstmsk0_wdt0_msk, k_ra8_reset_syrstmsk1_clu1_msk, k_ra8_reset_syrstmsk1_lm1_msk, k_ra8_reset_syrstmsk1_wdt1_msk, k_ra8_reset_syrstmsk2_pvd1_msk, k_ra8_reset_syrstmsk2_pvd2_msk, ra8_reset_syrstmsk0(), ra8_reset_syrstmsk1(), and ra8_reset_syrstmsk2().
Referenced by ra8_reset_get_source_mask(), and ra8_reset_set_source_mask().
|
nodiscard |
Clear (write 0 to) the requested set of latched RSTSRn flags.
Per HUM Ch 6.2.2 / 6.2.3 / 6.2.4 register descriptions, every RSTSRn flag uses the "read 1 then write 0" idiom: software clears a bit by writing 0 after observing it as 1. This function performs the write step for every bit selected by mask across all three RSTSR registers.
The mask argument is encoded as follows so a single call can clear flags from RSTSR0 (bits 0..7), RSTSR1 (bits 8..30) and RSTSR2/RSTSR3 (bits 31..) without forcing the caller to issue three separate calls:
RSTSR3 has no software-clear path – its flags are owned by the core-voltage / temperature monitor secure code; this function leaves RSTSR3 alone.
| [in] | mask | Encoded clear mask (see above). |
| k_ra8_ok | Mask applied. |
Definition at line 350 of file ra8_reset.c.
References internal_decode(), internal_read_raw(), k_ra8_ok, k_ra8_reset_mask_rstsr0_msk, k_ra8_reset_mask_rstsr1_shift, k_ra8_reset_mask_rstsr1_window, k_ra8_reset_mask_rstsr2_cwsf, k_ra8_reset_rstsr2_cwsf_msk, ra8_reset_rstsr0(), ra8_reset_rstsr1(), ra8_reset_rstsr2(), and s_state.
Referenced by main().
|
nodiscard |
Read the RSTSAR (Reset Security Attribution) register.
RSTSAR at SYSC offset 0x3C4 holds five NONSECn bits that select whether each of the five reset-status group registers (RSTSR0..RSTSR3 + future) is reachable from the non-secure side. The driver returns the raw 32-bit value; callers can mask against k_ra8_reset_rstsar_field_msk to drop reserved upper bits.
| [out] | out | Receives the RSTSAR value (non-NULL). |
| k_ra8_ok | Value written. |
| k_ra8_err_null_ptr | out was nullptr. |
Definition at line 386 of file ra8_reset.c.
References k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_reset_rstsar(), and s_tag.
|
nodiscard |
Decode the latched RSTSRn flags into a single primary cause.
If ra8_reset_init was called this returns the cached snapshot; otherwise it reads the registers fresh. The returned value is the highest-priority cause currently latched. Priority order matches HUM Ch 6.1 Table 6.1 p 244 (POR -> LVD -> Deep SW Standby -> core/temp/overcurrent -> IWDT/WDT/SW/Lockup/LM/BUS/CM -> Cold/Warm).
To examine every latched flag at once (multiple causes can stack between two reads), use ra8_reset_get_raw instead.
| [out] | out | Decoded cause (non-NULL). |
| k_ra8_ok | Cause written to *out. |
| k_ra8_err_null_ptr | out was nullptr. |
Definition at line 326 of file ra8_reset.c.
References internal_decode(), internal_read_raw(), k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.
Referenced by internal_wakeup_reason(), and main().
|
nodiscard |
Read the raw RSTSR0 / RSTSR1 / RSTSR2 / RSTSR3 register words.
If ra8_reset_init has run this returns the cached snapshot; otherwise the registers are read fresh.
| [out] | out | Destination struct (non-NULL). |
| k_ra8_ok | Raw values written. |
| k_ra8_err_null_ptr | out was nullptr. |
Definition at line 339 of file ra8_reset.c.
References internal_read_raw(), k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.
|
nodiscard |
Read whether a specific reset source is currently masked (disabled).
Reads the relevant SYRSTMSK0/1/2 byte and returns the mask state for source. Reads do not require a PRCR unlock.
| [in] | source | Reset source to query (< k_ra8_reset_source_count). |
| [out] | disabled | Receives true if the reset is masked/disabled. |
| k_ra8_ok | Result written to *disabled. |
| k_ra8_err_null_ptr | disabled was nullptr. |
| k_ra8_err_invalid_arg | source >= k_ra8_reset_source_count. |
source is a valid ra8_reset_source_t (< count). Definition at line 537 of file ra8_reset.c.
References internal_source_loc(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, and s_tag.
|
nodiscard |
Snapshot the reset cause at boot.
Reads RSTSR0/1/2/3 once and caches the decoded cause + raw words in a file-scope static. Subsequent calls to ra8_reset_get_cause / ra8_reset_get_raw return the snapshot rather than re-reading the registers. This is the only safe way to share the cause across the firmware – any other code path that calls ra8_reset_clear_cause would otherwise destroy the information before later modules could see it.
Idempotent: calling ra8_reset_init more than once re-reads the registers and overwrites the snapshot, which is what you want during unit tests but you should avoid in production code.
| k_ra8_ok | Snapshot captured. |
Definition at line 310 of file ra8_reset.c.
References internal_decode(), internal_read_raw(), k_ra8_ok, ra8_log_info_val, s_state, and s_tag.
Referenced by internal_wdt_demo_setup_or_halt(), main(), and wdt_rr_setup_or_halt().
|
nodiscard |
Enable or disable the occurrence of a specific reset source.
Sets (disable == true) or clears (disable == false) the mask bit for source in SYRSTMSK0/1/2. The register group is write-protected by PRCR.PRC5 (HUM Ch 6.2.6 Note p 262): this function unlocks PRC5, performs the read-modify-write of the relevant SYRSTMSKn byte, then relocks PRC5 – leaving the other PRC bits untouched.
| [in] | source | Reset source to mask/unmask (< k_ra8_reset_source_count). |
| [in] | disable | true disables the reset; false re-enables it. |
| k_ra8_ok | Mask bit updated. |
| k_ra8_err_invalid_arg | source >= k_ra8_reset_source_count. |
source is a valid ra8_reset_source_t (< count). source reads disable. Definition at line 505 of file ra8_reset.c.
References internal_source_loc(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_reset_prcr_key, k_ra8_reset_prcr_pr_bits_msk, k_ra8_reset_prcr_prc5_msk, ra8_log_error, ra8_reset_prcr(), and s_tag.
| void ra8_reset_software_reset | ( | void | ) |
Trigger a software-initiated system reset.
Writes the Cortex-M85 SCB->AIRCR register with the mandatory 0x05FA write-key in the upper half-word and the SYSRESETREQ bit set, exactly as CMSIS NVIC_SystemReset does. The reset does not return – on real hardware control is given to the reset exception handler within a few cycles. The function ends with a __DSB (or its off-target equivalent) so the AIRCR write is observable before the CPU stalls waiting for reset.
After the reset completes RSTSR1.SWRF will read 1 and ra8_reset_get_cause will return k_ra8_reset_cause_software.
Definition at line 394 of file ra8_reset.c.
References k_ra8_reset_aircr_sysresetreq_msk, k_ra8_reset_aircr_vectkey_pos, k_ra8_reset_aircr_vectkey_value, ra8_hw_wait_for_reset(), ra8_log_info, ra8_reset_aircr(), and s_tag.
Referenced by main().
| void ra8_reset_test_only_reset_state | ( | void | ) |
Reset the cached reset-cause snapshot for host tests.
Zeroes the cached boot-cause snapshot so each host test case starts from the driver's just-loaded state. Compiled unconditionally (like the other *_test_* helpers) but only ever called from tests/; on the target it is an unreferenced symbol dropped by --gc-sections.
Definition at line 319 of file ra8_reset.c.
References k_ra8_reset_cause_unknown, and s_state.
|
static |
|
static |
Logging tag for the reset driver.
Definition at line 39 of file ra8_reset.c.