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

Low Power Mode + clock-domain wrapper implementation. More...

#include "ra8_pwr.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_cgc.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_hw_intrinsics.h"
#include "ra8_log.h"
#include "ra8_lpm_regs.h"
#include "ra8_mstp.h"
#include "ra8_mstp_regs.h"
#include "ra8_system_regs.h"
Include dependency graph for ra8_pwr.c:

Go to the source code of this file.

Enumerations

enum  pwr_mask_t : uint16_t { k_pwr_byte_mask = 0xFFU }
 Low-byte mask for register/bit decomposition. More...
enum  ra8_pwr_dim_t : uint8_t {
  k_ra8_pwr_wupen_count = 2U ,
  k_ra8_pwr_wupen_bits = 32U
}
 WUPEN address-decode bounds. More...

Functions

static volatile uint32_t * internal_wupen_ptr (uint8_t reg)
 Pointer to one of the 32-bit WUPEN registers.
static bool internal_decode_wake (ra8_pwr_wake_t source, uint8_t *out_reg, uint8_t *out_bit)
 Decode and validate a packed wake source.
static void internal_wfi (void)
 WFI wrapper.
ra8_err_t ra8_pwr_init (void)
 Initialise the LPM substrate.
ra8_err_t ra8_pwr_module_request (ra8_mstp_t id)
 Ask for a peripheral's clock to be enabled.
ra8_err_t ra8_pwr_module_release (ra8_mstp_t id)
 Release a previously-requested peripheral.
ra8_err_t ra8_pwr_set_wake_source (ra8_pwr_wake_t source)
 Enable an LPM wake source.
ra8_err_t ra8_pwr_clear_wake_source (ra8_pwr_wake_t source)
 Disable an LPM wake source.
ra8_err_t ra8_pwr_wake_source_is_enabled (ra8_pwr_wake_t source, bool *out_enabled)
 Read the current WUPEN bit value for a source.
void ra8_pwr_enter_sleep (void)
 Enter CPU sleep mode (peripherals continue running).
ra8_err_t ra8_pwr_enter_software_standby (void)
 Enter Software Standby mode.
ra8_err_t ra8_pwr_get_clock_hz (ra8_clock_id_t id, uint32_t *out_hz)
 Forward to ra8_cgc_get_clock_hz() for naming consistency.

Variables

static const char * s_tag = "PWR"

Detailed Description

Low Power Mode + clock-domain wrapper implementation.

Tag
[Ring 3 / HAL] {World: S}

Ring 3 / HAL substrate. See ra8_pwr.h for the API contract. Implementation depth is intentionally minimal:

  • Module request / release forward straight to ra8_mstp.
  • Wake-source toggling reads / modifies / writes WUPEN0 or WUPEN1 directly. The full WUPEN field map will be added in (RTC, ULPT, AGT bring-up).
  • ra8_pwr_enter_sleep() issues a single WFI on the target and is a no-op in RA8_OFF_TARGET.
  • ra8_pwr_enter_software_standby() validates that at least one wake source is armed, then sets LPMD and SLEEPDEEP and issues WFI. The WFI is host-no-op so unit tests do not stall.

Definition in file ra8_pwr.c.

Enumeration Type Documentation

◆ pwr_mask_t

enum pwr_mask_t : uint16_t

Low-byte mask for register/bit decomposition.

Enumerator
k_pwr_byte_mask 

Pwr byte mask.

Definition at line 49 of file ra8_pwr.c.

◆ ra8_pwr_dim_t

enum ra8_pwr_dim_t : uint8_t

WUPEN address-decode bounds.

Enumerator
k_ra8_pwr_wupen_count 

WUPEN0 + WUPEN1.

k_ra8_pwr_wupen_bits 

32 bits per register.

Definition at line 57 of file ra8_pwr.c.

Function Documentation

◆ internal_decode_wake()

bool internal_decode_wake ( ra8_pwr_wake_t source,
uint8_t * out_reg,
uint8_t * out_bit )
static

Decode and validate a packed wake source.

Parameters
[in]sourcePacked identifier.
[out]out_regRegister index 0 or 1.
[out]out_bitBit position 0..31.
Returns
true on valid decode.

See implementation.

Return values
k_ra8_okOperation succeeded.
Precondition
Module state is consistent.
Module state is consistent.
Postcondition
Caller-visible state matches the documented contract.
Caller-visible state matches the documented contract.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 101 of file ra8_pwr.c.

References k_pwr_byte_mask, k_ra8_pwr_wupen_bits, and k_ra8_pwr_wupen_count.

Referenced by ra8_pwr_clear_wake_source(), ra8_pwr_set_wake_source(), and ra8_pwr_wake_source_is_enabled().

◆ internal_wfi()

void internal_wfi ( void )
inlinestatic

WFI wrapper.

No-op on the host build.

Routes through the ra8_hw_intrinsics seam: on the Cortex-M85 target it expands to wfi; on the host the stub returns at once so unit tests can call ra8_pwr_enter_sleep() without stalling.

Precondition
Module state is consistent.
The desired sleep-mode registers have been written.
Postcondition
The core has parked until a wake event (target) or returned (host).
No module state is mutated by the wait itself.
Note
Not thread-safe unless documented otherwise.
Since
0.1.0

Definition at line 131 of file ra8_pwr.c.

References ra8_hw_wfi(), and RA8_INTERNAL.

Referenced by ra8_pwr_enter_sleep(), and ra8_pwr_enter_software_standby().

◆ internal_wupen_ptr()

volatile uint32_t * internal_wupen_ptr ( uint8_t reg)
static

Pointer to one of the 32-bit WUPEN registers.

The WUPEN registers live inside the SYSC block at the offsets defined in ra8_lpm_regs.h.

Definition at line 74 of file ra8_pwr.c.

References k_ra8_lpm_wupen0_off, k_ra8_lpm_wupen1_off, k_ra8_system_base_addr, and RA8_INTERNAL.

Referenced by ra8_pwr_clear_wake_source(), ra8_pwr_enter_software_standby(), ra8_pwr_init(), ra8_pwr_set_wake_source(), and ra8_pwr_wake_source_is_enabled().

◆ ra8_pwr_clear_wake_source()

ra8_err_t ra8_pwr_clear_wake_source ( ra8_pwr_wake_t source)
nodiscard

Disable an LPM wake source.

Clears the corresponding bit in WUPEN0 or WUPEN1.

Parameters
[in]sourcePacked ra8_pwr_wake_t identifier.
Returns
ra8_err_t error code.
Return values
k_ra8_okThe bit is clear.
k_ra8_err_invalid_argsource decodes to an out-of-range register or bit.
Precondition
IRQs masked or single-threaded init context.
ra8_pwr_init() has been called.
Postcondition
The relevant WUPEN bit is clear.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 183 of file ra8_pwr.c.

References internal_decode_wake(), internal_wupen_ptr(), k_ra8_err_invalid_arg, k_ra8_ok, ra8_log_error_val, and s_tag.

◆ ra8_pwr_enter_sleep()

void ra8_pwr_enter_sleep ( void )

Enter CPU sleep mode (peripherals continue running).

Issues a single WFI instruction. The Cortex-M85 enters Sleep mode and the CPU clock is gated until any enabled interrupt fires. Peripherals run normally because LPMD bits are not touched.

On the host (RA8_OFF_TARGET) this is a no-op so unit tests do not stall.

Precondition
IRQs are masked at the level the caller wants to wake on.
At least one enabled interrupt source exists, otherwise the CPU never wakes.
Postcondition
On wake, the function returns to the caller. Caller is responsible for draining whatever woke them.
Note
Thread safety: not thread-safe.
Since
0.1.0
Postcondition
Caller-visible state matches the documented contract.

Definition at line 212 of file ra8_pwr.c.

References internal_wfi().

◆ ra8_pwr_enter_software_standby()

ra8_err_t ra8_pwr_enter_software_standby ( void )
nodiscard

Enter Software Standby mode.

Sets LPSCR.LPMD = 0x5 and the Cortex-M85 SCR.SLEEPDEEP bit, then issues WFI (HUM 11.6.2.1 p 482). Most oscillators stop, the CPU stops, peripherals freeze. Wakes from any source armed via ra8_pwr_set_wake_source().

On the host this is a no-op.

Returns
ra8_err_t error code.
Return values
k_ra8_okReturned cleanly after wake.
k_ra8_err_invalid_stateCaller failed to arm any wake source first.
Precondition
At least one wake source is armed in WUPEN0/1.
IRQs are configured per HUM 11.6.2.1 (the wake interrupt must have its IELSRn entry programmed).
Postcondition
On wake, the function returns to the caller.
LPMD has been written back to 0 (normal mode).
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 217 of file ra8_pwr.c.

References internal_wfi(), internal_wupen_ptr(), k_ra8_err_invalid_state, k_ra8_ok, ra8_log_error, and s_tag.

◆ ra8_pwr_get_clock_hz()

ra8_err_t ra8_pwr_get_clock_hz ( ra8_clock_id_t id,
uint32_t * out_hz )
nodiscard

Forward to ra8_cgc_get_clock_hz() for naming consistency.

Plain forwarding helper. Drivers that already include ra8_pwr.h for module gating do not need to also include ra8_cgc.h just to look up a baud-rate divider.

Parameters
[in]idClock identifier.
[out]out_hzOn success, current frequency in Hz.
Returns
Result of the underlying ra8_cgc_get_clock_hz().
Precondition
out_hz is non-NULL.
id is a value from ra8_clock_id_t.
Postcondition
On success, *out_hz holds the live frequency.
No hardware state is modified.
Note
Thread safety: not thread-safe.
See also
ra8_cgc_get_clock_hz
Since
0.1.0

Definition at line 240 of file ra8_pwr.c.

References ra8_cgc_get_clock_hz().

◆ ra8_pwr_init()

ra8_err_t ra8_pwr_init ( void )
nodiscard

Initialise the LPM substrate.

Validates the post-reset state and clears every WUPEN bit so that subsequent ra8_pwr_set_wake_source() calls are the only source of wake events. Also calls ra8_mstp_init() so the MSTP ref-count table starts in lockstep with hardware.

Returns
ra8_err_t error code.
Return values
k_ra8_okSubstrate ready.
k_ra8_err_hw_timeoutra8_mstp_init() did not see its read-back within budget.
Precondition
Caller is in single-threaded init context.
Cold reset has just occurred (warm-reset entry is OK too – the function tolerates either).
Postcondition
WUPEN0 == 0 and WUPEN1 == 0.
ra8_mstp ref-count table is all zero.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 141 of file ra8_pwr.c.

References internal_wupen_ptr(), k_ra8_ok, ra8_log_error_val, ra8_log_info, ra8_mstp_init(), and s_tag.

Referenced by ra8_nsc_periph_init().

◆ ra8_pwr_module_release()

ra8_err_t ra8_pwr_module_release ( ra8_mstp_t id)
nodiscard

Release a previously-requested peripheral.

Forwards to ra8_mstp_disable(id).

Parameters
[in]idPeripheral identifier from ra8_mstp_t.
Returns
Result of the underlying ra8_mstp_disable().
Precondition
IRQs masked or single-threaded init context.
Caller previously called ra8_pwr_module_request(id).
Postcondition
On the last release, the peripheral is gated.
Ref count for id is decremented by 1.
Note
Thread safety: not thread-safe.
See also
ra8_mstp_disable
Since
0.1.0

Definition at line 163 of file ra8_pwr.c.

References ra8_mstp_disable().

◆ ra8_pwr_module_request()

ra8_err_t ra8_pwr_module_request ( ra8_mstp_t id)
nodiscard

Ask for a peripheral's clock to be enabled.

Forwards to ra8_mstp_enable(id) after logging. Future versions will validate the requested module against the current LPM state and route the request through an NSC veneer.

Parameters
[in]idPeripheral identifier from ra8_mstp_t.
Returns
Result of the underlying ra8_mstp_enable().
Precondition
IRQs masked or single-threaded init context.
ra8_pwr_init() has been called.
Postcondition
On success, the peripheral is clocked.
Ref count for id is at least 1.
Note
Thread safety: not thread-safe.
See also
ra8_mstp_enable
Since
0.1.0

Definition at line 158 of file ra8_pwr.c.

References ra8_mstp_enable().

◆ ra8_pwr_set_wake_source()

ra8_err_t ra8_pwr_set_wake_source ( ra8_pwr_wake_t source)
nodiscard

Enable an LPM wake source.

Sets the corresponding bit in WUPEN0 or WUPEN1 (HUM 11.2.x register descriptions). Wake sources are addressed by the packed ra8_pwr_wake_t enum.

Parameters
[in]sourcePacked ra8_pwr_wake_t identifier.
Returns
ra8_err_t error code.
Return values
k_ra8_okThe bit is set.
k_ra8_err_invalid_argsource decodes to an out-of-range register or bit.
Precondition
IRQs masked or single-threaded init context.
ra8_pwr_init() has been called.
Postcondition
The relevant WUPEN bit is set.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 168 of file ra8_pwr.c.

References internal_decode_wake(), internal_wupen_ptr(), k_ra8_err_invalid_arg, k_ra8_ok, ra8_log_error_val, and s_tag.

◆ ra8_pwr_wake_source_is_enabled()

ra8_err_t ra8_pwr_wake_source_is_enabled ( ra8_pwr_wake_t source,
bool * out_enabled )
nodiscard

Read the current WUPEN bit value for a source.

Diagnostic accessor used by tests. Returns true if the source is currently armed.

Parameters
[in]sourcePacked ra8_pwr_wake_t identifier.
[out]out_enabledtrue on success if the bit is set.
Returns
ra8_err_t error code.
Return values
k_ra8_okBit value returned.
k_ra8_err_null_ptrout_enabled was NULL.
k_ra8_err_invalid_argsource decoded out of range.
Precondition
out_enabled is non-NULL.
source is a value from ra8_pwr_wake_t.
Postcondition
No hardware state is modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 198 of file ra8_pwr.c.

References internal_decode_wake(), internal_wupen_ptr(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.

Variable Documentation

◆ s_tag

const char* s_tag = "PWR"
static

Definition at line 46 of file ra8_pwr.c.