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

Battery Backup Function (VBATT) driver – tamper detection. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_bkup.h"
#include "ra8_bkup_internal.h"
#include "ra8_bkup_regs.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
#include "ra8_register_protection.h"
Include dependency graph for ra8_bkup_tamper.c:

Go to the source code of this file.

Enumerations

enum  ra8_bkup_tamper_internal_t : uint16_t { k_ra8_bkup_max_nc_width = (uint16_t)k_ra8_bkup_nc_width_1hz }
 Local numeric constants – avoid magic numbers per CLAUDE.md. More...

Functions

static ra8_err_t internal_validate_chan (const ra8_bkup_tamper_chan_cfg_t *ch)
 Validate a per-channel tamper descriptor.
static uint8_t internal_chan_mask (uint8_t base_mask, ra8_bkup_channel_t channel)
 Convert channel + bit-base mask into the actual masked bit.
static ra8_err_t internal_validate_tamper_channels (const ra8_bkup_tamper_config_t *cfg)
 Validate every channel descriptor in a tamper config.
static uint8_t internal_compose_vbtictlr (const ra8_bkup_tamper_config_t *cfg)
 Compose the VBTICTLR (VCHnINEN) byte from per-channel flags.
static uint8_t internal_compose_vbtictlr2 (const ra8_bkup_tamper_config_t *cfg)
 Compose the VBTICTLR2 (VCHnNCE + VCHnEG) byte from per-channel flags.
static uint8_t internal_compose_vbtadcr1 (const ra8_bkup_tamper_config_t *cfg)
 Compose the VBTADCR1 (IRQ-enable + clear-backup) byte.
static uint8_t internal_compose_vbtadcr2 (const ra8_bkup_tamper_config_t *cfg)
 Compose the VBTADCR2 (capture-source) byte.
static uint8_t internal_compose_vbtadcr3 (const ra8_bkup_tamper_config_t *cfg)
 Compose the VBTADCR3 (HUK-zeroize) byte.
ra8_err_t ra8_bkup_tamper_init (const ra8_bkup_tamper_config_t *cfg)
 Apply per-channel tamper configuration in one shot.
ra8_err_t ra8_bkup_tamper_disable (void)
 Disable every tamper input and clear flags.
ra8_err_t ra8_bkup_read_input (ra8_bkup_channel_t channel, bool *high_out)
 Read the live RTCICn pin level via VBTIMONR.
ra8_err_t ra8_bkup_set_input_enable (ra8_bkup_channel_t channel, bool enable)
 Convenience wrapper that just sets / clears VCHnINEN.

Detailed Description

Battery Backup Function (VBATT) driver – tamper detection.

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

Tamper-detection half of the RA8D2 battery-backup driver: the RTCIC pad wiring, the per-channel tamper configuration composers, and the input monitor. Split out of ra8_bkup.c to stay under the per-file line cap; the core lifecycle, backup store and interrupt path stay there, and the TrustZone attribution registers live in ra8_bkup_security.c.

Everything here concerns the VBTICTLR / VBTICTLR2 / VBTIMONR / VBTADCR1-3 / VBTNCWCR register group. The channel-bit helper and the per-channel validator are private to this TU because no other part of the driver addresses tamper channels.

PRCR write protection (issue #131)
The whole tamper register file sits behind PRC1 (HUM Ch 13.1 Table 13.1 "Association between PRCR bits and use of registers to be protected" p 520-521). A write issued while PRC1 is locked is silently discarded – no bus fault, no status flag – so every write path here runs inside an RA8_PROTECTED_WRITE window. Reads are never protected. See the ra8_bkup.c file comment for the bench evidence behind that rule.

Definition in file ra8_bkup_tamper.c.

Enumeration Type Documentation

◆ ra8_bkup_tamper_internal_t

enum ra8_bkup_tamper_internal_t : uint16_t

Local numeric constants – avoid magic numbers per CLAUDE.md.

Enumerator
k_ra8_bkup_max_nc_width 

Highest legal VINCW encoding.

Definition at line 49 of file ra8_bkup_tamper.c.

Function Documentation

◆ internal_chan_mask()

uint8_t internal_chan_mask ( uint8_t base_mask,
ra8_bkup_channel_t channel )
inlinestatic

Convert channel + bit-base mask into the actual masked bit.

Most VBT* registers lay each channel's bit on the same bit position (VBTADF0 == bit 0 ... VBTADF2 == bit 2 ; VCH0EG == bit 4 ... VCH2EG == bit 6). Helper computes the per-channel mask from the channel-0 mask plus the channel index.

Parameters
[in]base_maskChannel-0 mask (e.g. 0x01 or 0x10).
[in]channelChannel index 0..2.
Returns
base_mask left-shifted by channel.
Precondition
channel < k_ra8_bkup_chan_count.
base_mask != 0.
Postcondition
Returned mask covers exactly one bit.
Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Side effects bounded to documented state.

Definition at line 115 of file ra8_bkup_tamper.c.

References RA8_INTERNAL.

Referenced by internal_compose_vbtadcr1(), internal_compose_vbtadcr2(), internal_compose_vbtadcr3(), internal_compose_vbtictlr(), internal_compose_vbtictlr2(), ra8_bkup_read_input(), and ra8_bkup_set_input_enable().

◆ internal_compose_vbtadcr1()

uint8_t internal_compose_vbtadcr1 ( const ra8_bkup_tamper_config_t * cfg)
static

Compose the VBTADCR1 (IRQ-enable + clear-backup) byte.

Parameters
[in]cfgTamper config holding irq_enable / clear_backup flags.
Returns
Composed VBTADCR1 value.
Precondition
cfg != nullptr.
cfg->channels has k_ra8_bkup_chan_count entries.
Postcondition
Returned mask only sets VBTADIE0/VBTADCE0 family bits.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Side effects bounded to documented state.

Definition at line 237 of file ra8_bkup_tamper.c.

References ra8_bkup_tamper_config_t::channels, ra8_bkup_tamper_chan_cfg_t::clear_backup, internal_chan_mask(), ra8_bkup_tamper_chan_cfg_t::irq_enable, k_ra8_bkup_chan_count, k_ra8_bkup_vbtadcr1_mask_vbtadce0, k_ra8_bkup_vbtadcr1_mask_vbtadie0, and RA8_INTERNAL.

Referenced by ra8_bkup_tamper_init().

◆ internal_compose_vbtadcr2()

uint8_t internal_compose_vbtadcr2 ( const ra8_bkup_tamper_config_t * cfg)
static

Compose the VBTADCR2 (capture-source) byte.

Parameters
[in]cfgTamper config holding capture_src.
Returns
Composed VBTADCR2 value.
Precondition
cfg != nullptr.
cfg->channels has k_ra8_bkup_chan_count entries.
Postcondition
Returned mask only sets VBRTCES0 family bits.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Side effects bounded to documented state.

Definition at line 273 of file ra8_bkup_tamper.c.

References ra8_bkup_tamper_chan_cfg_t::capture_src, ra8_bkup_tamper_config_t::channels, internal_chan_mask(), k_ra8_bkup_capture_src_vbtadf, k_ra8_bkup_chan_count, k_ra8_bkup_vbtadcr2_mask_vbrtces0, and RA8_INTERNAL.

Referenced by ra8_bkup_tamper_init().

◆ internal_compose_vbtadcr3()

uint8_t internal_compose_vbtadcr3 ( const ra8_bkup_tamper_config_t * cfg)
static

Compose the VBTADCR3 (HUK-zeroize) byte.

Parameters
[in]cfgTamper config holding zeroize_huk.
Returns
Composed VBTADCR3 value.
Precondition
cfg != nullptr.
cfg->channels has k_ra8_bkup_chan_count entries.
Postcondition
Returned mask only sets VBTADZE0 family bits.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Side effects bounded to documented state.

Definition at line 305 of file ra8_bkup_tamper.c.

References ra8_bkup_tamper_config_t::channels, internal_chan_mask(), k_ra8_bkup_chan_count, k_ra8_bkup_vbtadcr3_mask_vbtadze0, RA8_INTERNAL, and ra8_bkup_tamper_chan_cfg_t::zeroize_huk.

Referenced by ra8_bkup_tamper_init().

◆ internal_compose_vbtictlr()

uint8_t internal_compose_vbtictlr ( const ra8_bkup_tamper_config_t * cfg)
static

Compose the VBTICTLR (VCHnINEN) byte from per-channel flags.

Parameters
[in]cfgTamper config holding the per-channel input_enable flags.
Returns
Composed VBTICTLR value.
Precondition
cfg != nullptr.
cfg->channels has k_ra8_bkup_chan_count entries.
Postcondition
Returned mask only sets VCHnINEN bits.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Side effects bounded to documented state.

Definition at line 169 of file ra8_bkup_tamper.c.

References ra8_bkup_tamper_config_t::channels, ra8_bkup_tamper_chan_cfg_t::input_enable, internal_chan_mask(), k_ra8_bkup_chan_count, k_ra8_bkup_vbtictlr_mask_vch0inen, and RA8_INTERNAL.

Referenced by ra8_bkup_tamper_init().

◆ internal_compose_vbtictlr2()

uint8_t internal_compose_vbtictlr2 ( const ra8_bkup_tamper_config_t * cfg)
static

Compose the VBTICTLR2 (VCHnNCE + VCHnEG) byte from per-channel flags.

Parameters
[in]cfgTamper config holding noise-canceller and edge fields.
Returns
Composed VBTICTLR2 value.
Precondition
cfg != nullptr.
cfg->channels has k_ra8_bkup_chan_count entries.
Postcondition
Returned mask only sets VCHnNCE/VCHnEG bits.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Side effects bounded to documented state.

Definition at line 201 of file ra8_bkup_tamper.c.

References ra8_bkup_tamper_config_t::channels, ra8_bkup_tamper_chan_cfg_t::edge, internal_chan_mask(), k_ra8_bkup_chan_count, k_ra8_bkup_edge_rising, k_ra8_bkup_vbtictlr2_mask_vch0eg, k_ra8_bkup_vbtictlr2_mask_vch0nce, ra8_bkup_tamper_chan_cfg_t::noise_canceller_en, and RA8_INTERNAL.

Referenced by ra8_bkup_tamper_init().

◆ internal_validate_chan()

ra8_err_t internal_validate_chan ( const ra8_bkup_tamper_chan_cfg_t * ch)
static

Validate a per-channel tamper descriptor.

Parameters
[in]chChannel descriptor.
Returns
k_ra8_ok if edge and capture_src are valid.
Precondition
ch != nullptr.
ch->edge / ch->capture_src are enum values.
Postcondition
No side effects.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Side effects bounded to documented state.

Definition at line 78 of file ra8_bkup_tamper.c.

References ra8_bkup_tamper_chan_cfg_t::capture_src, ra8_bkup_tamper_chan_cfg_t::edge, k_ra8_bkup_capture_src_pin, k_ra8_bkup_capture_src_vbtadf, k_ra8_bkup_edge_falling, k_ra8_bkup_edge_rising, k_ra8_err_invalid_arg, k_ra8_ok, and RA8_INTERNAL.

Referenced by internal_validate_tamper_channels().

◆ internal_validate_tamper_channels()

ra8_err_t internal_validate_tamper_channels ( const ra8_bkup_tamper_config_t * cfg)
static

Validate every channel descriptor in a tamper config.

Parameters
[in]cfgCaller-supplied, null-checked tamper config.
Returns
k_ra8_ok if every channel passes internal_validate_chan.
Precondition
cfg != nullptr.
cfg->channels has k_ra8_bkup_chan_count entries.
Postcondition
No side effects.

See the matching header declaration for the full contract; this site adds no behaviour beyond what the public API documents.

Return values
k_ra8_okSuccess path.
k_ra8_err_invalid_argCaller violated a precondition.
Note
Thread safety: see the header declaration.
Since
0.1.0
Postcondition
Side effects bounded to documented state.

Definition at line 140 of file ra8_bkup_tamper.c.

References ra8_bkup_tamper_config_t::channels, g_bkup_tag, internal_validate_chan(), k_ra8_bkup_chan_count, k_ra8_ok, RA8_INTERNAL, and RA8_RETURN_ON_ERROR.

Referenced by ra8_bkup_tamper_init().

◆ ra8_bkup_read_input()

ra8_err_t ra8_bkup_read_input ( ra8_bkup_channel_t channel,
bool * high_out )
nodiscard

Read the live RTCICn pin level via VBTIMONR.

Parameters
[in]channelRTCICn channel index.
[out]high_outSet to true if the pin reads high.
Returns
ra8_err_t error code.
Return values
k_ra8_okLevel decoded.
k_ra8_err_null_ptrhigh_out == nullptr.
k_ra8_err_invalid_argchannel >= 3.
Precondition
Driver initialized; VCHnINEN must be 1 for the read to be meaningful (HUM Ch 12.2.10 p 506 – otherwise reads as 0).
Postcondition
*high_out matches the live VCHnMON bit.
Since
0.1.0

Definition at line 398 of file ra8_bkup_tamper.c.

References g_bkup_tag, internal_chan_mask(), k_ra8_bkup_chan_count, k_ra8_bkup_vbtimonr_mask_vch0mon, k_ra8_err_invalid_arg, k_ra8_ok, ra8_bkup_vbtimonr(), and RA8_CHECK_NULL_PTR.

◆ ra8_bkup_set_input_enable()

ra8_err_t ra8_bkup_set_input_enable ( ra8_bkup_channel_t channel,
bool enable )
nodiscard

Convenience wrapper that just sets / clears VCHnINEN.

Parameters
[in]channelRTCICn channel index.
[in]enabletrue -> drive pad as input.
Returns
ra8_err_t error code.
Return values
k_ra8_okVBTICTLR updated.
k_ra8_err_invalid_argchannel >= 3.
Precondition
PRCR unlocked.
Postcondition
Bit channel of VBTICTLR matches enable.
Since
0.1.0

Definition at line 410 of file ra8_bkup_tamper.c.

References internal_chan_mask(), k_ra8_bkup_chan_count, k_ra8_bkup_vbtictlr_mask_vch0inen, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_prcr_unlock_lpm, priv_ra8_bkup_internal_rmw8(), and ra8_bkup_vbtictlr().

◆ ra8_bkup_tamper_disable()

ra8_err_t ra8_bkup_tamper_disable ( void )
nodiscard

Disable every tamper input and clear flags.

Counterpart to ra8_bkup_tamper_init: zeroes VBTICTLR / VBTICTLR2 / VBTADCR1 / VBTADCR2 / VBTADCR3 and W0Cs VBTADSR. Used during deinit and during the noise-canceller reconfiguration dance the HUM mandates ("VCHnNCE, VBTADCR1/2/3 should be disabled before changing VINCW", HUM Ch 12.3.5 p 516).

Returns
ra8_err_t error code.
Return values
k_ra8_okHardware disarmed.
Precondition
PRCR unlocked, IRQs masked.
Postcondition
VBTICTLR / VBTICTLR2 / VBTADCR1 / VBTADCR2 / VBTADCR3 == 0.
VBTADSR.VBTADF[2:0] cleared.
Since
0.1.0

Definition at line 377 of file ra8_bkup_tamper.c.

References k_ra8_ok, k_ra8_prcr_unlock_lpm, ra8_bkup_vbtadcr1(), ra8_bkup_vbtadcr2(), ra8_bkup_vbtadcr3(), ra8_bkup_vbtadsr(), ra8_bkup_vbtictlr(), ra8_bkup_vbtictlr2(), and RA8_PROTECTED_WRITE.

◆ ra8_bkup_tamper_init()

ra8_err_t ra8_bkup_tamper_init ( const ra8_bkup_tamper_config_t * cfg)
nodiscard

Apply per-channel tamper configuration in one shot.

Implements HUM Ch 12.3.7.4 p 518 steps 1-8: programs VCHnINEN / VCHnNCE / VCHnEG, sets VINCW for the noise canceller, dummy-reads and clears VBTADFn flags after edge programming, then enables VBTADCR1 (IRQ + clear) / VBTADCR2 (capture source) / VBTADCR3 (HUK zeroize) per channel.

The HUM-documented 50us pin-stable wait and 5-RTC-clock noise canceller wait are the caller's responsibility – the HAL has no generic delay primitive.

Parameters
[in]cfgNon-NULL whole-block configuration.
Returns
ra8_err_t error code.
Return values
k_ra8_okHardware programmed.
k_ra8_err_null_ptrcfg == nullptr.
k_ra8_err_invalid_argcfg->nc_width out of range.
Precondition
PRCR unlocked, IRQs masked.
All cfg->channels[].edge are valid enum values.
Postcondition
VBTICTLR / VBTICTLR2 / VBTNCWCR / VBTADCR1..3 reflect cfg.
VBTADSR cleared after the dummy-read step.
See also
ra8_bkup_tamper_disable
Since
0.1.0

Definition at line 322 of file ra8_bkup_tamper.c.

References g_bkup_tag, internal_compose_vbtadcr1(), internal_compose_vbtadcr2(), internal_compose_vbtadcr3(), internal_compose_vbtictlr(), internal_compose_vbtictlr2(), internal_validate_tamper_channels(), k_ra8_bkup_max_nc_width, k_ra8_bkup_vbtncwcr_mask_vincw, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_prcr_unlock_lpm, ra8_bkup_tamper_config_t::nc_width, ra8_bkup_vbtadcr1(), ra8_bkup_vbtadcr2(), ra8_bkup_vbtadcr3(), ra8_bkup_vbtadsr(), ra8_bkup_vbtictlr(), ra8_bkup_vbtictlr2(), ra8_bkup_vbtncwcr(), RA8_CHECK_NULL_PTR, ra8_log_info, RA8_PROTECTED_WRITE, RA8_RETURN_ON_ERROR, and s_bkup_initialized.