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

Sleep-mode wake-count demo for the bare EK-RA8D2. 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_time.h"
Include dependency graph for main.c:

Go to the source code of this file.

Enumerations

enum  lpm_demo_config_t : uint32_t {
  k_lpm_demo_baud = 115200U ,
  k_lpm_demo_period_ms = 100U
}
 Compile-time settings. More...
enum  lpm_demo_byte_t : uint8_t {
  k_lpm_demo_nibble_mask = 0x0FU ,
  k_lpm_demo_nibble_shift = 4U ,
  k_lpm_demo_alpha_thresh = 10U ,
  k_lpm_demo_hex_per_word = 8U
}
 Single-byte constants. More...

Functions

static void internal_lpm_demo_panic_halt (void)
 Park the processor after a fatal setup or sleep-cycle failure.
static uint8_t internal_lpm_demo_nibble_to_hex (uint8_t nibble)
 Convert the low nibble of a byte to an ASCII hex character.
static void internal_lpm_demo_word_to_hex (uint32_t v, uint8_t *dst)
 Render a 32-bit value as 8 ASCII hex chars (big-endian).
static void internal_lpm_demo_setup_or_halt (void)
 Bring CGC, SysTick, SCI8, LED1, and the LPM block up.
static ra8_err_t internal_lpm_demo_one_wake (void)
 Sleep + wake + emit one wake-count line.
void main (void)
 The application entry point Reset_Handler hands control to.

Variables

static const uint8_t s_lpm_demo_prefix [] = "lpm: wake_count="
 Output line tags.
static const uint8_t s_lpm_demo_eol [] = "\r\n"
static uint32_t s_wake_count
 Cumulative wake count incremented after every sleep+wake cycle.

Detailed Description

Sleep-mode wake-count demo for the bare EK-RA8D2.

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

Brings up CGC + SysTick + SCI8 + LED1 + the LPM block, then loops:

  1. ra8_lpm_enter_sleep(k_ra8_sleep_mode_sleep) – the CPU idles in WFI; SysTick keeps running and wakes the core every 1 ms.
  2. ra8_delay_ms(100) lets the SysTick handler bring us back ~100 wakes later.
  3. Increment an in-RAM s_wake_count, toggle LED1, emit "lpm: wake_count=NNNNNNNN\r\n" on the J-Link OB CDC channel (115200 8N1).

Sleep mode is the safest LPM mode for a HIL test demo because SysTick keeps running, no external wake source is required, and the JLink debug probe stays attached. Software-Standby / Deep-Standby would require an IRQ pin or RTC alarm wired up, which the bare EVM does not provide without a shield.

Bare EK-RA8D2 only – no shields or external transceivers.

Since
0.1.0

Definition in file main.c.

Enumeration Type Documentation

◆ lpm_demo_byte_t

enum lpm_demo_byte_t : uint8_t

Single-byte constants.

Enumerator
k_lpm_demo_nibble_mask 

Lpm demo nibble mask.

k_lpm_demo_nibble_shift 

Lpm demo nibble shift.

k_lpm_demo_alpha_thresh 

Lpm demo alpha thresh.

k_lpm_demo_hex_per_word 

Lpm demo hex per word.

Definition at line 53 of file main.c.

◆ lpm_demo_config_t

enum lpm_demo_config_t : uint32_t

Compile-time settings.

Enumerator
k_lpm_demo_baud 

Lpm demo baud.

k_lpm_demo_period_ms 

Lpm demo period ms.

Definition at line 47 of file main.c.

Function Documentation

◆ internal_lpm_demo_nibble_to_hex()

uint8_t internal_lpm_demo_nibble_to_hex ( uint8_t nibble)
static

Convert the low nibble of a byte to an ASCII hex character.

Masks the input to four bits and maps it to a decimal digit or a lowercase hexadecimal letter.

Parameters
[in]nibbleLower 4 bits used.
Returns
Printable ASCII byte.
Return values
0x30..0x39Decimal ASCII digit for nibble values zero through nine.
0x61..0x66Lowercase ASCII letter for nibble values ten through fifteen.
Precondition
The caller accepts that bits above the low nibble are discarded.
The execution character set uses contiguous ASCII digit and letter codes.
Postcondition
Return value is always printable ASCII.
The input value and all shared state remain unchanged.
Note
The conversion deliberately emits lowercase hexadecimal.
Since
0.1.0

Definition at line 105 of file main.c.

References k_lpm_demo_alpha_thresh, k_lpm_demo_nibble_mask, and RA8_INTERNAL.

Referenced by internal_lpm_demo_word_to_hex().

◆ internal_lpm_demo_one_wake()

ra8_err_t internal_lpm_demo_one_wake ( void )
staticnodiscard

Sleep + wake + emit one wake-count line.

Enters normal sleep until SysTick wakes the core, accumulates the configured idle period, increments the counter, and emits fixed-width hex.

MC/DC:
Single decision: ra8_lpm_enter_sleep != ok. One atomic condition x 2 vectors – the both-ok runtime path plus the sleep-failure branch covered by the host integration test. No compound (N+1) vectors required.
Returns
Error code from the first failing primitive.
Return values
k_ra8_okThe sleep cycle completed and the count line was emitted.
k_ra8_err_hw_errorThe low-power entry primitive rejected the request.
Precondition
internal_lpm_demo_setup_or_halt returned successfully.
Global interrupts are enabled so SysTick can wake the processor.
Postcondition
On success the wake-count line was transmitted and s_wake_count was incremented.
On failure, s_wake_count and the report stream remain unchanged.
Note
Console writes remain best-effort after a successful sleep transition.
Since
0.1.0

Definition at line 213 of file main.c.

References internal_lpm_demo_word_to_hex(), k_lpm_demo_hex_per_word, k_lpm_demo_period_ms, k_ra8_err_hw_error, k_ra8_ok, k_ra8_sleep_mode_sleep, ra8_board_uart_console_write(), ra8_delay_ms(), RA8_INTERNAL, ra8_lpm_enter_sleep(), s_lpm_demo_eol, s_lpm_demo_prefix, and s_wake_count.

Referenced by main().

◆ internal_lpm_demo_panic_halt()

void internal_lpm_demo_panic_halt ( void )
static

Park the processor after a fatal setup or sleep-cycle failure.

Executes wait-for-interrupt indefinitely so the demo cannot report wake counts after a prerequisite or low-power transition has failed.

Precondition
The caller has determined that normal execution 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
This terminal path keeps the last failure state available for probing.
Since
0.1.0

Definition at line 80 of file main.c.

References RA8_INTERNAL.

Referenced by internal_lpm_demo_setup_or_halt(), and main().

◆ internal_lpm_demo_setup_or_halt()

void internal_lpm_demo_setup_or_halt ( void )
static

Bring CGC, SysTick, SCI8, LED1, and the LPM block up.

Initializes each prerequisite in dependency order and transfers to internal_lpm_demo_panic_halt on the first error.

Precondition
The function runs during single-threaded application startup.
EK-RA8D2 board registers are accessible through the platform mapping.
Postcondition
On return, timing, console, LED1, and sleep-mode configuration are ready.
Any prerequisite failure prevents a return to the caller.
Note
The helper applies the demo's fail-closed startup policy consistently.
Since
0.1.0

Definition at line 153 of file main.c.

References internal_lpm_demo_panic_halt(), k_lpm_demo_baud, k_ra8_board_led1, k_ra8_clock_id_cpuclk0, k_ra8_lpm_dcssmode_128us, k_ra8_lpm_ss2lp_default, k_ra8_ok, ra8_board_led_init(), ra8_board_uart_console_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), RA8_INTERNAL, ra8_lpm_init(), and ra8_time_init().

Referenced by main().

◆ internal_lpm_demo_word_to_hex()

void internal_lpm_demo_word_to_hex ( uint32_t v,
uint8_t * dst )
static

Render a 32-bit value as 8 ASCII hex chars (big-endian).

Extracts nibbles from most significant to least significant and writes exactly eight lowercase hexadecimal characters without a terminator.

Parameters
[in]vValue to render.
[out]dst8-byte buffer that receives the hex characters.
Precondition
dst is non-NULL and has at least 8 bytes capacity.
The destination range does not overlap inaccessible storage.
Postcondition
dst[0..7] contains printable hex.
Bytes outside the eight-byte destination range remain unchanged.
Note
The output is fixed-width and intentionally not NUL-terminated.
Since
0.1.0

Definition at line 130 of file main.c.

References internal_lpm_demo_nibble_to_hex(), k_lpm_demo_hex_per_word, k_lpm_demo_nibble_mask, k_lpm_demo_nibble_shift, and RA8_INTERNAL.

Referenced by internal_lpm_demo_one_wake().

◆ 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 232 of file main.c.

References internal_lpm_demo_one_wake(), internal_lpm_demo_panic_halt(), internal_lpm_demo_setup_or_halt(), k_ra8_board_led1, k_ra8_ok, ra8_board_led_toggle(), and ra8_isr_globals_enable().

Variable Documentation

◆ s_lpm_demo_eol

const uint8_t s_lpm_demo_eol[] = "\r\n"
static

Definition at line 62 of file main.c.

Referenced by internal_lpm_demo_one_wake().

◆ s_lpm_demo_prefix

const uint8_t s_lpm_demo_prefix[] = "lpm: wake_count="
static

Output line tags.

Definition at line 61 of file main.c.

Referenced by internal_lpm_demo_one_wake().

◆ s_wake_count

uint32_t s_wake_count
static

Cumulative wake count incremented after every sleep+wake cycle.

Definition at line 65 of file main.c.

Referenced by internal_lpm_demo_one_wake().