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

Programmable Voltage Detection (PVD / LVD) HAL function prototypes. More...

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

Go to the source code of this file.

Functions

ra8_err_t ra8_lvd_channel_init (ra8_lvd_channel_t channel, const ra8_lvd_cfg_t *cfg)
 Configure one PVD channel from a full descriptor.
ra8_err_t ra8_lvd_channel_deinit (ra8_lvd_channel_t channel)
 Tear one channel back down to its reset state.
ra8_err_t ra8_lvd_set_threshold (ra8_lvd_channel_t channel, ra8_lvd_pvdlvl_t threshold)
 Change a channel's threshold without tearing the rest of its config.
ra8_err_t ra8_lvd_enable_irq (ra8_lvd_channel_t channel)
 Enable interrupt-on-cross for a monitor m channel.
ra8_err_t ra8_lvd_disable_irq (ra8_lvd_channel_t channel)
 Drop PVDmCR0.RIE for one channel.
ra8_err_t ra8_lvd_enable_reset (ra8_lvd_channel_t channel)
 Enable the reset path for a channel.
ra8_err_t ra8_lvd_disable_reset (ra8_lvd_channel_t channel)
 Drop the reset enable bit (RIE for m, RE for n).
ra8_err_t ra8_lvd_enable_cmpe (ra8_lvd_channel_t channel)
 Drive PVDmCR0.CMPE / PVDnCR0.CMPE high for a channel.
ra8_err_t ra8_lvd_disable_cmpe (ra8_lvd_channel_t channel)
 Drop PVDmCR0.CMPE / PVDnCR0.CMPE for a channel.
ra8_err_t ra8_lvd_set_filter (ra8_lvd_channel_t channel, ra8_lvd_loco_div_t filter_div, bool filter_en)
 Tune the digital filter (FSAMP[1:0] + DFDIS) on one channel.
ra8_err_t ra8_lvd_set_hysteresis_mode (ra8_lvd_channel_t channel, ra8_lvd_hysteresis_t hyst)
 Update PVDmFCR.RHSEL / PVDnFCR.RHSEL hysteresis-band selector.
ra8_err_t ra8_lvd_set_negate_mode (ra8_lvd_channel_t channel, ra8_lvd_negate_t negate)
 Update PVDmCR0.RN reset-negate timing on an m channel.
ra8_err_t ra8_lvd_set_irq_edge (ra8_lvd_channel_t channel, ra8_lvd_edge_t edge)
 Live update of PVDmCR1.IDTSEL[1:0] (edge select) for an m channel.
ra8_err_t ra8_lvd_set_irq_kind (ra8_lvd_channel_t channel, ra8_lvd_irq_type_t kind)
 Live update of PVDmCR1.IRQSEL (NMI vs maskable) on an m channel.
ra8_err_t ra8_lvd_set_security (uint32_t mask)
 Update PVDSAR.NONSEC0 / NONSEC1 to expose PVD1/PVD2 to non-secure.
ra8_err_t ra8_lvd_unlock_n_channels (void)
 Unlock PVD4/PVD5 control registers via PVDLR.
ra8_err_t ra8_lvd_relock_n_channels (void)
 Permanently re-lock PVD4/PVD5 by writing any value to PVDLR.
ra8_err_t ra8_lvd_get_status (ra8_lvd_channel_t channel, ra8_lvd_status_t *out)
 Read the DET and MON flags for one channel.
ra8_err_t ra8_lvd_clear_status (ra8_lvd_channel_t channel)
 Clear the latched DET flag on one channel (write-0-to-clear).
ra8_err_t ra8_lvd_enable_elc_event (ra8_lvd_channel_t channel)
 Enable the ELC event-out path for an m channel.
ra8_err_t ra8_lvd_disable_elc_event (ra8_lvd_channel_t channel)
 Disable the ELC event-out path for an m channel.
ra8_err_t ra8_lvd_configure_for_standby (ra8_lvd_channel_t channel)
 Configure a channel for Software / Deep Software Standby use.
ra8_err_t ra8_lvd_cancel_deep_standby_path (void)
 Clear PVDmCR0.RI on every m channel so Deep Software Standby modes 2 and 3 are reachable.
uint32_t ra8_lvd_filter_delay_us (ra8_lvd_loco_div_t div, uint32_t loco_hz)
 Compute the required "2s + 3 LOCO cycles" wait in microseconds.
ra8_err_t ra8_lvd_attach_handler (ra8_lvd_event_fn_t fn, void *ctx)
 Attach a single shared callback for every PVD channel.
ra8_err_t ra8_lvd_attach_channel_handler (ra8_lvd_channel_t channel, ra8_lvd_event_fn_t fn, void *ctx)
 Attach a per-channel callback (overrides the shared callback).
void ra8_lvd_dispatch (ra8_lvd_channel_t channel)
 Demux a PVD ISR – invoke the registered callback for channel.

Detailed Description

Programmable Voltage Detection (PVD / LVD) HAL function prototypes.

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

Public function prototypes for the RA8D2 PVD HAL driver: lifecycle, runtime reconfiguration, security attribution, n-channel register lock, status, ELC + standby helpers, the filter-timing helper, and the interrupt path. Split out of ra8_lvd.h so the public umbrella header stays under the per-file line budget; the umbrella ra8_lvd.h re-includes this header, so consumers are unaffected.

See ra8_lvd.h for the driver overview and HUM Ch 8 "Programmable Voltage Detection (PVD)", p 300-316 (R01UH1065EJ rev 1.30).

Since
0.1.0

Definition in file ra8_lvd_api.h.

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

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

If the per-channel callback is registered for a channel, ra8_lvd_dispatch fires it instead of the shared ra8_lvd_attach_handler callback. Pass fn = nullptr to clear the per-channel slot and fall back to the shared callback.

Parameters
[in]channelChannel id (m only).
[in]fnPer-channel callback or nullptr.
[in]ctxContext for the callback.
Returns
ra8_err_t error code.
Precondition
Single-threaded init context.
channel is one of {1, 2}.
Postcondition
The per-channel slot for channel reflects fn / ctx.
Shared callback is unchanged.
Note
Thread safety: not thread-safe.
Since
0.1.0

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

Attach a single shared callback for every PVD channel.

Parameters
[in]fnCallback fired by ra8_lvd_dispatch.
[in]ctxContext forwarded to the callback.
Returns
ra8_err_t error code.
Return values
k_ra8_okCallback registered (or cleared if fn == nullptr).
Precondition
Caller is in single-threaded init context.
fn may be nullptr (clears the callback).
Postcondition
Subsequent calls to ra8_lvd_dispatch use the new callback.
Old callback is no longer invoked.
Note
Thread safety: not thread-safe.
Since
0.1.0

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

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

HUM 8.2.4 p 305 "RI bit": "When the PVDmCR0.RI bit is 1 (voltage monitor m reset selected), a transition to Deep Software Standby mode 2 or 3 cannot be made". This convenience helper sweeps PVD1 and PVD2 in a single call so the LPM driver does not have to know the PVD register layout.

Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
Caller intends to enter Deep Software Standby 2 or 3.
Postcondition
PVD1CR0.RI = 0 and PVD2CR0.RI = 0.
All other CR0 fields preserved.
Note
Thread safety: not thread-safe.
Since
0.1.0

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_channel_deinit()

ra8_err_t ra8_lvd_channel_deinit ( ra8_lvd_channel_t channel)
nodiscard

Tear one channel back down to its reset state.

Runs the HUM Table 8.5 (m) or Table 8.7 (n) shutdown sequence:

  1. Clear PVDmCR0.CMPE.
  2. (Caller waits "2s + 3" LOCO cycles – see ra8_lvd_filter_delay_us.)
  3. Clear PVDmCR0.RIE / PVDnCR0.RE.
  4. Set PVDmCR0.DFDIS = 1 (filter off).
  5. Clear PVDmCMPCR.PVDE.
  6. Write 0 to PVDmSR.DET (m only) to clear any latched flag.
Parameters
[in]channelChannel id.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
channel is a valid id.
Postcondition
Channel's CMPCR / CR0 / CR1 / SR are zero.
Pending DET flag (if any) is cleared.
Note
Thread safety: not thread-safe.
Since
0.1.0

Tear one channel back down to its reset state.

Walks the documented disable sequence (CMPE -> RIE/RE -> DFDIS -> PVDE) so the comparator is in a known idle state.

Parameters
[in]channelPVD channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okChannel disabled.
k_ra8_err_invalid_argChannel mapping failed.
Precondition
PRCR.PRC3 unlocked (caller-managed).
Caller is in single-threaded shutdown context.
Postcondition
All channel control registers read as 0 (or reserved-only).
CMPCR is 0; the comparator is fully disarmed.
Note
Not thread-safe.
Since
0.1.0

Definition at line 624 of file ra8_lvd.c.

References ra8_lvd_channel_map_t::cmpcr, ra8_lvd_channel_map_t::cr0, ra8_lvd_channel_map_t::cr1, ra8_lvd_channel_map_t::fcr, g_lvd_map, ra8_lvd_channel_map_t::has_irq, internal_cr0_apply_reserved(), k_ra8_lvd_cr0_mask_cmpe, k_ra8_lvd_cr0_mask_dfdis, k_ra8_lvd_cr0_mask_re, k_ra8_lvd_cr0_mask_rie, 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_channel_init()

ra8_err_t ra8_lvd_channel_init ( ra8_lvd_channel_t channel,
const ra8_lvd_cfg_t * cfg )
nodiscard

Configure one PVD channel from a full descriptor.

Runs the HUM Table 8.4 (m channel) or Table 8.6 (n channel) setup sequence in full:

  1. Disable the detector (PVDmCMPCR.PVDE = 0).
  2. Program PVDLVL[4:0] in PVDmCMPCR.
  3. Program PVDmFCR.RHSEL (m or n).
  4. Re-enable PVDE (the caller is responsible for the t_d(E-A) stabilisation delay before step 8 – see ra8_lvd_filter_delay_us).
  5. Program FSAMP[1:0] in PVDmCR0 with DFDIS still 1.
  6. Drop DFDIS to 0 (filter on) only if cfg->filter_en is true.
  7. Program PVDmCR1 (edge + IRQ type) – m channels only.
  8. Set PVDmSR.DET = 0 (write-0-to-clear).
  9. Optionally set PVDmCR0.RIE / PVDnCR0.RE per cfg->irq_enable + cfg->response.

Set PVDmCR0.CMPE = 1 to gate the comparator output through.

Parameters
[in]channelChannel id (k_ra8_lvd_ch1, ch2, ch4, or ch5).
[in]cfgNon-NULL configuration descriptor.
Returns
ra8_err_t error code.
Return values
k_ra8_okChannel armed.
k_ra8_err_null_ptrcfg was nullptr.
k_ra8_err_invalid_argChannel out of range, threshold outside 0x03..0x0F, edge = 0b11, filter_div > 3, or RHSEL+RI conflict.
k_ra8_err_not_supportedResponse is interrupt/nmi on an n channel.
Precondition
IRQs masked or single-threaded init context.
PRCR.PRC3 has been unlocked by the caller.
Postcondition
On success, the chosen channel's PVDE and CMPE bits are set.
DET flag in PVDmSR is cleared (write-0-to-clear semantics).
State Machine
Note
Thread safety: not thread-safe.
See also
ra8_lvd_channel_deinit
Since
0.1.0

Configure one PVD channel from a full descriptor.

Validates cfg, then runs the comparator-then-CR0 sequence documented at HUM Ch 12.3.1 "Operating LVD" pp 600-602.

Parameters
[in]channelPVD channel id (PVD1 / PVD2 / PVD4 / PVD5).
[in]cfgNon-NULL configuration block.
Returns
ra8_err_t error code.
Return values
k_ra8_okChannel armed per cfg.
k_ra8_err_null_ptrcfg was NULL.
k_ra8_err_invalid_argChannel or config field out of range.
k_ra8_err_not_supportedResponse unavailable for the channel kind.
Precondition
cfg non-NULL.
PRCR.PRC3 unlocked (caller-managed).
Postcondition
On success, the channel comparator is armed and CMPE is set.
On error, no register has been written for the channel.
Note
Not thread-safe; pair with init-context IRQ masking.
Since
0.1.0

Definition at line 583 of file ra8_lvd.c.

References g_lvd_map, internal_lvd_program_cmpcr(), internal_lvd_program_cr0_chain(), internal_validate_cfg(), k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), RA8_CHECK_NULL_PTR, ra8_log_info_val, RA8_RETURN_ON_ERROR, and s_tag.

Referenced by internal_lvd_demo_configure().

◆ ra8_lvd_clear_status()

ra8_err_t ra8_lvd_clear_status ( ra8_lvd_channel_t channel)
nodiscard

Clear the latched DET flag on one channel (write-0-to-clear).

Per HUM 8.2.7 p 307 Note 1: only 0 can be written to DET. After the write, two PCLKB cycles are required before DET reads as 0 again. The driver does not spin – callers that need to re-arm RIE immediately should follow this call with the small busy-wait documented in the HUM (or equivalent ra8_time_delay_ns() helper once it lands).

Parameters
[in]channelChannel id (k_ra8_lvd_ch1 or ch2 only).
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
channel is one of {1, 2}.
Postcondition
PVDmSR.DET written to 0 (visible after 2 PCLKB cycles).
PVDmSR.MON is left untouched.
Note
Thread safety: not thread-safe.
Since
0.1.0

Clear the latched DET flag on one channel (write-0-to-clear).

Per HUM Ch 12.2.7 "PVDmSR" p 600 Note 1, only 0 can be written to DET; MON is preserved by clearing only the DET bit.

Parameters
[in]channelPVDm channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okDET acknowledged.
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.
SR.MON is unchanged.
Note
Not thread-safe (read-modify-write on SR).
Since
0.1.0

Definition at line 516 of file ra8_lvd_runtime.c.

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

◆ ra8_lvd_configure_for_standby()

ra8_err_t ra8_lvd_configure_for_standby ( ra8_lvd_channel_t channel)
nodiscard

Configure a channel for Software / Deep Software Standby use.

HUM 8.5(1) p 311 / HUM 8.5(2) p 312 require:

  • DFDIS = 1 (digital filter must be off in standby because LOCO stops in some standby modes).
  • For Deep Software Standby: RI = 0 (otherwise standby modes 2 / 3 become unreachable – HUM 8.2.4 p 305 RI bit note).

The routine performs both writes atomically (per channel) without altering CMPE or PVDE.

Parameters
[in]channelChannel id.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
channel is one of {1,2,4,5}.
Postcondition
DFDIS = 1 on the requested channel.
On m channels, RI = 0 and RN = 0.
Note
Thread safety: not thread-safe.
Since
0.1.0

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_cmpe()

ra8_err_t ra8_lvd_disable_cmpe ( ra8_lvd_channel_t channel)
nodiscard

Drop PVDmCR0.CMPE / PVDnCR0.CMPE for a channel.

Parameters
[in]channelChannel id.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
channel is one of {1,2,4,5}.
Postcondition
CMPE = 0; comparator output gated off.
DET / MON flags freeze at their last value (HUM 8.2.7 p 308).
Note
Thread safety: not thread-safe.
Since
0.1.0

Drop PVDmCR0.CMPE / PVDnCR0.CMPE for a channel.

Per HUM Ch 12.2.4 (p 597), used during shutdown or reconfiguration to silence the channel's response path without dropping PVDE.

Parameters
[in]channelPVD channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okCMPE cleared.
k_ra8_err_invalid_argChannel mapping failed.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CR0.CMPE reads as 0.
Reserved-bit invariant for the channel is preserved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 259 of file ra8_lvd_runtime.c.

References g_lvd_map, 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_disable_elc_event()

ra8_err_t ra8_lvd_disable_elc_event ( ra8_lvd_channel_t channel)
nodiscard

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

The HUM does not expose a dedicated bit. Per HUM 8.7 p 315 the cleanest way to gate the event off is to clear CMPE; the comparator output line goes "high" (driven inactive) and the ELC sees no edges.

Parameters
[in]channelChannel id (m only).
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
Channel is one of {1, 2}.
Postcondition
CMPE = 0; subsequent crossings will not assert the ELC event line.
Detector remains powered (PVDE / RIE preserved).
Note
Thread safety: not thread-safe.
Since
0.1.0

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_disable_irq()

ra8_err_t ra8_lvd_disable_irq ( ra8_lvd_channel_t channel)
nodiscard

Drop PVDmCR0.RIE for one channel.

Parameters
[in]channelChannel id (m only).
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
channel is one of {1, 2}.
Postcondition
PVDmCR0.RIE = 0; subsequent crossings won't fire IRQ/reset.
Comparator stays enabled – DET / MON still update.
Note
Thread safety: not thread-safe.
Since
0.1.0

Drop PVDmCR0.RIE for one channel.

Disables IRQ delivery via the standard CR0 RMW path so the reserved bit-3 stays set (HUM Ch 12.2.4 "PVDmCR0" p 597).

Parameters
[in]channelPVDm channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okIRQ disabled.
k_ra8_err_invalid_argChannel mapping failed.
k_ra8_err_not_supportedChannel has no IRQ path.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CR0.RIE reads as 0.
Reserved-bit invariant for the channel is preserved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 106 of file ra8_lvd_runtime.c.

References g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_err_not_supported, k_ra8_lvd_cr0_mask_rie, 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_reset()

ra8_err_t ra8_lvd_disable_reset ( ra8_lvd_channel_t channel)
nodiscard

Drop the reset enable bit (RIE for m, RE for n).

Parameters
[in]channelChannel id.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
channel is one of {1,2,4,5}.
Postcondition
RIE/RE bit is zero.
On m channels RI is left untouched – callers that need to reach Deep Software Standby 2/3 should also call ra8_lvd_cancel_deep_standby_path.
Note
Thread safety: not thread-safe.
Since
0.1.0

Drop the reset enable bit (RIE for m, RE for n).

For PVDm channels clears RI; for PVDn channels clears RE. See HUM Ch 12.2.4 / 12.2.5 (pp 597-598).

Parameters
[in]channelPVD channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okReset response disarmed.
k_ra8_err_invalid_argChannel mapping failed.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
Channel will not reset the SoC on subsequent crossings.
Reserved-bit invariant for the channel is preserved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 186 of file ra8_lvd_runtime.c.

References g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_lvd_cr0_mask_re, k_ra8_lvd_cr0_mask_rie, 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 – invoke the registered callback for channel.

Intended to be called from the secure-side ISR plumbing. Reads PVDmSR.DET; if no crossing is latched the call is a no-op (so a spurious IRQ does not invoke the callback). After the callback fires and returns, DET is cleared via the write-0-to-clear sequence.

Parameters
[in]channelChannel id that fired the IRQ / NMI.
Precondition
Called from PVD ISR or NMI context.
channel is a valid ra8_lvd_channel_t value.
Postcondition
If a callback is attached, it has been invoked exactly once.
PVDmSR.DET is 0 on return.
Note
Thread safety: ISR-context only. See HUM Ch 12 "Low Voltage Detection (LVD)" pp 593-624 for register semantics.
Since
0.1.0

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_cmpe()

ra8_err_t ra8_lvd_enable_cmpe ( ra8_lvd_channel_t channel)
nodiscard

Drive PVDmCR0.CMPE / PVDnCR0.CMPE high for a channel.

Per HUM 8.2.4 p 305 "CMPE bit", CMPE must be set after the detector has stabilised. This is the final step in Table 8.4 (step 13) and Table 8.6 (step 10). Splitting CMPE off as its own API lets a caller keep the detector and filter armed but throttle the downstream comparator output during MRAM erase / programme windows (HUM 8.2.4 p 305 RIE bit warning).

Parameters
[in]channelChannel id.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
Detector enabled (PVDE = 1) and stabilisation time elapsed.
Postcondition
PVDmCR0.CMPE / PVDnCR0.CMPE = 1.
DET / MON flags become valid two PCLKB cycles later.
Note
Thread safety: not thread-safe.
Since
0.1.0

Drive PVDmCR0.CMPE / PVDnCR0.CMPE high for a channel.

Per HUM Ch 12.2.4 (p 597) CMPE gates whether a detected crossing fans out to RIE/RE/RI; this helper toggles CMPE alone so the caller can stage the bring-up.

Parameters
[in]channelPVD channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okCMPE asserted.
k_ra8_err_invalid_argChannel mapping failed.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CR0.CMPE reads as 1.
Reserved-bit invariant for the channel is preserved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 226 of file ra8_lvd_runtime.c.

References g_lvd_map, 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_enable_elc_event()

ra8_err_t ra8_lvd_enable_elc_event ( ra8_lvd_channel_t channel)
nodiscard

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

Per HUM 8.7 p 315: the PVD has no dedicated ELC enable bit. The event signal is asserted whenever the comparator's output is enabled (PVDE = 1, CMPE = 1) AND the IRQ source fires (a Vdetm crossing per IDTSEL). This routine therefore re-asserts CMPE and ensures DET is cleared so the very first event after enabling does not get lost.

The corresponding ELC event-source select belongs in ra8_elc – the caller must call that path separately.

Parameters
[in]channelChannel id (m only – HUM 8.7 p 315 limits ELC to PVDm).
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
channel is one of {1, 2}.
Postcondition
CMPE = 1; DET = 0; the next crossing will assert the ELC event line.
No NVIC bits are touched (event path is independent of IRQ enable).
Note
Thread safety: not thread-safe.
Since
0.1.0

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_enable_irq()

ra8_err_t ra8_lvd_enable_irq ( ra8_lvd_channel_t channel)
nodiscard

Enable interrupt-on-cross for a monitor m channel.

Sets PVDmCR0.RIE = 1. The caller is responsible for the stabilisation delay t_d(E-A) before this call (see HUM 8.2.2 p 303 "PVDE bit (Voltage Detection m Enable)").

Parameters
[in]channelChannel id (only k_ra8_lvd_ch1 / ch2 are accepted; n channels do not have RIE).
Returns
ra8_err_t error code.
Return values
k_ra8_okInterrupt path armed.
k_ra8_err_invalid_argChannel id out of range.
k_ra8_err_not_supportedChannel does not have an IRQ path.
Precondition
PRCR.PRC3 unlocked.
Caller has waited t_d(E-A) since enabling the detector.
Postcondition
PVDmCR0.RIE = 1 for the requested channel.
Subsequent threshold crossings will fire the registered callback (after ra8_lvd_dispatch runs).
Note
Thread safety: not thread-safe.
Since
0.1.0

Enable interrupt-on-cross for a monitor m channel.

Enables IRQ delivery via the standard CR0 RMW path so the reserved bit-3 stays set (HUM Ch 12.2.4 "PVDmCR0" p 597).

Parameters
[in]channelPVDm channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okIRQ enabled.
k_ra8_err_invalid_argChannel mapping failed.
k_ra8_err_not_supportedChannel has no IRQ path.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CR0.RIE reads as 1.
Reserved-bit invariant for the channel is preserved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 68 of file ra8_lvd_runtime.c.

References g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_err_not_supported, k_ra8_lvd_cr0_mask_rie, 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_enable_reset()

ra8_err_t ra8_lvd_enable_reset ( ra8_lvd_channel_t channel)
nodiscard

Enable the reset path for a channel.

For m channels: sets RI = 1 (reset selected) and RIE = 1. For n channels: sets RE = 1 (the only response option n has).

Parameters
[in]channelChannel id.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
Channel detector previously stabilised (t_d(E-A) elapsed).
Postcondition
Reset path armed; a qualifying crossing will trigger reset.
Deep Software Standby mode 2/3 is no longer reachable on m channels (HUM 8.2.4 p 305 RI bit note).
Note
Thread safety: not thread-safe.
Since
0.1.0

Enable the reset path for a channel.

For PVDm channels sets RI + RIE; for PVDn channels sets RE (the only response option). See HUM Ch 12.2.4 / 12.2.5 (pp 597-598).

Parameters
[in]channelPVD channel id.
Returns
ra8_err_t error code.
Return values
k_ra8_okReset response armed.
k_ra8_err_invalid_argChannel mapping failed.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
Channel will reset the SoC on the configured crossing.
Reserved-bit invariant for the channel is preserved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 142 of file ra8_lvd_runtime.c.

References g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_lvd_cr0_mask_re, k_ra8_lvd_cr0_mask_ri, k_ra8_lvd_cr0_mask_rie, 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_filter_delay_us()

uint32_t ra8_lvd_filter_delay_us ( ra8_lvd_loco_div_t div,
uint32_t loco_hz )
nodiscard

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

Implements the HUM Table 8.4 step-8 / Table 8.6 step-8 wait formula:

us = (2 * 2^(div+1) + 3) * 1_000_000 / loco_hz + 1

Pass loco_hz = k_ra8_lvd_loco_hz_default for the nominal RA8D2 32.768 kHz LOCO. The +1 us round-up matches FSP r_lvd_filter_delay.

Parameters
[in]divFSAMP[1:0] encoding (0..3).
[in]loco_hzLOCO frequency (defaults expected – pass 0 to use k_ra8_lvd_loco_hz_default).
Returns
Required microseconds (>= 1).
Precondition
div is in 0..3 (out-of-range silently clamps to 3).
loco_hz is non-zero or 0 to take the default.
Postcondition
Return value is non-zero.
Function is pure – no hardware access.
Note
Thread safety: pure function, MT-safe.
Since
0.1.0

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_get_status()

ra8_err_t ra8_lvd_get_status ( ra8_lvd_channel_t channel,
ra8_lvd_status_t * out )
nodiscard

Read the DET and MON flags for one channel.

Parameters
[in]channelChannel id (k_ra8_lvd_ch1 or ch2 only).
[out]outDecoded status (non-NULL).
Returns
ra8_err_t error code.
Return values
k_ra8_okStatus returned in *out.
k_ra8_err_null_ptrout was nullptr.
k_ra8_err_invalid_argChannel id out of range.
k_ra8_err_not_supportedChannel has no status register.
Precondition
out is non-NULL.
channel is one of {1, 2}.
Postcondition
No hardware state is modified.
out->crossed reflects PVDmSR.DET; out->above reflects PVDmSR.MON.
Note
Thread safety: read-only, but caller should serialise with ra8_lvd_clear_status to avoid losing a crossing.
Since
0.1.0

Read the DET and MON flags for one channel.

Reads the status register documented at HUM Ch 12.2.7 "PVDmSR" p 600 and unpacks the latched-crossing (DET) and live-comparator (MON) bits.

Parameters
[in]channelPVDm channel id.
[out]outReceives the decoded status.
Returns
ra8_err_t error code.
Return values
k_ra8_okStatus decoded.
k_ra8_err_null_ptrout was NULL.
k_ra8_err_invalid_argChannel mapping failed.
k_ra8_err_not_supportedChannel has no IRQ path (PVDn).
Precondition
out non-NULL.
Channel previously brought up via ra8_lvd_channel_init.
Postcondition
*out reflects the live SR contents.
Hardware state is unchanged.
Note
Read-only; safe under simple races.
Since
0.1.0

Definition at line 474 of file ra8_lvd_runtime.c.

References ra8_lvd_status_t::above, ra8_lvd_status_t::crossed, g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_err_not_supported, k_ra8_lvd_sr_mask_det, k_ra8_lvd_sr_mask_mon, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), RA8_CHECK_NULL_PTR, ra8_lvd_reg8(), RA8_RETURN_ON_ERROR, s_tag, and ra8_lvd_channel_map_t::sr.

Referenced by internal_lvd_demo_sample().

◆ ra8_lvd_relock_n_channels()

ra8_err_t ra8_lvd_relock_n_channels ( void )
nodiscard

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

HUM 8.2.10 p 309 "After that, if you write an arbitrary value to the LOCK, the LOCK bit is fixed to 1." Use this once n-channel configuration is final. Calling unlock_n_channels again will not re-open the registers until the next qualifying reset.

Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
n-channel configuration is complete.
Postcondition
PVDLR.LOCK = 1; PVD4/PVD5 registers are write-protected.
No further unlock is possible until POR / RES / PVD0 reset.
Note
Thread safety: not thread-safe.
Since
0.1.0

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_filter()

ra8_err_t ra8_lvd_set_filter ( ra8_lvd_channel_t channel,
ra8_lvd_loco_div_t filter_div,
bool filter_en )
nodiscard

Tune the digital filter (FSAMP[1:0] + DFDIS) on one channel.

Per HUM 8.2.4 p 305 "FSAMP[1:0] bits" the divider can be rewritten only when DFDIS = 1. This routine enforces that:

  1. DFDIS <- 1 (filter off).
  2. (Caller responsible for "2 LOCO cycles" wait per HUM Note 2 p 313.)
  3. FSAMP[1:0] <- new divider.
  4. DFDIS <- enable (per filter_en).
Parameters
[in]channelChannel id.
[in]filter_divNew FSAMP[1:0] encoding (0..3).
[in]filter_entrue to leave the filter running, false to keep it disabled.
Returns
ra8_err_t error code.
Return values
k_ra8_okFilter reconfigured.
k_ra8_err_invalid_argChannel or filter_div out of range.
Precondition
PRCR.PRC3 unlocked.
LOCOCR.LCSTP = 0 if filter_en is true (HUM 8.2.4 p 305).
Postcondition
FSAMP[1:0] reflects filter_div.
DFDIS reflects !filter_en.
Note
Thread safety: not thread-safe.
Since
0.1.0

Tune the digital filter (FSAMP[1:0] + DFDIS) on one channel.

FSAMP can only be modified while DFDIS = 1 (HUM Ch 12.2.4 / 12.2.5 pp 597-598). This helper temporarily sets DFDIS, writes FSAMP, and drops DFDIS back when filter_en is true.

Parameters
[in]channelPVD channel id.
[in]filter_divNew FSAMP divider.
[in]filter_enTrue to enable the digital filter.
Returns
ra8_err_t error code.
Return values
k_ra8_okFilter updated.
k_ra8_err_invalid_argChannel or divider out of range.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CR0.FSAMP reflects filter_div.
CR0.DFDIS reflects the inverse of filter_en.
Note
Not thread-safe.
Since
0.1.0

Definition at line 301 of file ra8_lvd_runtime.c.

References g_lvd_map, k_ra8_lvd_cr0_mask_dfdis, k_ra8_lvd_cr0_mask_fsamp, k_ra8_lvd_cr0_shift_fsamp, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), priv_ra8_lvd_internal_cr0_rmw(), priv_ra8_lvd_internal_validate_div(), RA8_RETURN_ON_ERROR, and s_tag.

◆ ra8_lvd_set_hysteresis_mode()

ra8_err_t ra8_lvd_set_hysteresis_mode ( ra8_lvd_channel_t channel,
ra8_lvd_hysteresis_t hyst )
nodiscard

Update PVDmFCR.RHSEL / PVDnFCR.RHSEL hysteresis-band selector.

HUM 8.2.8 p 308 "RHSEL can be changed only if all the PVDmCMPCR.PVDE bits and all the PVDnCMPCR.PVDE bits are 0." The driver clears PVDE on the requested channel and restores it after the write; if other channels are concurrently running the caller must serialise.

Setting RHSEL = 1 (HVD) when PVDmCR0.RI = 0 is forbidden (HUM 8.2.8 p 308 last bullet); the driver returns k_ra8_err_invalid_state in that case.

Parameters
[in]channelChannel id.
[in]hystHysteresis side selector.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
hyst is one of {LVD, HVD}.
Postcondition
FCR.RHSEL reflects the requested value.
PVDE is restored to whatever value it had on entry.
Note
Thread safety: not thread-safe.
Since
0.1.0

Update PVDmFCR.RHSEL / PVDnFCR.RHSEL hysteresis-band selector.

Per HUM Ch 12.2.8 "PVDmFCR" p 600 RHSEL must not be set to 1 when PVDmCR0.RI = 0 on m channels. RHSEL can only be modified when every PVDE is 0; this helper preserves and restores the channel's own PVDE around the write.

Parameters
[in]channelPVD channel id.
[in]hystNew hysteresis mode.
Returns
ra8_err_t error code.
Return values
k_ra8_okHysteresis mode updated.
k_ra8_err_invalid_argChannel or mode out of range.
k_ra8_err_invalid_stateHVD requested with RI=0 (m channel only).
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
FCR.RHSEL reflects hyst.
CMPCR.PVDE state is preserved across the write.
Note
Not thread-safe.
Since
0.1.0

Definition at line 352 of file ra8_lvd_runtime.c.

References ra8_lvd_channel_map_t::cmpcr, ra8_lvd_channel_map_t::fcr, g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_lvd_cmpcr_mask_pvde, k_ra8_lvd_fcr_mask_rhsel, k_ra8_lvd_hysteresis_hvd, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), priv_ra8_lvd_internal_read_ri(), ra8_lvd_reg8(), RA8_RETURN_ON_ERROR, and s_tag.

◆ ra8_lvd_set_irq_edge()

ra8_err_t ra8_lvd_set_irq_edge ( ra8_lvd_channel_t channel,
ra8_lvd_edge_t edge )
nodiscard

Live update of PVDmCR1.IDTSEL[1:0] (edge select) for an m channel.

Parameters
[in]channelChannel id (m only).
[in]edgeNew edge encoding.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
edge != 0b11 (the prohibited setting per HUM 8.2.6 p 307).
Postcondition
PVDmCR1.IDTSEL reflects edge.
IRQSEL is preserved.
Note
Thread safety: not thread-safe.
Since
0.1.0

Live update of PVDmCR1.IDTSEL[1:0] (edge select) for an m channel.

Read-modify-writes CR1 (HUM Ch 12.2.6 "PVDmCR1" p 599) so the caller can change which crossing edge raises the IRQ without disturbing IRQSEL.

Parameters
[in]channelPVDm channel id (PVD1 / PVD2).
[in]edgeNew edge encoding.
Returns
ra8_err_t error code.
Return values
k_ra8_okEdge updated.
k_ra8_err_invalid_argChannel or edge out of range.
k_ra8_err_not_supportedChannel has no IRQ path (PVDn).
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CR1.IDTSEL reflects edge.
CR1.IRQSEL is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 736 of file ra8_lvd.c.

References ra8_lvd_channel_map_t::cr1, g_lvd_map, ra8_lvd_channel_map_t::has_irq, internal_validate_edge(), k_ra8_err_not_supported, k_ra8_lvd_cr1_mask_idtsel, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), ra8_lvd_reg8(), RA8_RETURN_ON_ERROR, and s_tag.

◆ ra8_lvd_set_irq_kind()

ra8_err_t ra8_lvd_set_irq_kind ( ra8_lvd_channel_t channel,
ra8_lvd_irq_type_t kind )
nodiscard

Live update of PVDmCR1.IRQSEL (NMI vs maskable) on an m channel.

Parameters
[in]channelChannel id (m only).
[in]kindMaskable or NMI.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
Channel is one of {1, 2}.
Postcondition
PVDmCR1.IRQSEL reflects kind.
IDTSEL preserved.
Note
Thread safety: not thread-safe.
Since
0.1.0

Live update of PVDmCR1.IRQSEL (NMI vs maskable) on an m channel.

Read-modify-writes CR1 (HUM Ch 12.2.6 "PVDmCR1" p 599) so the caller can switch the IRQ delivery vector at runtime.

Parameters
[in]channelPVDm channel id.
[in]kindMaskable IRQ or NMI.
Returns
ra8_err_t error code.
Return values
k_ra8_okKind updated.
k_ra8_err_invalid_argChannel mapping failed.
k_ra8_err_not_supportedChannel has no IRQ path.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CR1.IRQSEL reflects kind.
CR1.IDTSEL is unchanged.
Note
Not thread-safe.
Since
0.1.0

Definition at line 783 of file ra8_lvd.c.

References ra8_lvd_channel_map_t::cr1, g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_err_not_supported, k_ra8_lvd_cr1_mask_irqsel, k_ra8_lvd_irq_maskable, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), ra8_lvd_reg8(), RA8_RETURN_ON_ERROR, and s_tag.

◆ ra8_lvd_set_negate_mode()

ra8_err_t ra8_lvd_set_negate_mode ( ra8_lvd_channel_t channel,
ra8_lvd_negate_t negate )
nodiscard

Update PVDmCR0.RN reset-negate timing on an m channel.

HUM 8.2.4 p 305 "RN bit" describes four cases (RHSEL combined with RN). The driver only enforces the universal rule "RN = 1 is prohibited when RHSEL = 1" (HUM 8.2.4 p 306). The Software / Deep Software Standby compatibility constraint ("the only possible value for the RN bit is 0") is left to the caller.

Parameters
[in]channelChannel id (m only).
[in]negateNew RN value.
Returns
ra8_err_t error code.
Return values
k_ra8_okUpdated.
k_ra8_err_invalid_argChannel out of range.
k_ra8_err_not_supportedChannel is an n channel (no RN bit).
k_ra8_err_invalid_stateRN = 1 attempted while RHSEL = 1.
Precondition
PRCR.PRC3 unlocked.
Channel is one of {1, 2}.
Postcondition
PVDmCR0.RN reflects the requested value.
Other CR0 fields are unchanged.
Note
Thread safety: not thread-safe.
Since
0.1.0

Update PVDmCR0.RN reset-negate timing on an m channel.

Per HUM Ch 12.2.4 "PVDmCR0" p 597, RN=1 is rejected when RHSEL=1 (HVD mode). This helper enforces the constraint and writes RN.

Parameters
[in]channelPVDm channel id.
[in]negateNegation behaviour.
Returns
ra8_err_t error code.
Return values
k_ra8_okRN updated.
k_ra8_err_invalid_argChannel or mode out of range.
k_ra8_err_not_supportedChannel has no IRQ path (PVDn).
k_ra8_err_invalid_stateRN=1 conflicts with FCR.RHSEL=1.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CR0.RN reflects negate.
Reserved-bit invariant for the channel is preserved.
Note
Not thread-safe.
Since
0.1.0

Definition at line 411 of file ra8_lvd_runtime.c.

References ra8_lvd_channel_map_t::fcr, g_lvd_map, ra8_lvd_channel_map_t::has_irq, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_not_supported, k_ra8_lvd_cr0_mask_rn, k_ra8_lvd_fcr_mask_rhsel, k_ra8_lvd_negate_after_assert, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), priv_ra8_lvd_internal_cr0_rmw(), ra8_lvd_reg8(), RA8_RETURN_ON_ERROR, and s_tag.

◆ ra8_lvd_set_security()

ra8_err_t ra8_lvd_set_security ( uint32_t mask)
nodiscard

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

HUM 8.2.1 p 302. The PVDSAR register is a single 32-bit cell with two functional bits. Bits [31:2] are reserved (read-as-0 / write-0). PVD4 and PVD5 do not have a security-attribution bit and are always secure.

Parameters
[in]maskBit mask formed from k_ra8_lvd_pvdsar_mask_nonsec0 / k_ra8_lvd_pvdsar_mask_nonsec1. Pass 0 to make both channels secure-only.
Returns
ra8_err_t error code.
Return values
k_ra8_okAttribution updated.
k_ra8_err_invalid_argmask has any reserved bit set.
Precondition
PRCR.PRC3 unlocked.
Caller is currently in Secure world.
Postcondition
PVDSAR low two bits reflect mask; reserved bits stay 0.
Subsequent non-secure aliasing of PVDmCMPCR / PVDmCR0 / PVDmCR1 / PVDmSR succeeds for any channel whose NONSECx bit is now 1.
Note
Thread safety: not thread-safe.
Since
0.1.0

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_set_threshold()

ra8_err_t ra8_lvd_set_threshold ( ra8_lvd_channel_t channel,
ra8_lvd_pvdlvl_t threshold )
nodiscard

Change a channel's threshold without tearing the rest of its config.

Per HUM Ch 8.2.2 p 303 the PVDLVL field can only be changed while every PVDmCMPCR.PVDE and PVDnCMPCR.PVDE bit is 0. This driver temporarily clears the requested channel's own PVDE bit and writes the new threshold; if other channels are running concurrently the caller must serialise via ra8_lvd_channel_deinit first.

Parameters
[in]channelChannel id.
[in]thresholdNew PVDLVL encoding.
Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
threshold falls in 0x03..0x0F.
Postcondition
Channel's PVDLVL[4:0] reflects the new value.
Channel's PVDE bit is restored to whatever value it held on entry.
Note
Thread safety: not thread-safe.
Since
0.1.0

Change a channel's threshold without tearing the rest of its config.

Drops PVDE around the PVDLVL write so the comparator does not glitch (HUM Ch 12.2.2 "PVDmCMPCR" p 595), then restores PVDE.

Parameters
[in]channelPVD channel id.
[in]thresholdNew PVDLVL[4:0] encoding (0x03..0x0F).
Returns
ra8_err_t error code.
Return values
k_ra8_okThreshold updated.
k_ra8_err_invalid_argChannel or threshold out of range.
Precondition
Channel previously brought up via ra8_lvd_channel_init.
PRCR.PRC3 unlocked.
Postcondition
CMPCR.PVDLVL reflects threshold.
CMPCR.PVDE state is preserved across the write.
Note
Not thread-safe.
Since
0.1.0

Definition at line 688 of file ra8_lvd.c.

References ra8_lvd_channel_map_t::cmpcr, g_lvd_map, internal_validate_threshold(), k_ra8_lvd_cmpcr_mask_pvde, k_ra8_lvd_cmpcr_mask_pvdlvl, k_ra8_ok, priv_ra8_lvd_internal_channel_to_idx(), ra8_lvd_reg8(), RA8_RETURN_ON_ERROR, and s_tag.

◆ ra8_lvd_unlock_n_channels()

ra8_err_t ra8_lvd_unlock_n_channels ( void )
nodiscard

Unlock PVD4/PVD5 control registers via PVDLR.

HUM 8.2.10 p 309. The PVDLR.LOCK bit starts at 1 after every POR / RES-pin reset / PVD0 reset. While LOCK = 1, writes to PVD4CMPCR, PVD5CMPCR, PVD4CR0, PVD5CR0, PVD4FCR, PVD5FCR are silently dropped. Writing 0 once after a qualifying reset releases the lock; any subsequent write to PVDLR latches LOCK back to 1 forever (until the next qualifying reset).

Returns
ra8_err_t error code.
Precondition
PRCR.PRC3 unlocked.
This is the first PVDLR write since the last POR / RES / PVD0.
Postcondition
PVDLR.LOCK = 0; n-channel registers writable.
Re-locking is a one-shot: any subsequent relock is permanent.
Note
Thread safety: not thread-safe.
Since
0.1.0

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().