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

Programmable Voltage Detection (PVD / LVD) driver implementation. More...

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

Go to the source code of this file.

Functions

bool priv_ra8_lvd_internal_reject_hvd_after (uint32_t hvd_val, uint32_t after_assert_val, uint32_t hysteresis, uint32_t negate)
 Pure RN+RHSEL reject predicate – see header for full contract.
bool priv_ra8_lvd_internal_set_ri_bit (uint32_t reset_val, uint32_t reset_on_rise_val, uint32_t response)
 Pure RI-bit predicate – see header for full contract.
ra8_err_t priv_ra8_lvd_internal_channel_to_idx (ra8_lvd_channel_t channel, uint8_t *out_idx)
 Implementation of priv_ra8_lvd_internal_channel_to_idx() – switch on PVD id.
static ra8_err_t internal_validate_threshold (ra8_lvd_pvdlvl_t threshold)
 Reject PVDLVL encodings outside the HUM-allowed range.
ra8_err_t priv_ra8_lvd_internal_validate_div (ra8_lvd_loco_div_t div)
 Implementation of priv_ra8_lvd_internal_validate_div() – upper-bound check.
static ra8_err_t internal_validate_edge (ra8_lvd_edge_t edge)
 Validate IDTSEL[1:0] candidate (0..2).
uint8_t priv_ra8_lvd_internal_read_ri (const ra8_lvd_channel_map_t *map)
 Implementation of priv_ra8_lvd_internal_read_ri() – masked CR0 read.
static uint8_t internal_n_cr0_with_reserved (uint8_t base)
 Build a PVDnCR0 byte with the chip-mandated bit-6 = 1 / bit-7 = 0 reserved values.
static uint8_t internal_m_cr0_with_reserved (uint8_t base)
 Build a PVDmCR0 byte with bit3 forced to 1 (HUM-mandated).
static uint8_t internal_cr0_apply_reserved (const ra8_lvd_channel_map_t *map, uint8_t base)
 Apply the chip-specific reserved-bit pattern to a CR0 value.
void priv_ra8_lvd_internal_cr0_rmw (const ra8_lvd_channel_map_t *map, uint8_t clear_mask, uint8_t set_bits)
 Implementation of priv_ra8_lvd_internal_cr0_rmw() – RMW with reserved-bit refold.
static ra8_err_t internal_validate_cfg (const ra8_lvd_channel_map_t *map, const ra8_lvd_cfg_t *cfg)
 Validate the cfg fields that the per-channel init reads.
static uint8_t internal_compose_cr0 (const ra8_lvd_channel_map_t *map, const ra8_lvd_cfg_t *cfg)
 Compute the initial CR0 value for ra8_lvd_channel_init.
static void internal_program_cr1 (const ra8_lvd_channel_map_t *map, const ra8_lvd_cfg_t *cfg)
 Program CR1 + status-clear for the m-only steps 9-11.
static void internal_lvd_program_cmpcr (const ra8_lvd_channel_map_t *map, const ra8_lvd_cfg_t *cfg)
 Run HUM Table 8.4 / 8.6 steps 1-4 (CMPCR programming).
static void internal_lvd_program_cr0_chain (const ra8_lvd_channel_map_t *map, const ra8_lvd_cfg_t *cfg)
 Run HUM Table 8.4 / 8.6 steps 6-13 (CR0 / CR1 / status).
ra8_err_t ra8_lvd_channel_init (ra8_lvd_channel_t channel, const ra8_lvd_cfg_t *cfg)
 Bring up one PVD channel per HUM Ch 12 Table 12.4 / 12.6.
ra8_err_t ra8_lvd_channel_deinit (ra8_lvd_channel_t channel)
 Tear down one PVD channel per HUM Ch 12 Table 12.5 / 12.7.
ra8_err_t ra8_lvd_set_threshold (ra8_lvd_channel_t channel, ra8_lvd_pvdlvl_t threshold)
 Update PVDLVL for an already-armed channel.
ra8_err_t ra8_lvd_set_irq_edge (ra8_lvd_channel_t channel, ra8_lvd_edge_t edge)
 Update CR1.IDTSEL for an IRQ-capable PVDm channel.
ra8_err_t ra8_lvd_set_irq_kind (ra8_lvd_channel_t channel, ra8_lvd_irq_type_t kind)
 Update CR1.IRQSEL (maskable IRQ vs NMI) for a PVDm channel.

Variables

static const char * s_tag = "LVD"
 Logging tag used by every error path in this TU.
const ra8_lvd_channel_map_t g_lvd_map [k_ra8_lvd_map_idx_count]
 Lookup table from ra8_lvd_map_idx_t to register offsets.

Detailed Description

Programmable Voltage Detection (PVD / LVD) driver implementation.

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

Round-3 driver implementing the full PVD surface defined in ra8_lvd.h. Every register access carries a HUM Ch 8 citation (R01UH1065EJ rev 1.30).

The PVD block has no module-stop bit – it is part of the always-on SYSC region – so this driver does not call ra8_mstp_enable. Per HUM 8.2.* register notes, every control-register write requires PRCR.PRC3 = 1; the driver does NOT take the lock itself (callers must wrap each call), but the host-side fake mmap has no lock so unit tests still see writes land.

Definition in file ra8_lvd.c.

Function Documentation

◆ internal_compose_cr0()

uint8_t internal_compose_cr0 ( const ra8_lvd_channel_map_t * map,
const ra8_lvd_cfg_t * cfg )
static

Compute the initial CR0 value for ra8_lvd_channel_init.

Encodes FSAMP, DFDIS, RN and RI per HUM Ch 12.2.4 / 12.2.5 (pp 597-598). DFDIS stays asserted; the caller drops it after the first CR0 write if cfg->filter_en is true.

Parameters
[in]mapChannel map (decides whether RN/RI exist).
[in]cfgCaller-supplied config.
Returns
Encoded CR0 byte (without the reserved-bit overlay applied).
Return values
0..0xFFBit-packed CR0 value with DFDIS already set.
Precondition
map and cfg are non-null and refer to the same channel.
Caller will fold the reserved-bit pattern in via internal_cr0_apply_reserved before commit.
Postcondition
No side effects.
DFDIS bit is set in the returned value.
Note
Internal helper, not thread-safe.
Since
0.1.0

Definition at line 422 of file ra8_lvd.c.

References ra8_lvd_cfg_t::filter_div, ra8_lvd_channel_map_t::has_irq, k_ra8_lvd_cr0_mask_dfdis, k_ra8_lvd_cr0_mask_fsamp, k_ra8_lvd_cr0_mask_ri, k_ra8_lvd_cr0_mask_rn, k_ra8_lvd_cr0_shift_fsamp, k_ra8_lvd_negate_after_assert, k_ra8_lvd_response_reset, k_ra8_lvd_response_reset_on_rise, ra8_lvd_cfg_t::negate, priv_ra8_lvd_internal_set_ri_bit(), RA8_INTERNAL, and ra8_lvd_cfg_t::response.

Referenced by internal_lvd_program_cr0_chain().

◆ internal_cr0_apply_reserved()

uint8_t internal_cr0_apply_reserved ( const ra8_lvd_channel_map_t * map,
uint8_t base )
static

Apply the chip-specific reserved-bit pattern to a CR0 value.

Dispatches between internal_m_cr0_with_reserved (PVDmCR0 with bit-3 = 1 reserved) and internal_n_cr0_with_reserved (PVDnCR0 with bit-6 = 1 reserved) per HUM Ch 12.2.4 / 12.2.5.

Parameters
[in]mapChannel map entry.
[in]basePre-reserved CR0 value.
Returns
base ORed with the channel's mandatory reserved bits.
Return values
base|reservedCombined value safe for direct CR0 write.
Precondition
None.
map reflects a valid channel descriptor.
Postcondition
Hardware state unchanged.
Caller can write the return value to PVDxCR0 without losing the reserved-bit invariant.
Note
Pure helper; safe from any context.
Since
0.1.0

Definition at line 315 of file ra8_lvd.c.

References ra8_lvd_channel_map_t::has_irq, internal_m_cr0_with_reserved(), internal_n_cr0_with_reserved(), and RA8_INTERNAL.

Referenced by internal_lvd_program_cmpcr(), internal_lvd_program_cr0_chain(), priv_ra8_lvd_internal_cr0_rmw(), and ra8_lvd_channel_deinit().

◆ internal_lvd_program_cmpcr()

void internal_lvd_program_cmpcr ( const ra8_lvd_channel_map_t * map,
const ra8_lvd_cfg_t * cfg )
static

Run HUM Table 8.4 / 8.6 steps 1-4 (CMPCR programming).

Disables the channel, writes PVDLVL with PVDE clear, programs RHSEL on FCR, and re-enables PVDE so the comparator can stabilise.

Parameters
[in]mapChannel map.
[in]cfgCaller-supplied config.
Precondition
Module clock ungated.
PRCR.PRC3 unlocked (caller-managed).
Postcondition
CMPCR/FCR reflect cfg; PVDE asserted.
Channel comparator is armed and stabilising.
Note
Internal helper, not thread-safe.
Since
0.1.0

Definition at line 493 of file ra8_lvd.c.

References ra8_lvd_channel_map_t::cmpcr, ra8_lvd_channel_map_t::cr0, ra8_lvd_channel_map_t::fcr, ra8_lvd_cfg_t::hysteresis, internal_cr0_apply_reserved(), k_ra8_lvd_cmpcr_mask_pvde, k_ra8_lvd_cmpcr_mask_pvdlvl, k_ra8_lvd_fcr_mask_rhsel, RA8_INTERNAL, ra8_lvd_reg8(), and ra8_lvd_cfg_t::threshold.

Referenced by ra8_lvd_channel_init().

◆ internal_lvd_program_cr0_chain()

void internal_lvd_program_cr0_chain ( const ra8_lvd_channel_map_t * map,
const ra8_lvd_cfg_t * cfg )
static

Run HUM Table 8.4 / 8.6 steps 6-13 (CR0 / CR1 / status).

Programs FSAMP/RN/RI then optionally drops DFDIS, CR1+DET on m-only, then RIE/RE and finally CMPE. Returns the final CR0 value for caller logging or further updates.

Parameters
[in]mapChannel map.
[in]cfgCaller-supplied config.
Precondition
ra8_lvd_channel_init already ran the CMPCR steps.
PRCR.PRC3 unlocked (caller-managed).
Postcondition
Channel is armed per cfg.
CMPE bit is set on the matching CR0 register.
Note
Internal helper, not thread-safe.
Since
0.1.0

Definition at line 531 of file ra8_lvd.c.

References ra8_lvd_channel_map_t::cr0, ra8_lvd_cfg_t::filter_en, ra8_lvd_channel_map_t::has_irq, internal_compose_cr0(), internal_cr0_apply_reserved(), internal_program_cr1(), ra8_lvd_cfg_t::irq_enable, k_ra8_lvd_cr0_mask_cmpe, k_ra8_lvd_cr0_mask_dfdis, k_ra8_lvd_cr0_mask_rie, k_ra8_lvd_response_none, RA8_INTERNAL, ra8_lvd_reg8(), and ra8_lvd_cfg_t::response.

Referenced by ra8_lvd_channel_init().

◆ internal_m_cr0_with_reserved()

uint8_t internal_m_cr0_with_reserved ( uint8_t base)
static

Build a PVDmCR0 byte with bit3 forced to 1 (HUM-mandated).

PVDmCR0 has a HUM-mandated bit-3 = 1 reserved value that must accompany every write (HUM Ch 12.2.4 "PVDmCR0" p 597). This helper folds the bit into a candidate base value before commit.

Parameters
[in]baseCR0 candidate without bit3 applied.
Returns
base | bit3 (HUM 12.2.4 p 597 "The write value should be 1.").
Return values
base|k_ra8_lvd_cr0_mask_bit3OR-folded reserved bit-3.
Precondition
None.
Caller will write the result back to PVDmCR0.
Postcondition
Hardware state unchanged.
Bit-3 of return is set; other bits stay as in base.
Note
Pure helper; safe from any context.
Since
0.1.0

Definition at line 287 of file ra8_lvd.c.

References k_ra8_lvd_cr0_mask_bit3, and RA8_INTERNAL.

Referenced by internal_cr0_apply_reserved().

◆ internal_n_cr0_with_reserved()

uint8_t internal_n_cr0_with_reserved ( uint8_t base)
static

Build a PVDnCR0 byte with the chip-mandated bit-6 = 1 / bit-7 = 0 reserved values.

PVDnCR0 has a reserved bit-6 = 1 / bit-7 = 0 pattern that must survive every write (HUM Ch 12.2.5 "PVDnCR0" p 598). This helper folds the pattern into a candidate base value before commit.

Parameters
[in]baseCR0 candidate without reserved bits applied.
Returns
base | bit6 (HUM 12.2.5 p 598 "This bit is read as 1. The write value should be 1.").
Return values
base|k_ra8_lvd_cr0_mask_n_bit6OR-folded reserved-bit pattern.
Precondition
None.
Caller will write the result back to PVDnCR0.
Postcondition
Hardware state unchanged.
Bit-6 of return is set; bit-7 stays as in base.
Note
Pure helper; safe from any context.
Since
0.1.0

Definition at line 261 of file ra8_lvd.c.

References k_ra8_lvd_cr0_mask_n_bit6, and RA8_INTERNAL.

Referenced by internal_cr0_apply_reserved().

◆ internal_program_cr1()

void internal_program_cr1 ( const ra8_lvd_channel_map_t * map,
const ra8_lvd_cfg_t * cfg )
static

Program CR1 + status-clear for the m-only steps 9-11.

HUM Table 8.4 steps 9-11 (only m channels have CR1 / SR). Writes the IDTSEL/IRQSEL pair and clears DET when the caller asked for it.

Parameters
[in]mapChannel map.
[in]cfgCaller-supplied config.
Precondition
map describes an m channel (caller checks map->has_irq).
PRCR.PRC3 unlocked (caller-managed).
Postcondition
CR1 reflects cfg, DET cleared if cfg->clear_status.
Reserved-bit invariant for the channel is preserved.
Note
Internal helper, not thread-safe.
Since
0.1.0

Definition at line 459 of file ra8_lvd.c.

References ra8_lvd_cfg_t::clear_status, ra8_lvd_channel_map_t::cr1, ra8_lvd_cfg_t::edge, ra8_lvd_cfg_t::irq_type, k_ra8_lvd_cr1_mask_idtsel, k_ra8_lvd_cr1_mask_irqsel, k_ra8_lvd_irq_maskable, RA8_INTERNAL, ra8_lvd_reg8(), and ra8_lvd_channel_map_t::sr.

Referenced by internal_lvd_program_cr0_chain().

◆ internal_validate_cfg()

ra8_err_t internal_validate_cfg ( const ra8_lvd_channel_map_t * map,
const ra8_lvd_cfg_t * cfg )
static

Validate the cfg fields that the per-channel init reads.

Sequentially calls the per-field validators (threshold, divider, edge for IRQ-capable channels) so a single error code surfaces without partial register writes. See HUM Ch 12 "Low Voltage Detection (LVD)" pp 593-624.

Parameters
[in]mapChannel map for the requested channel.
[in]cfgCaller-supplied configuration.
Returns
k_ra8_ok or one of the err codes.
Return values
k_ra8_okAll fields in spec.
k_ra8_err_invalid_argAt least one field outside the documented domain.
Precondition
cfg != nullptr.
map != nullptr.
Postcondition
Hardware state unchanged.
Return reflects the strictest validator that fired.
Note
Internal helper; not thread-safe.
Since
0.1.0

Definition at line 364 of file ra8_lvd.c.

References ra8_lvd_cfg_t::edge, ra8_lvd_cfg_t::filter_div, ra8_lvd_channel_map_t::has_irq, ra8_lvd_cfg_t::hysteresis, internal_validate_edge(), internal_validate_threshold(), k_ra8_err_invalid_arg, k_ra8_err_not_supported, k_ra8_lvd_hysteresis_hvd, k_ra8_lvd_negate_after_assert, k_ra8_lvd_response_interrupt, k_ra8_lvd_response_nmi, k_ra8_ok, ra8_lvd_cfg_t::negate, priv_ra8_lvd_internal_reject_hvd_after(), priv_ra8_lvd_internal_validate_div(), RA8_INTERNAL, ra8_lvd_cfg_t::response, and ra8_lvd_cfg_t::threshold.

Referenced by ra8_lvd_channel_init().

◆ internal_validate_edge()

ra8_err_t internal_validate_edge ( ra8_lvd_edge_t edge)
static

Validate IDTSEL[1:0] candidate (0..2).

0b11 is HUM-prohibited.

Edge selects which crossing direction triggers the IRQ (HUM Ch 12.2.6 "PVDmCR1" p 599). Only the rising / falling / both combinations are valid; 0b11 is reserved.

Parameters
[in]edgeEdge candidate.
Returns
k_ra8_ok or k_ra8_err_invalid_arg.
Return values
k_ra8_okEdge encoding valid.
k_ra8_err_invalid_argEdge encoding out of range or reserved.
Precondition
None.
edge originates from the public ra8_lvd_edge_t enum.
Postcondition
Hardware state unchanged.
Return value reflects the bounds check only.
Note
Pure helper; safe from any context.
Since
0.1.0

Definition at line 223 of file ra8_lvd.c.

References k_ra8_err_invalid_arg, k_ra8_lvd_edge_both, k_ra8_ok, and RA8_INTERNAL.

Referenced by internal_validate_cfg(), and ra8_lvd_set_irq_edge().

◆ internal_validate_threshold()

ra8_err_t internal_validate_threshold ( ra8_lvd_pvdlvl_t threshold)
static

Reject PVDLVL encodings outside the HUM-allowed range.

Per HUM Ch 12.2.4 "PVDmCR0" p 597 only PVDLVL values 0x03..0x0F are valid; lower values map to under-spec voltages and 0x10..0x1F are reserved.

Parameters
[in]thresholdPVDLVL[4:0] candidate.
Returns
k_ra8_ok if 0x03 <= threshold <= 0x0F, k_ra8_err_invalid_arg otherwise.
Return values
k_ra8_okThreshold within spec.
k_ra8_err_invalid_argThreshold below min or above max.
Precondition
threshold is any uint8_t.
Caller has already mapped the enum to the 5-bit register field.
Postcondition
Hardware state unchanged.
Return value reflects the bounds check only.
Note
Pure helper; safe from any context.
Since
0.1.0

Definition at line 182 of file ra8_lvd.c.

References k_ra8_err_invalid_arg, k_ra8_lvd_pvdlvl_max, k_ra8_lvd_pvdlvl_min, k_ra8_ok, and RA8_INTERNAL.

Referenced by internal_validate_cfg(), and ra8_lvd_set_threshold().

◆ priv_ra8_lvd_internal_channel_to_idx()

◆ priv_ra8_lvd_internal_cr0_rmw()

void priv_ra8_lvd_internal_cr0_rmw ( const ra8_lvd_channel_map_t * map,
uint8_t clear_mask,
uint8_t set_bits )

◆ priv_ra8_lvd_internal_read_ri()

uint8_t priv_ra8_lvd_internal_read_ri ( const ra8_lvd_channel_map_t * map)

Implementation of priv_ra8_lvd_internal_read_ri() – masked CR0 read.

Read PVDmCR0.RI for an m channel.

Definition at line 233 of file ra8_lvd.c.

References ra8_lvd_channel_map_t::cr0, k_ra8_lvd_cr0_mask_ri, and ra8_lvd_reg8().

Referenced by ra8_lvd_set_hysteresis_mode().

◆ priv_ra8_lvd_internal_reject_hvd_after()

bool priv_ra8_lvd_internal_reject_hvd_after ( uint32_t hvd_val,
uint32_t after_assert_val,
uint32_t hysteresis,
uint32_t negate )

Pure RN+RHSEL reject predicate – see header for full contract.

Pure predicate for "RN=1 prohibited when RHSEL=1" rejection.

Promoted helper so the line-494 AND can be driven under MC/DC.

Parameters
[in]hvd_valNumeric value of k_ra8_lvd_hysteresis_hvd.
[in]after_assert_valNumeric value of k_ra8_lvd_negate_after_assert.
[in]hysteresisCandidate hysteresis value.
[in]negateCandidate negate value.
Returns
Boolean reject predicate.
Return values
trueCaller returns k_ra8_err_invalid_arg.
falseCombination is allowed.
Precondition
None.
None.
Postcondition
No state mutated.
Return depends solely on inputs.
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 51 of file ra8_lvd.c.

Referenced by internal_validate_cfg().

◆ priv_ra8_lvd_internal_set_ri_bit()

bool priv_ra8_lvd_internal_set_ri_bit ( uint32_t reset_val,
uint32_t reset_on_rise_val,
uint32_t response )

Pure RI-bit predicate – see header for full contract.

Pure predicate for the CR0 "set RI bit" decision.

Promoted helper so the line-533 OR can be driven under MC/DC.

Parameters
[in]reset_valNumeric value of k_ra8_lvd_response_reset.
[in]reset_on_rise_valNumeric value of k_ra8_lvd_response_reset_on_rise.
[in]responseCandidate response value.
Returns
Boolean predicate.
Return values
trueCaller ORs RI bit into CR0.
falseRI bit stays clear.
Precondition
None.
None.
Postcondition
No state mutated.
Return depends solely on inputs.
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 75 of file ra8_lvd.c.

Referenced by internal_compose_cr0().

◆ priv_ra8_lvd_internal_validate_div()

ra8_err_t priv_ra8_lvd_internal_validate_div ( ra8_lvd_loco_div_t div)

Implementation of priv_ra8_lvd_internal_validate_div() – upper-bound check.

Validate FSAMP[1:0] candidate (0..3).

Definition at line 194 of file ra8_lvd.c.

References k_ra8_err_invalid_arg, k_ra8_lvd_loco_div_max, and k_ra8_ok.

Referenced by internal_validate_cfg(), and ra8_lvd_set_filter().

◆ ra8_lvd_channel_deinit()

ra8_err_t ra8_lvd_channel_deinit ( ra8_lvd_channel_t channel)
nodiscard

Tear down one PVD channel per HUM Ch 12 Table 12.5 / 12.7.

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

Bring up one PVD channel per HUM Ch 12 Table 12.4 / 12.6.

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

ra8_err_t ra8_lvd_set_irq_edge ( ra8_lvd_channel_t channel,
ra8_lvd_edge_t edge )
nodiscard

Update CR1.IDTSEL for an IRQ-capable PVDm channel.

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

Update CR1.IRQSEL (maskable IRQ vs NMI) for a PVDm channel.

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

ra8_err_t ra8_lvd_set_threshold ( ra8_lvd_channel_t channel,
ra8_lvd_pvdlvl_t threshold )
nodiscard

Update PVDLVL for an already-armed channel.

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.

Variable Documentation

◆ g_lvd_map

Initial value:
= {
.has_irq = true},
.has_irq = true},
.has_irq = false},
.has_irq = false},
}
@ k_ra8_lvd_pvd5_cmpcr_off
PVD5CMPCR.
@ k_ra8_lvd_pvd1_cr1_off
PVD1CR1.
@ k_ra8_lvd_pvd1_fcr_off
PVD1FCR.
@ k_ra8_lvd_pvd1_sr_off
PVD1SR.
@ k_ra8_lvd_pvd5_fcr_off
PVD5FCR.
@ k_ra8_lvd_pvd2_cr1_off
PVD2CR1.
@ k_ra8_lvd_pvd1_cr0_off
PVD1CR0.
@ k_ra8_lvd_pvd4_fcr_off
PVD4FCR.
@ k_ra8_lvd_pvd5_cr0_off
PVD5CR0.
@ k_ra8_lvd_pvd2_cmpcr_off
PVD2CMPCR.
@ k_ra8_lvd_pvd1_cmpcr_off
PVD1CMPCR.
@ k_ra8_lvd_pvd2_sr_off
PVD2SR.
@ k_ra8_lvd_pvd2_cr0_off
PVD2CR0.
@ k_ra8_lvd_pvd2_fcr_off
PVD2FCR.
@ k_ra8_lvd_pvd4_cmpcr_off
PVD4CMPCR.
@ k_ra8_lvd_pvd4_cr0_off
PVD4CR0.

Lookup table from ra8_lvd_map_idx_t to register offsets.

Single definition for the whole ra8_lvd driver. The descriptor type, its index enum, and the matching extern declaration live in ra8_lvd_internal.h so the runtime / events translation units can read the same table.

Note
PRIVATE to the ra8_lvd driver TUs.
Warning
Read-only; do not mutate.
Since
0.1.0

Defined once in ra8_lvd.c; declared here so the runtime / events translation units can read the same descriptor table.

Note
PRIVATE to the ra8_lvd driver TUs.
Warning
Read-only; do not mutate.
Since
0.1.0

Definition at line 108 of file ra8_lvd.c.

Referenced by ra8_lvd_attach_channel_handler(), ra8_lvd_cancel_deep_standby_path(), ra8_lvd_channel_deinit(), ra8_lvd_channel_init(), ra8_lvd_clear_status(), ra8_lvd_configure_for_standby(), ra8_lvd_disable_cmpe(), ra8_lvd_disable_elc_event(), ra8_lvd_disable_irq(), ra8_lvd_disable_reset(), ra8_lvd_dispatch(), ra8_lvd_enable_cmpe(), ra8_lvd_enable_elc_event(), ra8_lvd_enable_irq(), ra8_lvd_enable_reset(), ra8_lvd_get_status(), ra8_lvd_set_filter(), ra8_lvd_set_hysteresis_mode(), ra8_lvd_set_irq_edge(), ra8_lvd_set_irq_kind(), ra8_lvd_set_negate_mode(), and ra8_lvd_set_threshold().

◆ s_tag

const char* s_tag = "LVD"
static

Logging tag used by every error path in this TU.

Definition at line 87 of file ra8_lvd.c.