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

CAC (Clock Frequency Accuracy Measurement) edge-counter model. More...

#include <stdint.h>
#include <stdio.h>
#include "board_periph_block.h"
#include "emu_host_io_internal.h"
Include dependency graph for board_periph_cac.c:

Go to the source code of this file.

Data Structures

struct  cac_state_t
 CAC register state. More...

Enumerations

enum  cac_geom_t : uint64_t {
  k_cac_base = 0x40202400UL ,
  k_cac_span = 0x10UL ,
  k_cac_off_cacr0 = 0x00UL ,
  k_cac_off_caicr = 0x03UL ,
  k_cac_off_castr = 0x04UL ,
  k_cac_off_caulvr = 0x06UL ,
  k_cac_off_callvr = 0x08UL ,
  k_cac_off_cacntbr = 0x0AUL
}
 CAC block geometry (ra8_cac_regs.h, r_cac_regs_t). More...
enum  cac_field_t : uint8_t {
  k_cac_cacr0_cfme = 0x01U ,
  k_cac_castr_ferrf = 0x01U ,
  k_cac_castr_mendf = 0x02U ,
  k_cac_castr_ovff = 0x04U ,
  k_cac_caicr_ferrfcl = 0x10U ,
  k_cac_caicr_mendfcl = 0x20U ,
  k_cac_caicr_ovffcl = 0x40U
}
 CACR0 / CASTR / CAICR field masks (ra8_cac.c). More...
enum  cac_order_t : uint32_t { k_cac_block_order = 165U }
 Per-tick order slot for the CAC block (relative order only). More...

Functions

static RA8_INTERNAL void internal_cac_measure (void)
 Complete one measurement: latch an in-window count and set MENDF.
static RA8_INTERNAL void internal_cac_reset (void)
 Reset the CAC model to power-on state.
static RA8_INTERNAL uint64_t internal_cac_read (uc_engine *uc, uint64_t addr, unsigned size)
 MMIO read inside the CAC window.
static RA8_INTERNAL void internal_cac_write (uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
 MMIO write inside the CAC window.
static RA8_INTERNAL void internal_cac_report (void)
 End-of-run CAC section: measurements + last count and window.
static RA8_INTERNAL void internal_cac_block_register (void)
 Register the CAC block before main (host constructor).

Variables

static cac_state_t s_cac
static const board_periph_block_t s_k_cac_block
 CAC block descriptor (self-registered with the core).

Detailed Description

CAC (Clock Frequency Accuracy Measurement) edge-counter model.

Models the RA8D2 CAC (ra8_cac_regs.h, ra8_cac.c) at 0x40202400 so a frequency-accuracy measurement actually completes with an in-window edge count, instead of the status flag never asserting. Against the sparse fallback cac_accuracy_demo started a measurement (CACR0.CFME = 1) but CASTR.MENDF never set, so ra8_cac_measure timed out and the banner reported meas=TIMEOUT. This block latches MENDF on the start write and returns a count inside the programmed [CALLVR, CAULVR] window, so the measurement completes with FERRF / OVFF clear and the banner reports ok=Y.

The CAC counts edges of a measurement-target clock during one reference period and sets CASTR.FERRF when the count falls outside the upper / lower limit registers. The board emulator has no real clocks to count, so rather than invent an edge rate it reports the midpoint of the firmware's own programmed window: that is in-band by construction, so the genuine driver path (start -> poll MENDF -> read CACNTBR -> check FERRF) sees a healthy measurement exactly as a correctly-tuned crystal would on silicon.

Sequence modelled (HUM Ch 10.2):

  • CACR0 (+0x00) CFME bit starts a measurement. On a CFME=1 write the model loads CACNTBR with the [CALLVR, CAULVR] midpoint and sets CASTR.MENDF (FERRF / OVFF stay clear). A CFME=0 write stops it.
  • CASTR (+0x04) exposes MENDF / FERRF / OVFF; the driver's CAICR clear bits (FERRFCL / MENDFCL / OVFFCL, +4 in CAICR) clear the matching flags.
  • CAULVR (+0x06) / CALLVR (+0x08) are the window limits the driver programmes; CACNTBR (+0x0A) is the latched count it reads back.
Since
0.1.0

Definition in file board_periph_cac.c.

Enumeration Type Documentation

◆ cac_field_t

enum cac_field_t : uint8_t

CACR0 / CASTR / CAICR field masks (ra8_cac.c).

Enumerator
k_cac_cacr0_cfme 

CACR0.CFME measurement enable (bit 0).

k_cac_castr_ferrf 

CASTR.FERRF frequency-error (bit 0).

k_cac_castr_mendf 

CASTR.MENDF measurement-end (bit 1).

k_cac_castr_ovff 

CASTR.OVFF counter-overflow (bit 2).

k_cac_caicr_ferrfcl 

CAICR.FERRFCL clear FERRF (bit 4).

k_cac_caicr_mendfcl 

CAICR.MENDFCL clear MENDF (bit 5).

k_cac_caicr_ovffcl 

CAICR.OVFFCL clear OVFF (bit 6).

Definition at line 57 of file board_periph_cac.c.

◆ cac_geom_t

enum cac_geom_t : uint64_t

CAC block geometry (ra8_cac_regs.h, r_cac_regs_t).

Enumerator
k_cac_base 

CAC register base (HUM Ch 10.2).

k_cac_span 

Covers CACR0..CACNTBR.

k_cac_off_cacr0 

CACR0 control 0 (CFME).

k_cac_off_caicr 

CAICR interrupt / flag-clear.

k_cac_off_castr 

CASTR status (MENDF/FERRF/OVFF).

k_cac_off_caulvr 

CAULVR upper limit (16b).

k_cac_off_callvr 

CALLVR lower limit (16b).

k_cac_off_cacntbr 

CACNTBR counter buffer (16b).

Definition at line 45 of file board_periph_cac.c.

◆ cac_order_t

enum cac_order_t : uint32_t

Per-tick order slot for the CAC block (relative order only).

Enumerator
k_cac_block_order 

After the DRW block; report order.

Definition at line 68 of file board_periph_cac.c.

Function Documentation

◆ internal_cac_block_register()

RA8_INTERNAL void internal_cac_block_register ( void )
static

Register the CAC block before main (host constructor).

Definition at line 225 of file board_periph_cac.c.

References board_periph_register_block(), RA8_INTERNAL, and s_k_cac_block.

◆ internal_cac_measure()

RA8_INTERNAL void internal_cac_measure ( void )
static

Complete one measurement: latch an in-window count and set MENDF.

Complete one measurement: latch an in-window count and set mendf; this step is contained within the board periph cac model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for cac measure.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph cac model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 92 of file board_periph_cac.c.

References k_cac_castr_mendf, RA8_INTERNAL, and s_cac.

Referenced by internal_cac_write().

◆ internal_cac_read()

RA8_INTERNAL uint64_t internal_cac_read ( uc_engine * uc,
uint64_t addr,
unsigned size )
static

MMIO read inside the CAC window.

MMIO read inside the cac window; this step is contained within the board periph cac model and uses bounded caller or module-owned storage.

Parameters
[in,out]ucUnicorn engine whose emulated state is read or updated.
[in]addrGuest address involved in the operation.
[in]sizeSize of the requested region or access in bytes.
Returns
The cac read result produced by the board periph cac model.
Return values
valueThe operation-specific cac read value.
Precondition
Arguments satisfy the ranges documented for cac read.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph cac model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 127 of file board_periph_cac.c.

References k_cac_base, k_cac_off_cacntbr, k_cac_off_cacr0, k_cac_off_callvr, k_cac_off_castr, k_cac_off_caulvr, RA8_INTERNAL, and s_cac.

◆ internal_cac_report()

RA8_INTERNAL void internal_cac_report ( void )
static

End-of-run CAC section: measurements + last count and window.

End-of-run cac section: measurements + last count and window; this step is contained within the board periph cac model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for cac report.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph cac model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 199 of file board_periph_cac.c.

References priv_emu_io_errf(), RA8_INTERNAL, and s_cac.

◆ internal_cac_reset()

RA8_INTERNAL void internal_cac_reset ( void )
static

Reset the CAC model to power-on state.

Reset the cac model to power-on state; this step is contained within the board periph cac model and uses bounded caller or module-owned storage.

Precondition
Arguments satisfy the ranges documented for cac reset.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph cac model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 109 of file board_periph_cac.c.

References RA8_INTERNAL, and s_cac.

◆ internal_cac_write()

RA8_INTERNAL void internal_cac_write ( uc_engine * uc,
uint64_t addr,
unsigned size,
uint64_t value )
static

MMIO write inside the CAC window.

MMIO write inside the cac window; this step is contained within the board periph cac model and uses bounded caller or module-owned storage.

Parameters
[in,out]ucUnicorn engine whose emulated state is read or updated.
[in]addrGuest address involved in the operation.
[in]sizeSize of the requested region or access in bytes.
[in]valueRegister or payload value involved in the operation.
Precondition
Arguments satisfy the ranges documented for cac write.
The call executes on the emulator's single owning thread.
Postcondition
State changes remain confined to the board periph cac model and documented output objects.
Ownership of caller-supplied storage is unchanged.
Note
The operation is synchronous and does not transfer heap ownership.
Since
0.1.0

Definition at line 163 of file board_periph_cac.c.

References internal_cac_measure(), k_cac_base, k_cac_cacr0_cfme, k_cac_caicr_ferrfcl, k_cac_caicr_mendfcl, k_cac_caicr_ovffcl, k_cac_castr_ferrf, k_cac_castr_mendf, k_cac_castr_ovff, k_cac_off_cacr0, k_cac_off_caicr, k_cac_off_callvr, k_cac_off_caulvr, and s_cac.

Variable Documentation

◆ s_cac

◆ s_k_cac_block

const board_periph_block_t s_k_cac_block
static
Initial value:
= {
.base = (uint64_t)k_cac_base,
.span = (uint64_t)k_cac_span,
.order = (uint32_t)k_cac_block_order,
.tick = nullptr,
.name = "CAC",
}
static RA8_INTERNAL uint64_t internal_cac_read(uc_engine *uc, uint64_t addr, unsigned size)
MMIO read inside the CAC window.
static RA8_INTERNAL void internal_cac_report(void)
End-of-run CAC section: measurements + last count and window.
@ k_cac_block_order
After the DRW block; report order.
static RA8_INTERNAL void internal_cac_write(uc_engine *uc, uint64_t addr, unsigned size, uint64_t value)
MMIO write inside the CAC window.
static RA8_INTERNAL void internal_cac_reset(void)
Reset the CAC model to power-on state.
@ k_cac_span
Covers CACR0..CACNTBR.
@ k_cac_base
CAC register base (HUM Ch 10.2).
-proof

CAC block descriptor (self-registered with the core).

Definition at line 212 of file board_periph_cac.c.

Referenced by internal_cac_block_register().