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

Software Standby (LPSCR.LPMD = 0x5) + RTC periodic wake demo. More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_board_ek_ra8d2.h"
#include "ra8_boot_entry.h"
#include "ra8_cgc.h"
#include "ra8_err.h"
#include "ra8_isr.h"
#include "ra8_lpm.h"
#include "ra8_lpm_regs.h"
#include "ra8_rtc.h"
#include "ra8_time.h"
Include dependency graph for main.c:

Go to the source code of this file.

Enumerations

enum  lpm_swstd_const_t : uint32_t { k_lpm_swstd_baud = 115200U }
 Demo tunables. More...
enum  lpm_swstd_byte_t : uint16_t {
  k_lpm_swstd_alarm_offset_s = 5U ,
  k_lpm_swstd_seed_year_lo = 26U ,
  k_lpm_swstd_year_base = 2000U ,
  k_lpm_swstd_seed_month = 1U ,
  k_lpm_swstd_seed_day = 1U ,
  k_lpm_swstd_secs_per_min = 60U ,
  k_lpm_swstd_mins_per_hour = 60U ,
  k_lpm_swstd_hours_per_day = 24U
}
 Single-byte demo constants. More...

Functions

static void internal_lpm_swstd_panic_halt (void)
 Park the processor after a fatal setup or standby-path failure.
static void internal_lpm_swstd_setup_or_halt (void)
 Bring CGC + SysTick + SCI8 + RTC + LPM block up.
static void internal_lpm_swstd_add_offset (const ra8_rtc_datetime_t *now, ra8_rtc_datetime_t *out)
 Compute now + 5 s wrapping over seconds/minutes/hours.
static ra8_err_t internal_lpm_swstd_arm_wake (const ra8_rtc_datetime_t *now)
 Arm the +5 s RTC alarm and the WUPEN0.RTCALM wake source.
void main (void)
 The application entry point Reset_Handler hands control to.

Variables

static const uint8_t s_lpm_swstd_boot_msg [] = "lpm_swstd: boot\r\n"
 Boot banner – this is the HIL gate string.
volatile uint32_t g_lpm_swstd_wake_count = 0U
 Liveness counter – bumped after each Software-Standby wake.

Detailed Description

Software Standby (LPSCR.LPMD = 0x5) + RTC periodic wake demo.

Tag
[Ring 6 / APP] {World: S}

Demonstrates Software Standby mode on the EK-RA8D2. Software Standby gates almost every clock domain except the sub-clock oscillator (SOSC) and a small set of always-on wake-up detectors – including the RTC. The demo wires the RTC alarm onto WUPEN0.RTCALMWUPEN so a +5 s RTC alarm wakes the CPU out of LPMD = 0x5.

Boot flow:

  1. CGC + SysTick + UART (SCI8) bring-up.
  2. Emit boot banner "lpm_swstd: boot\r\n" – this is what the HIL harness gates on (see hil.conf).
  3. RTC init + seed time + arm alarm + enable RCR1.AIE.
  4. Arm WUPEN0.RTCALMWUPEN so the alarm cancels Software Standby.
  5. ra8_lpm_enter_sleep(k_ra8_sleep_mode_software_std).
  6. On wake, re-arm the alarm +5 s in the future and loop.
SOSC caveat
The sub-clock crystal on the bare EK-RA8D2 has been observed to be intermittent (see memory/project_eth_* notes for the same SOSC failure mode in other apps). If SOSC is not ticking, the RTC alarm never fires and the WFI hangs indefinitely. The HIL gate is deliberately boot-banner-only so the bench reports "this firmware built and ran main() to the standby entry point" even when the crystal is silent. The wake path itself is verified by direct benchwork (debugger / scope), not by the automated HIL.
Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ lpm_swstd_byte_t

enum lpm_swstd_byte_t : uint16_t

Single-byte demo constants.

Enumerator
k_lpm_swstd_alarm_offset_s 

Lpm swstd alarm offset s.

k_lpm_swstd_seed_year_lo 

Lpm swstd seed year lo.

k_lpm_swstd_year_base 

Calendar epoch base for the year field.

k_lpm_swstd_seed_month 

Lpm swstd seed month.

k_lpm_swstd_seed_day 

Lpm swstd seed day.

k_lpm_swstd_secs_per_min 

Lpm swstd secs per minimum.

k_lpm_swstd_mins_per_hour 

Lpm swstd mins per hour.

k_lpm_swstd_hours_per_day 

Lpm swstd hours per day.

Definition at line 59 of file main.c.

◆ lpm_swstd_const_t

enum lpm_swstd_const_t : uint32_t

Demo tunables.

Enumerator
k_lpm_swstd_baud 

Lpm swstd baud.

Definition at line 54 of file main.c.

Function Documentation

◆ internal_lpm_swstd_add_offset()

void internal_lpm_swstd_add_offset ( const ra8_rtc_datetime_t * now,
ra8_rtc_datetime_t * out )
static

Compute now + 5 s wrapping over seconds/minutes/hours.

Copies the complete calendar value, then advances the time-of-day fields with explicit carry propagation through seconds, minutes, and hours.

Parameters
[in]nowCurrent datetime.
[out]outReceives the +5 s alarm datetime.
Precondition
out is non-NULL.
now->second < 60, now->minute < 60, now->hour < 24.
Postcondition
out->second/minute/hour reflect the wall-clock advance.
out->year/month/day/weekday mirror now.
Note
Day rollover wraps the hour to zero; date advancement is out of scope.
Since
0.1.0

Definition at line 185 of file main.c.

References ra8_rtc_datetime_t::hour, k_lpm_swstd_alarm_offset_s, k_lpm_swstd_hours_per_day, k_lpm_swstd_mins_per_hour, k_lpm_swstd_secs_per_min, ra8_rtc_datetime_t::minute, RA8_INTERNAL, and ra8_rtc_datetime_t::second.

Referenced by internal_lpm_swstd_arm_wake().

◆ internal_lpm_swstd_arm_wake()

ra8_err_t internal_lpm_swstd_arm_wake ( const ra8_rtc_datetime_t * now)
staticnodiscard

Arm the +5 s RTC alarm and the WUPEN0.RTCALM wake source.

Builds the future alarm, enables the RTC alarm interrupt, and then enables the corresponding software-standby wake bit.

Parameters
[in]nowCurrent RTC calendar value used as the alarm base.
MC/DC:
Compound decision: ra8_rtc_set_alarm != ok || ra8_rtc_set_irq_enable != ok || ra8_lpm_arm_wupen0_bits != ok. Three atomic conditions x N+1 = 4 vectors – all-ok runtime path
  • each branch error path covered in the host unit test.
Returns
Error code from the first failing primitive.
Return values
k_ra8_okThe alarm and wake-source bit were armed.
Precondition
RTC has been initialised and seeded.
LPM block has been initialised with PRC1 unlocked.
Postcondition
On success the RTC alarm is set 5 s in the future and WUPEN0.RTCALMWUPEN is asserted.
On failure, later alarm-routing operations are not attempted.
Note
The alarm target uses the bounded offset helper and does not change now.
Since
0.1.0

Definition at line 227 of file main.c.

References internal_lpm_swstd_add_offset(), k_ra8_lpm_wupen0_rtcalm, k_ra8_ok, k_ra8_rtc_irq_alarm, ra8_lpm_arm_wupen0_bits(), ra8_rtc_set_alarm(), and ra8_rtc_set_irq_enable().

Referenced by main().

◆ internal_lpm_swstd_panic_halt()

void internal_lpm_swstd_panic_halt ( void )
static

Park the processor after a fatal setup or standby-path failure.

Executes wait-for-interrupt indefinitely so a failed software- standby sequence cannot continue into application code with partial state.

Precondition
The caller has determined that the demo cannot continue safely.
No foreground recovery operation remains capable of restoring state.
Postcondition
This function does not return.
The processor remains in a low-activity wait loop.
Note
The terminal loop preserves the failure state for a debugger probe.
Since
0.1.0

Definition at line 98 of file main.c.

References RA8_INTERNAL.

Referenced by internal_lpm_swstd_setup_or_halt(), and main().

◆ internal_lpm_swstd_setup_or_halt()

void internal_lpm_swstd_setup_or_halt ( void )
static

Bring CGC + SysTick + SCI8 + RTC + LPM block up.

Same shape as lpm_idle_demo but adds RTC init + alarm seed. The J-Link console (SCI8 + PD02/PD03 routing + baud) is brought up via the EK-RA8D2 board-support package.

Precondition
IRQs disabled (Reset_Handler default).
Reset_Handler has copied .data and zeroed .bss.
Postcondition
On success every sub-system is armed; on failure the function panic-halts and never returns.
LPM block has LPSCR.LPMD = 0 (System Active) so the first WFI is a plain CPU sleep until ra8_lpm_enter_sleep is called.
Note
The helper applies a fail-closed startup policy before IRQs are enabled.
Since
0.1.0

Definition at line 125 of file main.c.

References internal_lpm_swstd_panic_halt(), k_lpm_swstd_baud, k_lpm_swstd_seed_day, k_lpm_swstd_seed_month, k_lpm_swstd_seed_year_lo, k_lpm_swstd_year_base, k_ra8_clock_id_cpuclk0, k_ra8_lpm_dcssmode_128us, k_ra8_lpm_ss2lp_default, k_ra8_ok, ra8_board_uart_console_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), RA8_INTERNAL, ra8_lpm_init(), ra8_rtc_init(), ra8_rtc_set(), and ra8_time_init().

Referenced by main().

◆ main()

void main ( void )

The application entry point Reset_Handler hands control to.

Returns void, not int. This is a freestanding image: there is no hosted C environment, no process and nothing to report an exit status to. ISO C fixes main at int only for a hosted implementation; for a freestanding one (C23 5.1.2.1) the startup function's name and type are implementation-defined, and this is that definition. Reset_Handler discards no value because there is none to discard, and if main ever does return, startup halts the CPU rather than resuming anything.

The firmware lane is compiled -ffreestanding (see cmake/ra8_add_app.cmake) and the flag and this signature travel together: without it both GCC and clang reject a non-int main (-Wmain / -Wmain-return-type). Do not remove one without the other.

That coupling is why the declaration sits behind __STDC_HOSTED__ == 0, which -ffreestanding sets and a hosted build does not. The guard is not defensive dressing: this header is reachable from host builds (the unit tests compile ra8_core natively), and an unguarded void main(void); makes every hosted translation unit that includes it fail with conflicting types for 'main' against its own ISO int main. The declaration therefore exists exactly where its contract does.

Hosted first-party code – everything under tests/ and tools/ – uses the ISO int main(...) contract instead, because it genuinely does run under an OS that reads the exit status. scripts/checks/check_entry_points.py holds each domain to its own contract (#707).

Declared here, once, for the same reason SystemInit is: every vector_table.c used to restate it as a local extern int32_t main(void);, sixteen copies that no compiler ever compared against the definition – and roughly thirty of them had silently drifted out of agreement with the main they called.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has configured the clock tree and VTOR.
Postcondition
Control does not return; the image runs until reset or halt.
Any value the application wanted to report has been logged, not returned.
Note
Not thread-safe; single-threaded startup context only.
Warning
Only valid while the translation unit is compiled -ffreestanding. A hosted build rejects this signature.
See also
SystemInit()
Since
0.1.0

The application entry point Reset_Handler hands control to.

Brings up CGC + BSP audio then plays blocks.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has set VTOR, FPU, and priority grouping.
Postcondition
On clean entry the CPU stays in the playback loop forever.
On any HAL init failure the function halts in WFI.
Since
0.1.0

The application entry point Reset_Handler hands control to.

Brings up CGC + GPT triple, runs sweep.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has set VTOR, FPU, and priority grouping.
Postcondition
On clean entry the CPU stays in the sweep loop forever.
On any HAL init failure the function halts in WFI.
Since
0.1.0

The application entry point Reset_Handler hands control to.

Brings up clocks + UART + RMII pins, then ThreadX.

Precondition
Reset_Handler has copied .data and zeroed .bss.
Postcondition
On clean entry the kernel runs the worker thread once.
Since
0.1.0

The application entry point Reset_Handler hands control to.

Brings up clocks + UART, then enters ThreadX.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has set VTOR, FPU, and priority grouping.
Postcondition
On clean entry the kernel runs the worker thread forever.
On any HAL init failure the function halts in WFI.
Since
0.1.0

The application entry point Reset_Handler hands control to.

Brings up LED, console, SDHI pins, then ThreadX.

Precondition
Reset_Handler has copied .data + zeroed .bss.
SystemInit has set VTOR, FPU, and priority grouping.
Postcondition
CPUCLK0 is raised to the PLL1 target before the kernel starts.
On clean entry the SD card thread runs forever.
On any HAL init failure the function halts in __WFI.
Since
0.1.0

The application entry point Reset_Handler hands control to.

Brings up CGC + USB-FS + UAC1, then enters the iso-IN feed loop forever.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has set VTOR, FPU, and priority grouping.
Postcondition
On clean entry the CPU stays in the iso-IN feed loop forever.
On any HAL init failure the function halts in WFI.
Since
0.1.0

The application entry point Reset_Handler hands control to.

Precondition
SystemInit set VTOR / FPU / priority grouping.

The application entry point Reset_Handler hands control to.

See file header.

Precondition
Boot init has completed.
The secure-boot library's BLXNS into NS image either failed or was skipped (the call site in ra8_trustzone_init is a no-op on host builds).
Postcondition
Diagnostic counter latched, CPU parked in a halt loop.
Function never returns.
Note
Single-threaded entry.
Since
0.1.0

The application entry point Reset_Handler hands control to.

Precondition
Reset_Handler copied .data and zeroed .bss.
SystemInit set VTOR / FPU / priority grouping.
Postcondition
On success g_eoh_chapters / g_eoh_crc hold the parsed results, the banner is emitted, and g_eoh_heartbeat advances once per frame.
On any failure g_eoh_err is non-zero and the CPU parks (no heartbeat).
Since
0.1.0

The application entry point Reset_Handler hands control to.

Precondition
Reset_Handler copied .data and zeroed .bss.
SystemInit set VTOR / FPU / priority grouping.
Postcondition
The chapters/ch0-CRC banner is emitted; the CPU then loops in WFI.
Since
0.1.0

The application entry point Reset_Handler hands control to.

Precondition
Reset_Handler copied .data and zeroed .bss.
SystemInit set VTOR / FPU / priority grouping.
Postcondition
On success the g_etoc_* result globals hold the parsed TOC values, the banner is emitted, and g_etoc_heartbeat advances once per frame.
On any failure g_etoc_err is non-zero and the CPU parks (no heartbeat).
Since
0.1.0

The application entry point Reset_Handler hands control to.

Precondition
Reset_Handler copied .data and zeroed .bss; SystemInit set VTOR/FPU.
Postcondition
The shelf scans on the panel; taps open books, browse, and read.
Since
0.1.0

Definition at line 242 of file main.c.

References g_lpm_swstd_wake_count, internal_lpm_swstd_arm_wake(), internal_lpm_swstd_panic_halt(), internal_lpm_swstd_setup_or_halt(), k_ra8_ok, k_ra8_rtc_irq_alarm, k_ra8_sleep_mode_software_std, ra8_board_uart_console_write(), ra8_isr_globals_enable(), ra8_lpm_enter_sleep(), ra8_rtc_clear_status(), ra8_rtc_get(), and s_lpm_swstd_boot_msg.

Variable Documentation

◆ g_lpm_swstd_wake_count

volatile uint32_t g_lpm_swstd_wake_count = 0U

Liveness counter – bumped after each Software-Standby wake.

Exposed for ad-hoc J-Link debugging when the SOSC is actually ticking; not gated on by the HIL config (see file header).

Since
0.1.0

Definition at line 83 of file main.c.

Referenced by main().

◆ s_lpm_swstd_boot_msg

const uint8_t s_lpm_swstd_boot_msg[] = "lpm_swstd: boot\r\n"
static

Boot banner – this is the HIL gate string.

Definition at line 71 of file main.c.

Referenced by main().