|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Cortex-M85 SysTick + DWT cycle-counter timebase primitive. More...
Go to the source code of this file.
Enumerations | |
| enum | ra8_systick_limit_t : uint32_t { k_ra8_systick_rvr_max = 0x00FFFFFFUL } |
| Architectural range limit of the Cortex-M SysTick reload register. More... | |
| enum | ra8_systick_clock_source_t : uint8_t { k_ra8_systick_clk_external = 0U , k_ra8_systick_clk_cpu = 1U } |
| Selects the SysTick counter clock (SYST_CSR.CLKSOURCE). More... | |
Functions | |
| ra8_err_t | ra8_systick_reload_for (uint32_t cpu_hz, uint32_t tick_hz, uint32_t *out_reload) |
| Compute the SysTick reload for a given core clock and tick rate. | |
| ra8_err_t | ra8_systick_configure (uint32_t reload, ra8_systick_clock_source_t src, bool tick_irq) |
| Arm and start SysTick with a reload value and clock source. | |
| ra8_err_t | ra8_systick_set_reload (uint32_t reload) |
| Re-arm SysTick with a new reload, leaving the control bits untouched. | |
| uint32_t | ra8_systick_current_value (void) |
| Read the live SysTick current-value register (SYST_CVR). | |
| void | ra8_dwt_cyccnt_enable (void) |
| Enable the DWT free-running cycle counter (DWT_CYCCNT). | |
| void | ra8_dwt_cyccnt_reset (void) |
| Zero the DWT cycle counter (DWT_CYCCNT). | |
| uint32_t | ra8_dwt_cyccnt_read (void) |
| Sample the DWT cycle counter (DWT_CYCCNT). | |
Cortex-M85 SysTick + DWT cycle-counter timebase primitive.
A single hardware primitive for the two architectural timekeeping blocks the RA8D2's Cortex-M85 exposes in its System Control Space (PPB window 0xE000Exxx), so no caller has to own a private address-cast accessor:
These are Arm v8-M architectural registers, NOT RA8D2 peripherals, so they carry references to the Arm v8-M Architecture Reference Manual (the "Arm v8-M ARM") rather than the RA8D2 Hardware User's Manual. On a host build (RA8_OFF_TARGET) the SCS window is backed by the fake MMIO map, so every access here is observable to unit tests and the reload / range logic is exercised exactly as on silicon.
Definition in file ra8_systick.h.
| enum ra8_systick_clock_source_t : uint8_t |
Selects the SysTick counter clock (SYST_CSR.CLKSOURCE).
Arm v8-M ARM: SYST_CSR.CLKSOURCE selects between the processor clock and an implementation-defined external reference clock. On the RA8D2 the processor clock is CPUCLK0, which is what every millisecond timebase in this tree derives its reload against.
| Enumerator | |
|---|---|
| k_ra8_systick_clk_external | CLKSOURCE = 0: external reference clock. |
| k_ra8_systick_clk_cpu | CLKSOURCE = 1: processor (CPU) clock. |
Definition at line 73 of file ra8_systick.h.
| enum ra8_systick_limit_t : uint32_t |
Architectural range limit of the Cortex-M SysTick reload register.
Arm v8-M ARM: SYST_RVR.RELOAD is a 24-bit field; the top byte reads as zero. A reload larger than this cannot be represented, so the configure / set-reload / reload-for entry points reject it rather than truncating (which would silently make the tick far too fast).
| Enumerator | |
|---|---|
| k_ra8_systick_rvr_max | Max SYST_RVR reload (24-bit). |
Definition at line 61 of file ra8_systick.h.
| void ra8_dwt_cyccnt_enable | ( | void | ) |
Enable the DWT free-running cycle counter (DWT_CYCCNT).
Sets DEMCR.TRCENA to unlock the DWT unit, then sets DWT_CTRL.CYCCNTENA to start DWT_CYCCNT counting every CPU cycle. Both are read-modify-write so any other trace/debug bits already set are preserved. The counter is PRIMASK-immune: it keeps advancing even while interrupts are globally masked, which is what makes it a usable delay reference in early boot and IRQ-off critical sections.
Definition at line 168 of file ra8_systick.c.
References internal_systick_reg(), k_ra8_dwt_ctrl, k_ra8_dwt_ctrl_cyccntena, k_ra8_dwt_demcr, and k_ra8_dwt_demcr_trcena.
Referenced by demo_setup_or_halt(), and ra8_time_init().
|
nodiscard |
Sample the DWT cycle counter (DWT_CYCCNT).
Reads the free-running 32-bit cycle counter. Wraps every 2^32 CPU cycles (~4.3 s at 1 GHz); compare two samples with unsigned subtraction so the elapsed count stays correct across a wrap.
| 0..UINT32_MAX | CPU cycles counted since the counter was last zeroed, modulo 2^32. |
Definition at line 183 of file ra8_systick.c.
References internal_systick_reg(), and k_ra8_dwt_cyccnt.
Referenced by cam_record_sync_sample(), cam_sync_state_init(), demo_emit_measurement(), and ra8_delay_ms().
| void ra8_dwt_cyccnt_reset | ( | void | ) |
Zero the DWT cycle counter (DWT_CYCCNT).
Writes zero to DWT_CYCCNT so a subsequent ra8_dwt_cyccnt_read measures cycles elapsed from this call. Does not enable or disable the counter; ra8_dwt_cyccnt_enable must already have started it for the reset to matter.
Definition at line 176 of file ra8_systick.c.
References internal_systick_reg(), and k_ra8_dwt_cyccnt.
Referenced by demo_emit_measurement().
|
nodiscard |
Arm and start SysTick with a reload value and clock source.
Performs the full bring-up sequence: disable the counter, program SYST_RVR with reload, clear SYST_CVR so counting restarts from the new reload, then write SYST_CSR to enable the counter with the requested clock source and, optionally, the tick interrupt. This is the exact sequence a millisecond timebase performs once at init.
| [in] | reload | SYST_RVR reload value; must be <= k_ra8_systick_rvr_max. |
| [in] | src | Counter clock source (ra8_systick_clock_source_t). |
| [in] | tick_irq | When true, enable SYST_CSR.TICKINT so the counter reaching zero raises the SysTick exception; when false, the counter free-runs and callers poll ra8_systick_current_value. |
| k_ra8_ok | SysTick armed and counting. |
| k_ra8_err_out_of_range | reload exceeds k_ra8_systick_rvr_max. |
reload was produced by ra8_systick_reload_for or is otherwise known to fit the 24-bit field. reload and the counter is enabled. Definition at line 122 of file ra8_systick.c.
References internal_systick_reg(), k_ra8_err_out_of_range, k_ra8_ok, k_ra8_systick_clk_cpu, k_ra8_systick_csr, k_ra8_systick_csr_clksource, k_ra8_systick_csr_enable, k_ra8_systick_csr_tickint, k_ra8_systick_cvr, k_ra8_systick_rvr, k_ra8_systick_rvr_max, ra8_log_error, and s_tag.
Referenced by demo_setup_or_halt(), and ra8_time_init().
|
nodiscard |
Read the live SysTick current-value register (SYST_CVR).
Returns the counter's current value, which counts down from SYST_RVR to zero and reloads. Reading it never clears it (only a write does), so this is a side-effect-free sample of the running counter.
| 0..k_ra8_systick_rvr_max | Current down-counter value. |
Definition at line 161 of file ra8_systick.c.
References internal_systick_reg(), and k_ra8_systick_cvr.
|
nodiscard |
Compute the SysTick reload for a given core clock and tick rate.
Derives the SYST_RVR reload value as cpu_hz / tick_hz - 1, the pure arithmetic every SysTick consumer needs. Validates that neither input is zero, that the clock is at least one tick period (cpu_hz >= tick_hz), and that the resulting reload fits the 24-bit SYST_RVR field. No register is touched, so this half is fully deterministic and host-testable on its own.
| [in] | cpu_hz | Core (SysTick) clock in Hz. |
| [in] | tick_hz | Desired tick rate in Hz (e.g. 1000 for a 1 ms tick). |
| [out] | out_reload | On success, receives the SYST_RVR reload value. |
| k_ra8_ok | Reload computed and written to out_reload. |
| k_ra8_err_null_ptr | out_reload is NULL. |
| k_ra8_err_invalid_arg | cpu_hz or tick_hz is zero, or cpu_hz is below one tick period. |
| k_ra8_err_out_of_range | The reload exceeds k_ra8_systick_rvr_max (cpu_hz far too high for tick_hz). |
out_reload is a valid, writable uint32_t. tick_hz is the rate the caller will actually program. out_reload is left unmodified.Definition at line 92 of file ra8_systick.c.
References k_ra8_err_invalid_arg, k_ra8_err_out_of_range, k_ra8_ok, k_ra8_systick_rvr_max, RA8_CHECK_NULL_PTR, ra8_log_error, and s_tag.
Referenced by demo_setup_or_halt().
|
nodiscard |
Re-arm SysTick with a new reload, leaving the control bits untouched.
Writes SYST_RVR with reload and clears SYST_CVR so the next count starts from the new reload. Unlike ra8_systick_configure this does NOT touch SYST_CSR, so the enable / clock-source / tick-interrupt bits already in force are preserved. This is the retune path: adjust the reload for a live clock change without a disable/enable glitch on the running tick.
| [in] | reload | New SYST_RVR reload value; <= k_ra8_systick_rvr_max. |
| k_ra8_ok | Reload re-armed; current value cleared. |
| k_ra8_err_out_of_range | reload exceeds k_ra8_systick_rvr_max. |
reload fits the 24-bit SYST_RVR field. reload and SYST_CVR reads zero. Definition at line 146 of file ra8_systick.c.
References internal_systick_reg(), k_ra8_err_out_of_range, k_ra8_ok, k_ra8_systick_cvr, k_ra8_systick_rvr, k_ra8_systick_rvr_max, ra8_log_error, and s_tag.
Referenced by ra8_threadx_systick_retune().