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

SysTick tick counter implementation. More...

#include "ra8_time.h"
#include <stdint.h>
#include "ra8_err.h"
#include "ra8_log.h"
#include "ra8_systick.h"
#include "ra8_time_constants.h"
Include dependency graph for ra8_time.c:

Go to the source code of this file.

Functions

void SysTick_Handler (void)
 Service one SysTick event for the core timebase.
ra8_err_t ra8_time_init (uint32_t cpu_hz)
 Implementation of ra8_time_init() – programme SysTick.
uint32_t ra8_time_ms (void)
 Implementation of ra8_time_ms() – read SysTick counter.
void ra8_delay_ms (uint32_t ms)
 Implementation of ra8_delay_ms() – busy-wait with wfi.
void ra8_time_on_tick (void)
 Implementation of ra8_time_on_tick() – SysTick IRQ tick.
void _tx_timer_interrupt (void)
void ux_dcd_ra8_usb_irq_reenable (void)
 Storm-guard recovery: zero the run counter and re-enable the USB IRQ.

Variables

static const char * s_tag = "TIME"
static volatile uint32_t s_tick_ms = 0U
static volatile uint32_t s_cycles_per_ms = 0U
 CPU cycles per millisecond, stamped by ra8_time_init.
volatile uint32_t g_ra8_threadx_systick_ready
 0 until _tx_initialize_low_level has armed ThreadX's SysTick + timer state; 1 afterwards.

Detailed Description

SysTick tick counter implementation.

A 1 kHz millisecond tick counter layered on the Cortex-M85 SysTick + DWT timebase primitive (::ra8_systick.h): ra8_time_init arms SysTick through ra8_systick_configure and the DWT cycle counter through ra8_dwt_cyccnt_enable, and ra8_delay_ms reads the PRIMASK-immune cycle counter through ra8_dwt_cyccnt_read. This translation unit owns only the tick counter, the SysTick IRQ body, and the delay policy; every raw SysTick / DWT register access now lives in the primitive (which is in ra8_core, so this Ring-1 consumer includes it without an upward layering dependency).

Definition in file ra8_time.c.

Function Documentation

◆ _tx_timer_interrupt()

void _tx_timer_interrupt ( void )
extern

References g_ra8_threadx_systick_ready.

Referenced by SysTick_Handler().

◆ ra8_delay_ms()

void ra8_delay_ms ( uint32_t ms)

Implementation of ra8_delay_ms() – busy-wait with wfi.

Non-Secure ra8_delay_ms – sleep ms ThreadX ticks.

Busy-wait for at least ms milliseconds.

Loops on s_tick_ms and issues wfi between checks.

Parameters
[in]msMilliseconds to wait. Zero returns immediately.
Precondition
ra8_time_init() has been called.
IRQs are NOT globally masked.
Postcondition
At least ms milliseconds have elapsed.
No internal state modified.
Note
Thread-safe.
Since
0.1.0

Definition at line 129 of file ra8_time.c.

◆ ra8_time_init()

ra8_err_t ra8_time_init ( uint32_t cpu_hz)
nodiscard

Implementation of ra8_time_init() – programme SysTick.

Initialise SysTick for a 1 kHz tick interrupt.

Computes the reload as cpu_hz / 1000 - 1, programmes SYST_RVR/CVR/CSR. On the off-target host the SCS writes are skipped.

Parameters
[in]cpu_hzCurrent CPU clock in Hz.
Returns
Error code.
Return values
k_ra8_okSysTick programmed; tick interrupt active.
k_ra8_err_invalid_argcpu_hz is zero or yields a zero reload.
Precondition
ra8_cgc_init() has run – CPU clock is stable.
Function is called from a single-threaded context.
Postcondition
On success, SysTick fires every 1 ms.
s_tick_ms is reset to zero.
Note
Not thread-safe; intended for one-shot init only.
Since
0.1.0

Definition at line 59 of file ra8_time.c.

References k_ra8_err_invalid_arg, k_ra8_ms_per_sec, k_ra8_ok, k_ra8_systick_clk_cpu, ra8_dwt_cyccnt_enable(), ra8_log_error, ra8_log_info_val, ra8_systick_configure(), s_cycles_per_ms, s_tag, and s_tick_ms.

Referenced by adc_diag_setup_or_halt(), al_setup_or_halt(), app_bringup_clocks(), blc_setup_or_halt(), bm_setup_or_halt(), bs_setup_or_halt(), c6_fwver_setup_or_halt(), c6_hosted_setup_or_halt(), c6_join_setup_or_halt(), c6_probe_clocks_or_halt(), c6_wifi_setup_or_halt(), cam_bringup(), cdc_setup_or_halt(), ch_setup_or_halt(), cm_bringup_clocks(), combo_clocks_or_halt(), crc_demo_setup_or_halt(), demo_setup_or_halt(), demo_setup_or_halt(), dfu_setup_or_halt(), drw_blend_setup_or_halt(), drw_demo_setup_or_halt(), dtc_arm_setup_or_halt(), dtc_demo_setup_or_halt(), ec_setup_or_halt(), ef_setup_or_halt(), ehb_setup_or_halt(), eoh_setup_or_halt(), eop_setup_or_halt(), ep_bringup_core(), ep_setup_or_halt(), erb_setup_or_halt(), es_setup_or_halt(), est_setup_or_halt(), etoc_setup_or_halt(), ez_bringup_clocks(), fileops_setup_or_halt(), flash_journal_setup_or_halt(), fs_fmt_setup_or_halt(), gh_setup_or_halt(), gpt_ecc_clocks_or_halt(), gptp_setup_or_halt(), hid_setup_or_halt(), i3c_demo_clocks_or_halt(), iic_setup_or_halt(), imp_setup_or_halt(), imu_demo_clocks_or_halt(), internal_acmphs_demo_setup(), internal_agt_periodic_setup_or_halt(), internal_audio_loopback_init_clocks_and_led(), internal_bkup_demo_setup_or_halt(), internal_c6_cam_setup_or_halt(), internal_can_demo_setup_or_halt(), internal_canfd_demo_setup_or_halt(), internal_canfd_filter_setup_or_halt(), internal_clocks_or_halt(), internal_clocks_or_halt(), internal_dac_b_demo_setup_or_halt(), internal_dac_demo_setup_or_halt(), internal_demo_clocks_or_halt(), internal_demo_setup_or_halt(), internal_dotf_demo_setup_or_halt(), internal_eth_loopback_setup_or_halt(), internal_gpio_demo_setup_or_halt(), internal_gpt_3p_demo_setup_or_halt(), internal_gpt_irq_demo_setup_or_halt(), internal_gpt_pwm_demo_setup_or_halt(), internal_icu_extint_demo_setup_or_halt(), internal_iic_peripheral_setup_or_halt(), internal_kat_setup_or_halt(), internal_kint_demo_setup_or_halt(), internal_lcd_bringup_clocks(), internal_lpm_deep_setup_or_halt(), internal_lpm_demo_setup_or_halt(), internal_lpm_dpsby1_setup_or_halt(), internal_lpm_dpsby2_setup_or_halt(), internal_lpm_dpsby3_setup_or_halt(), internal_lpm_swstd_setup_or_halt(), internal_lpm_wake_setup_or_halt(), internal_lus_setup_or_halt(), internal_lvd_demo_setup_or_halt(), internal_mecc_setup_or_halt(), internal_motor_3phase_init_clocks_and_led(), internal_mpu_simple_setup_or_halt(), internal_pc_setup_or_halt(), internal_pdg_demo_setup_or_halt(), internal_poeg_demo_setup_or_halt(), internal_rc_setup_or_halt(), internal_rcs_setup_or_halt(), internal_rng_demo_setup_or_halt(), internal_rtc_demo_setup_or_halt(), internal_sd_demo_setup_or_halt(), internal_setup_or_halt(), internal_ssie_loop_setup_or_halt(), internal_tc_setup_or_halt(), internal_td_setup_or_halt(), internal_uart_hello_setup_or_halt(), internal_usb_audio_clocks_or_halt(), internal_wdt_demo_setup_or_halt(), ipc_demo_setup_or_halt(), iu_setup_or_halt(), iv_setup_or_halt(), kat_setup_or_halt(), kb_setup_or_halt(), l3_setup_or_halt(), lcd_bringup_clocks(), lin_hil_setup_or_halt(), lk_setup_or_halt(), lpi_setup_or_halt(), main(), mem_setup_or_halt(), mg_bringup_clocks(), microsd_setup_or_halt(), mlun_setup_or_halt(), modem_clocks_or_halt(), ospirw_setup_or_halt(), pdm_demo_clocks_or_halt(), pp_demo_clocks_or_halt(), riic_target_clocks_or_halt(), rot_setup_or_halt(), sb_setup_or_halt(), scb_demo_setup_or_halt(), sd_demo_setup_or_halt(), sd_setup_or_halt(), sdhi_card_setup_or_halt(), sdhi_demo_setup_or_halt(), sdmsc_setup_or_halt(), sdram_demo_setup_or_halt(), selftest_setup_or_halt(), sfr_bringup_clocks(), sh_setup_or_halt(), tb_setup_or_halt(), timer_demo_setup_or_halt(), tsn_setup_or_halt(), uart_irq_setup_or_halt(), wa_setup_or_halt(), wc_setup_or_halt(), wd_setup_or_halt(), wdt_rr_setup_or_halt(), wdt_window_demo_setup_or_halt(), webp_demo_setup_or_halt(), wifi_hal_setup_or_halt(), wk_setup_or_halt(), and wlun_setup_or_halt().

◆ ra8_time_ms()

uint32_t ra8_time_ms ( void )

Implementation of ra8_time_ms() – read SysTick counter.

Non-Secure ra8_time_ms – monotonic millisecond clock from ThreadX.

Get the current 1 kHz tick count.

Returns the SysTick-incremented s_tick_ms counter.

Returns
Milliseconds since ra8_time_init(), modulo 2^32.
Return values
0..UINT32_MAXCurrent tick count.
Precondition
ra8_time_init() has been called.
Reader is OK with single-word atomicity.
Postcondition
No state modified.
Successive calls are non-decreasing modulo 2^32.
Note
Thread-safe (atomic single-word read on Cortex-M).
Since
0.1.0

Definition at line 108 of file ra8_time.c.

◆ ra8_time_on_tick()

void ra8_time_on_tick ( void )

Implementation of ra8_time_on_tick() – SysTick IRQ tick.

SysTick IRQ handler – called from the vector table.

Increments s_tick_ms. Invoked from SysTick IRQ.

Precondition
Invoked from SysTick IRQ context (or test equivalent).
ra8_time_init() has set up the SysTick reload.
Postcondition
s_tick_ms is incremented by exactly one.
No other state is modified.
Note
IRQ-safe; SysTick cannot pre-empt itself.
Since
0.1.0

Definition at line 170 of file ra8_time.c.

References s_tick_ms.

Referenced by SysTick_Handler().

◆ SysTick_Handler()

void SysTick_Handler ( void )

Service one SysTick event for the core timebase.

Service the SysTick exception selected by the linked application.

The weak firmware implementation advances the millisecond counter, then services linked ThreadX and USB hooks when their weak symbols and readiness state permit. The host-test implementation advances only the counter. An application may replace either weak definition with a strong handler.

Precondition
The handler is entered for one SysTick event or a host-test equivalent.
On target, ra8_time_init() configured the SysTick period.
Postcondition
s_tick_ms has advanced by exactly one.
Optional subsystem hooks run only when linked and ready.
Note
IRQ-safe; the weak symbol may be overridden by an application handler.
Since
0.1.0

Definition at line 244 of file ra8_time.c.

◆ ux_dcd_ra8_usb_irq_reenable()

void ux_dcd_ra8_usb_irq_reenable ( void )
extern

Storm-guard recovery: zero the run counter and re-enable the USB IRQ.

The recovery half of the USBFS interrupt-storm guard. Each USB-FS app's SysTick_Handler calls this every 1 ms. Zeroing g_isr_spurious_run makes that counter a per-millisecond rate gauge – so normal idle SOFR can never accumulate to the mask threshold – and re-enabling the NVIC line undoes any mask internal_usbfs_isr applied. Re-enabling an already-enabled line is a no-op, so calling this outside a storm is harmless. SysTick is used rather than a ThreadX TX_TIMER because it is an exception handler: it keeps running even while a storm has thread mode – and the ThreadX timer subsystem – starved.

Returns
No value; the helper is unconditional.
Note
g_isr_spurious_run == 0 and the USB IRQ line is enabled.
Precondition
s_usb_irq_slot resolved (ux_dcd_ra8_usb_initialize has run).
Called from the per-app 1 ms SysTick handler (exception context).
Postcondition
g_isr_spurious_run == 0.
NVIC re-routes the next USB event to the registered trampoline.
Note
Idempotent; intended to be called from the 1 ms SysTick handler.
Since
0.1.0

Definition at line 260 of file ux_dcd_ra8_usb.c.

References g_dcd, g_isr_spurious_run, internal_usbfs_irq_set_enabled(), k_nvic_irqs_per_reg, k_nvic_ispr_base, k_nvic_reg_stride, k_ux_dcd_ra8_usb_max_pipes, and s_usb_irq_slot.

Referenced by SysTick_Handler().

Variable Documentation

◆ g_ra8_threadx_systick_ready

volatile uint32_t g_ra8_threadx_systick_ready
extern

0 until _tx_initialize_low_level has armed ThreadX's SysTick + timer state; 1 afterwards.

Read by the shared SysTick handler in libs/ra8_core/src/ra8_time.c.

Note
Single-writer (assembly, once); multi-reader (every SysTick).
Since
0.1.0

Definition at line 58 of file tx_systick_ready.c.

Referenced by _tx_timer_interrupt(), internal_systick_handler(), ns_systick_handler(), and SysTick_Handler().

◆ s_cycles_per_ms

volatile uint32_t s_cycles_per_ms = 0U
static

CPU cycles per millisecond, stamped by ra8_time_init.

Definition at line 33 of file ra8_time.c.

Referenced by ra8_delay_ms(), and ra8_time_init().

◆ s_tag

const char* s_tag = "TIME"
static

Definition at line 28 of file ra8_time.c.

◆ s_tick_ms

volatile uint32_t s_tick_ms = 0U
static

Definition at line 30 of file ra8_time.c.

Referenced by ra8_delay_ms(), ra8_time_init(), ra8_time_ms(), and ra8_time_on_tick().