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

PVD / LVD security attribution, n-channel lock, ELC / standby helpers, filter-timing math, and callback registration / ISR demux. More...

#include <stdint.h>
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_lvd.h"
#include "ra8_lvd_internal.h"
#include "ra8_lvd_regs.h"
Include dependency graph for ra8_lvd_events.c:

Go to the source code of this file.

Functions

ra8_err_t ra8_lvd_set_security (uint32_t mask)
 Program PVDSAR security attribution for PVD channels.
ra8_err_t ra8_lvd_unlock_n_channels (void)
 Unlock PVDLR so PVDn channels accept further writes.
ra8_err_t ra8_lvd_relock_n_channels (void)
 Relock PVDLR after a PVDn maintenance window.
ra8_err_t ra8_lvd_enable_elc_event (ra8_lvd_channel_t channel)
 Arm the ELC event line for a PVDm channel.
ra8_err_t ra8_lvd_disable_elc_event (ra8_lvd_channel_t channel)
 Disarm the ELC event line for a PVDm channel.
ra8_err_t ra8_lvd_configure_for_standby (ra8_lvd_channel_t channel)
 Reconfigure a PVD channel for entry into Software / Deep Standby.
ra8_err_t ra8_lvd_cancel_deep_standby_path (void)
 Drop CR0.RI on every NMI-capable channel (deep-standby exit).
uint32_t ra8_lvd_filter_delay_us (ra8_lvd_loco_div_t div, uint32_t loco_hz)
 Compute the digital-filter settle delay in microseconds.
ra8_err_t ra8_lvd_attach_handler (ra8_lvd_event_fn_t fn, void *ctx)
 Register the shared LVD ISR callback (NULL detaches).
ra8_err_t ra8_lvd_attach_channel_handler (ra8_lvd_channel_t channel, ra8_lvd_event_fn_t fn, void *ctx)
 Register a per-channel LVD callback for a PVDm channel.
void ra8_lvd_dispatch (ra8_lvd_channel_t channel)
 Demux a PVD ISR – ack DET, fire per-channel + shared callbacks.

Variables

static const char * s_tag = "LVD"
 Logging tag used by every error path in this TU.
static ra8_lvd_event_fn_t s_lvd_fn
 Shared crossing callback (set via ra8_lvd_attach_handler).
static void * s_lvd_ctx
 Context passed to s_lvd_fn.
static ra8_lvd_event_fn_t s_lvd_chan_fn [k_ra8_lvd_map_idx_count]
 Per-channel override callbacks for PVD1 / PVD2.
static void * s_lvd_chan_ctx [k_ra8_lvd_map_idx_count]
 Per-channel callback contexts paired with s_lvd_chan_fn.

Detailed Description

PVD / LVD security attribution, n-channel lock, ELC / standby helpers, filter-timing math, and callback registration / ISR demux.

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

Companion translation unit to ra8_lvd.c. Owns the PVDSAR security attribution write, the PVDLR n-channel lock / unlock pair, the ELC event-line and standby reconfiguration helpers, the pure filter-settle delay computation, and the callback registration plus ISR demux path (which holds the per-driver callback state private to this TU). The shared channel-map descriptor table and the cross-TU register helpers it calls live in ra8_lvd_internal.h; every register access keeps its HUM Ch 8 citation (R01UH1065EJ rev 1.30).

Since
0.1.0

Definition in file ra8_lvd_events.c.

Function Documentation

◆ ra8_lvd_attach_channel_handler()

ra8_err_t ra8_lvd_attach_channel_handler ( ra8_lvd_channel_t channel,
ra8_lvd_event_fn_t fn,
void * ctx )
nodiscard

Register a per-channel LVD callback for a PVDm channel.

Attach a per-channel callback (overrides the shared callback).

Per-channel handlers take precedence over the shared callback set by ra8_lvd_attach_handler. Available only on PVDm channels.

Parameters
[in]channelPVDm channel id.
[in]fnCallback function or NULL to detach.
[in]ctxOpaque value forwarded verbatim to fn.
Returns
ra8_err_t error code.
Return values
k_ra8_okSlot updated.
k_ra8_err_invalid_argChannel mapping failed.
k_ra8_err_not_supportedChannel has no IRQ path (PVDn).
Precondition
IRQs masked or single-threaded init context.
Lifetime of ctx outlives the next ra8_lvd_dispatch call.
Postcondition
Per-channel slot for channel reflects (fn, ctx).
Shared callback slot is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 428 of file ra8_lvd_events.c.

References g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_err_not_supported, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), RA8_RETURN_ON_ERROR, s_lvd_chan_ctx, s_lvd_chan_fn, and s_tag.

◆ ra8_lvd_attach_handler()

ra8_err_t ra8_lvd_attach_handler ( ra8_lvd_event_fn_t fn,
void * ctx )
nodiscard

Register the shared LVD ISR callback (NULL detaches).

Attach a single shared callback for every PVD channel.

Stores (fn, ctx) in the shared slot consulted by every ra8_lvd_dispatch call when no per-channel handler is attached.

Parameters
[in]fnCallback function or NULL to detach.
[in]ctxOpaque value forwarded verbatim to fn.
Returns
ra8_err_t error code.
Return values
k_ra8_okSlot updated.
Precondition
IRQs masked or single-threaded init context.
Lifetime of ctx outlives the next ra8_lvd_dispatch call.
Postcondition
Shared callback slot reflects (fn, ctx).
Per-channel slots are unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 396 of file ra8_lvd_events.c.

References k_ra8_ok, s_lvd_ctx, and s_lvd_fn.

◆ ra8_lvd_cancel_deep_standby_path()

ra8_err_t ra8_lvd_cancel_deep_standby_path ( void )
nodiscard

Drop CR0.RI on every NMI-capable channel (deep-standby exit).

Clear PVDmCR0.RI on every m channel so Deep Software Standby modes 2 and 3 are reachable.

Per HUM Ch 12.2.4 (p 597), prepares the PVD subsystem for normal operation after exiting Deep Standby by clearing the per-channel RI bit (which is documented to be UD-only across DPSTBY).

Returns
ra8_err_t error code.
Return values
k_ra8_okPath cleared on every NMI channel.
Precondition
PRCR.PRC3 unlocked (caller-managed).
Caller has just exited Deep Software Standby.
Postcondition
CR0.RI reads as 0 on every NMI-capable channel.
Subsequent crossings will not auto-reset the SoC.
Note
Not thread-safe.
Since
0.1.0

Definition at line 319 of file ra8_lvd_events.c.

References g_lvd_map, k_ra8_lvd_cr0_mask_ri, k_ra8_lvd_nmi_channel_count, k_ra8_ok, and priv_ra8_lvd_internal_cr0_rmw().

◆ ra8_lvd_configure_for_standby()

ra8_err_t ra8_lvd_configure_for_standby ( ra8_lvd_channel_t channel)
nodiscard

Reconfigure a PVD channel for entry into Software / Deep Standby.

Configure a channel for Software / Deep Software Standby use.

Per HUM Ch 12.5 (p 602-603), the digital filter must be disabled and (for m channels) RI / RN cleared before entering standby.

Parameters
[in]channelPVD channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okChannel reconfigured for standby.
k_ra8_err_invalid_argChannel mapping failed.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
Caller is preparing the SoC for standby entry.
Postcondition
CR0.DFDIS reads as 1.
For m channels CR0.RI and CR0.RN read as 0.
Note
Not thread-safe.
Since
0.1.0

Definition at line 278 of file ra8_lvd_events.c.

References g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_lvd_cr0_mask_dfdis, k_ra8_lvd_cr0_mask_ri, k_ra8_lvd_cr0_mask_rn, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), priv_ra8_lvd_internal_cr0_rmw(), RA8_RETURN_ON_ERROR, and s_tag.

◆ ra8_lvd_disable_elc_event()

ra8_err_t ra8_lvd_disable_elc_event ( ra8_lvd_channel_t channel)
nodiscard

Disarm the ELC event line for a PVDm channel.

Disable the ELC event-out path for an m channel.

Per HUM Ch 12.7 p 606, clears CMPE so the ELC line goes inactive.

Parameters
[in]channelPVDm channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okELC line disarmed.
k_ra8_err_invalid_argChannel mapping failed.
k_ra8_err_not_supportedChannel has no IRQ path (PVDn).
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CR0.CMPE reads as 0.
ELC consumer no longer receives crossings as events.
Note
Not thread-safe.
Since
0.1.0

Definition at line 241 of file ra8_lvd_events.c.

References g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_err_not_supported, k_ra8_lvd_cr0_mask_cmpe, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), priv_ra8_lvd_internal_cr0_rmw(), RA8_RETURN_ON_ERROR, and s_tag.

◆ ra8_lvd_dispatch()

void ra8_lvd_dispatch ( ra8_lvd_channel_t channel)

Demux a PVD ISR – ack DET, fire per-channel + shared callbacks.

Demux a PVD ISR – invoke the registered callback for channel.

Snapshots PVDmSR.DET; if no crossing is latched the call is a no-op. Otherwise invokes the per-channel callback (if any), then the shared callback (if any), then clears DET via the W0C sequence (HUM Ch 12.2.7 "PVDmSR" p 600).

Parameters
[in]channelPVD channel id that fired the IRQ / NMI.
Precondition
Called from PVD ISR or NMI context.
PRCR.PRC3 unlocked (caller-managed during ack).
Postcondition
If a callback was attached, it has been invoked exactly once.
PVDmSR.DET is 0 on return.
Note
Thread safety: ISR-context only.
Since
0.1.0

Definition at line 463 of file ra8_lvd_events.c.

References g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_lvd_sr_mask_det, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), ra8_lvd_reg8(), s_lvd_chan_ctx, s_lvd_chan_fn, s_lvd_ctx, s_lvd_fn, and ra8_lvd_channel_map_t::sr.

◆ ra8_lvd_enable_elc_event()

ra8_err_t ra8_lvd_enable_elc_event ( ra8_lvd_channel_t channel)
nodiscard

Arm the ELC event line for a PVDm channel.

Enable the ELC event-out path for an m channel.

Per HUM Ch 12.7 "Event Link Controller (ELC) Output" p 606 the event line tracks CMPE; this helper acknowledges any latched DET before raising CMPE so the ELC consumer sees a clean transition.

Parameters
[in]channelPVDm channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okELC line armed.
k_ra8_err_invalid_argChannel mapping failed.
k_ra8_err_not_supportedChannel has no IRQ path (PVDn).
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
SR.DET reads as 0; CR0.CMPE reads as 1.
ELC consumer receives subsequent crossings as events.
Note
Not thread-safe.
Since
0.1.0

Definition at line 196 of file ra8_lvd_events.c.

References g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_err_not_supported, k_ra8_lvd_cr0_mask_cmpe, k_ra8_lvd_sr_mask_det, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), priv_ra8_lvd_internal_cr0_rmw(), ra8_lvd_reg8(), RA8_RETURN_ON_ERROR, s_tag, and ra8_lvd_channel_map_t::sr.

◆ ra8_lvd_filter_delay_us()

uint32_t ra8_lvd_filter_delay_us ( ra8_lvd_loco_div_t div,
uint32_t loco_hz )
nodiscard

Compute the digital-filter settle delay in microseconds.

Compute the required "2s + 3 LOCO cycles" wait in microseconds.

Implements the "2s + 3 cycles of the LOCO" formula from HUM Table 12.4 / 12.6 step 8 (s = 2^(div+1)). Matches FSP's r_lvd_filter_delay rounded-up microseconds.

Parameters
[in]divLOCO divider used by the channel.
[in]loco_hzLOCO frequency in Hz (0 -> default 32_768 Hz).
Returns
Settle delay in microseconds (rounded up by +1 us).
Return values
>=1Microseconds the caller must wait after FSAMP changes.
Precondition
None.
Caller will block / sleep at least the returned amount.
Postcondition
Hardware state is unchanged.
Return value is in microseconds.
Note
Pure function; safe from any context.
Since
0.1.0

Definition at line 355 of file ra8_lvd_events.c.

References k_ra8_lvd_filter_extra, k_ra8_lvd_filter_factor, k_ra8_lvd_loco_div_max, k_ra8_lvd_loco_hz_default, and k_ra8_lvd_us_per_sec.

◆ ra8_lvd_relock_n_channels()

ra8_err_t ra8_lvd_relock_n_channels ( void )
nodiscard

Relock PVDLR after a PVDn maintenance window.

Permanently re-lock PVD4/PVD5 by writing any value to PVDLR.

Writes any non-unlock pattern to PVDLR (HUM Ch 12.2.10 p 601 – "if you write an arbitrary value to the LOCK, the LOCK bit is fixed to 1.").

Returns
ra8_err_t error code.
Return values
k_ra8_okLock re-engaged.
Precondition
PRCR.PRC3 unlocked.
PVDn updates are complete and safe to freeze.
Postcondition
PVDLR.LOCK reads as 1.
Further PVDn writes are silently ignored.
Note
Not thread-safe.
Since
0.1.0

Definition at line 159 of file ra8_lvd_events.c.

References k_ra8_lvd_pvdlr_off, k_ra8_lvd_pvdlr_value_relock, k_ra8_ok, and ra8_lvd_reg8().

◆ ra8_lvd_set_security()

ra8_err_t ra8_lvd_set_security ( uint32_t mask)
nodiscard

Program PVDSAR security attribution for PVD channels.

Update PVDSAR.NONSEC0 / NONSEC1 to expose PVD1/PVD2 to non-secure.

Writes the security attribution mask (HUM Ch 12.2.1 "PVDSAR" p 594) so each PVD channel can be claimed by Secure or Non-secure.

Parameters
[in]maskBitwise-OR of k_ra8_lvd_pvdsar_* constants.
Returns
ra8_err_t error code.
Return values
k_ra8_okMask written.
k_ra8_err_invalid_argmask includes undefined bits.
Precondition
PRCR.PRC3 unlocked (caller-managed).
Caller is in Secure world (PVDSAR is S-only).
Postcondition
PVDSAR reflects mask.
Subsequent PVD register accesses honour the new attribution.
Note
Not thread-safe.
Since
0.1.0

Definition at line 103 of file ra8_lvd_events.c.

References k_ra8_err_invalid_arg, k_ra8_lvd_pvdsar_mask_all, k_ra8_lvd_pvdsar_off, k_ra8_ok, and ra8_lvd_reg32().

◆ ra8_lvd_unlock_n_channels()

ra8_err_t ra8_lvd_unlock_n_channels ( void )
nodiscard

Unlock PVDLR so PVDn channels accept further writes.

Unlock PVD4/PVD5 control registers via PVDLR.

Writes the documented unlock pattern to PVDLR (HUM Ch 12.2.10 "PVDLR" p 601) so subsequent ra8_lvd_* calls on PVDn channels are honoured.

Returns
ra8_err_t error code.
Return values
k_ra8_okLock released.
Precondition
PRCR.PRC3 unlocked (caller-managed).
Caller plans to update PVDn state next.
Postcondition
PVDLR.LOCK reads as 0.
PVDn channel writes are accepted.
Note
Not thread-safe.
Since
0.1.0

Definition at line 133 of file ra8_lvd_events.c.

References k_ra8_lvd_pvdlr_off, k_ra8_lvd_pvdlr_value_unlock, k_ra8_ok, and ra8_lvd_reg8().

Variable Documentation

◆ s_lvd_chan_ctx

void* s_lvd_chan_ctx[k_ra8_lvd_map_idx_count]
static

Per-channel callback contexts paired with s_lvd_chan_fn.

Definition at line 75 of file ra8_lvd_events.c.

Referenced by ra8_lvd_attach_channel_handler(), and ra8_lvd_dispatch().

◆ s_lvd_chan_fn

Per-channel override callbacks for PVD1 / PVD2.

Indexed by ra8_lvd_map_idx_t; only entries [0] and [1] are used (the n channels have no IRQ path). When non-null, takes precedence over s_lvd_fn in ra8_lvd_dispatch.

Definition at line 69 of file ra8_lvd_events.c.

Referenced by ra8_lvd_attach_channel_handler(), and ra8_lvd_dispatch().

◆ s_lvd_ctx

void* s_lvd_ctx
static

Context passed to s_lvd_fn.

Definition at line 58 of file ra8_lvd_events.c.

Referenced by ra8_lvd_attach_handler(), and ra8_lvd_dispatch().

◆ s_lvd_fn

ra8_lvd_event_fn_t s_lvd_fn
static

Shared crossing callback (set via ra8_lvd_attach_handler).

Definition at line 52 of file ra8_lvd_events.c.

Referenced by ra8_lvd_attach_handler(), and ra8_lvd_dispatch().

◆ s_tag

const char* s_tag = "LVD"
static

Logging tag used by every error path in this TU.

Private per-TU copy of the driver-wide "LVD" log tag.

Note
PRIVATE.
Warning
Do not modify at runtime.
Since
0.1.0

Definition at line 41 of file ra8_lvd_events.c.