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

Low Power Mode (LPM) HAL driver – public API. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_lpm_regs.h"
Include dependency graph for ra8_lpm.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_lpm_config_t
 Configuration descriptor for ra8_lpm_init. More...
struct  ra8_lpm_ldo_cfg_t
 LDO standby retention selection (HUM 11.2.1 p 436). More...
struct  ra8_lpm_ram_retention_t
 RAM retention configuration (HUM 11.2.16 / 11.2.17). More...

Enumerations

enum  ra8_lpm_pd_timeout_t : uint32_t { k_ra8_lpm_pd_timeout_default = 100000U }
 Poll bound for ra8_lpm_graphics_power_on flag waits. More...
enum  ra8_lpm_clock_t : uint8_t {
  k_ra8_lpm_clock_moco = 0U ,
  k_ra8_lpm_clock_hoco = 1U ,
  k_ra8_lpm_clock_loco = 2U ,
  k_ra8_lpm_clock_main = 3U ,
  k_ra8_lpm_clock_sub = 4U ,
  k_ra8_lpm_clock_count = 5U
}
 Selector for ra8_lpm_set_clock_stop / ra8_lpm_get_clock_stop. More...

Functions

ra8_err_t ra8_lpm_init (const ra8_lpm_config_t *cfg)
 Initialise the LPM block from a config descriptor.
ra8_err_t ra8_lpm_deinit (void)
 Restore SBYCR / DPSBYCR / LPSCR / SSCR1 to cold-reset defaults.
ra8_err_t ra8_lpm_prcr_unlock (void)
 Unlock PRCR.PRC1 to permit writes to LPM control registers.
ra8_err_t ra8_lpm_prcr_relock (void)
 Re-lock PRCR.PRC1 after protected writes.
ra8_err_t ra8_lpm_set_wakeup_sources (uint32_t wupen0, uint32_t wupen1)
 Programme the raw WUPEN0 / WUPEN1 masks.
ra8_err_t ra8_lpm_arm_wupen0_bits (uint32_t bits)
 OR-in additional WUPEN0 bits without disturbing other sources.
ra8_err_t ra8_lpm_clear_wupen0_bits (uint32_t bits)
 AND-out WUPEN0 bits to disarm specific wake-up sources.
ra8_err_t ra8_lpm_arm_wupen1_bits (uint32_t bits)
 OR-in additional WUPEN1 bits without disturbing other sources.
ra8_err_t ra8_lpm_clear_wupen1_bits (uint32_t bits)
 AND-out WUPEN1 bits to disarm specific wake-up sources.
ra8_err_t ra8_lpm_arm_dpsier (ra8_lpm_dpsier_idx_t idx, uint8_t value)
 Programme the per-byte DPSIER0..3 enable byte directly.
ra8_err_t ra8_lpm_clear_dpsifr (ra8_lpm_dpsier_idx_t idx)
 Clear DPSIFR0..3 so a stale flag does not cancel deep standby.
ra8_err_t ra8_lpm_set_dpsiegr (ra8_lpm_dpsier_idx_t idx, uint8_t value)
 Programme DPSIEGR0..2 (deep-standby IRQ edge polarity).
ra8_err_t ra8_lpm_snooze_set_request_sources (bool ulpt0_underflow, bool ulpt1_underflow, bool acmphs0)
 Configure ULPT-driven snooze request sources.
ra8_err_t ra8_lpm_snooze_set_end_sources (bool ulpt0, bool ulpt1, bool usbfs, bool usbhs)
 Configure end-of-snooze sources via DPSIER3 (ULPT/USB hooks).
ra8_err_t ra8_lpm_set_ram_retention (const ra8_lpm_ram_retention_t *cfg)
 Programme PDRAMSCR0 / PDRAMSCR1 from a retention descriptor.
ra8_err_t ra8_lpm_set_ldo_standby (const ra8_lpm_ldo_cfg_t *cfg)
 Programme PLL1LDOCR / PLL2LDOCR / HOCOLDOCR SKEEP bits.
ra8_err_t ra8_lpm_set_clock_stop (ra8_lpm_clock_t clock, bool stop)
 Set or clear the per-oscillator stop bit before sleep entry.
ra8_err_t ra8_lpm_graphics_power_on (uint32_t timeout_iters)
 Power the graphics domain on (DRW / GLCDC / MIPI DSI+CSI / VIN).
ra8_err_t ra8_lpm_get_clock_stop (ra8_lpm_clock_t clock, bool *stop)
 Read the per-oscillator stop bit.
ra8_err_t ra8_lpm_get_opccr (uint8_t *opccr)
 Read OPCCR raw byte (OPCM[1:0] + OPCMTSF).
ra8_err_t ra8_lpm_wait_for_opccr (uint32_t poll_limit)
 Wait for OPCCR.OPCMTSF to clear (mode-transition complete).
ra8_err_t ra8_lpm_enter_sleep (ra8_sleep_mode_t mode)
 Programme LPSCR for mode and enter the requested sleep.
ra8_err_t ra8_lpm_enter_deep_standby (void)
 Convenience wrapper – enter Deep Software Standby mode 1.
ra8_err_t ra8_lpm_get_status (uint32_t *out)
 Read LPM status (SBYCR | DPSBYCR | LPSCR | SSCR1) packed.
ra8_err_t ra8_lpm_get_exit_cause (uint64_t *out)
 Snapshot WUPEN0 / WUPEN1 into a single 64-bit word.
ra8_err_t ra8_lpm_get_dpsi_state (uint8_t enables[4], uint8_t flags[4], uint8_t edges[3])
 Read DPSIER0..3 + DPSIFR0..3 + DPSIEGR0..2 into a buffer.

Detailed Description

Low Power Mode (LPM) HAL driver – public API.

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

Hand-written HAL covering the entire LPM block defined in HUM Ch 11 (pages 429..497) plus the wake-up-source registers in ICU Ch 14.2.19 / 14.2.20. The driver exposes:

Definition in file ra8_lpm.h.

Enumeration Type Documentation

◆ ra8_lpm_clock_t

enum ra8_lpm_clock_t : uint8_t

Selector for ra8_lpm_set_clock_stop / ra8_lpm_get_clock_stop.

Enumerator
k_ra8_lpm_clock_moco 

Middle-Speed On-Chip Oscillator.

k_ra8_lpm_clock_hoco 

High-Speed On-Chip Oscillator.

k_ra8_lpm_clock_loco 

Low-Speed On-Chip Oscillator.

k_ra8_lpm_clock_main 

Main Oscillator.

k_ra8_lpm_clock_sub 

Sub-clock Oscillator.

k_ra8_lpm_clock_count 

RA8 lpm clock count.

Definition at line 152 of file ra8_lpm.h.

◆ ra8_lpm_pd_timeout_t

enum ra8_lpm_pd_timeout_t : uint32_t

Poll bound for ra8_lpm_graphics_power_on flag waits.

Power-gating a domain completes in microseconds (HUM Ch 11.5.1 p 480), so this bound is generous by orders of magnitude at any core clock; it exists to satisfy NASA Rule 2 rather than to encode a real deadline.

See also
ra8_lpm_graphics_power_on
Enumerator
k_ra8_lpm_pd_timeout_default 

Default power-gate poll bound.

Definition at line 144 of file ra8_lpm.h.

Function Documentation

◆ ra8_lpm_arm_dpsier()

ra8_err_t ra8_lpm_arm_dpsier ( ra8_lpm_dpsier_idx_t idx,
uint8_t value )
nodiscard

Programme the per-byte DPSIER0..3 enable byte directly.

Parameters
[in]idxDPSIER selector (k_ra8_lpm_dpsier_idx_*).
[in]value8-bit enable mask to write.
Returns
ra8_err_t error code.
Return values
k_ra8_okRegister updated.
k_ra8_err_invalid_argidx out of range.
Precondition
IRQs masked or single-threaded context.
PRCR.PRC1 unlocked (S-TYPE-4 register).
Postcondition
DPSIER[idx] == value.
DPSIFR[idx] cleared by the driver to avoid spurious cancels.
Note
Thread safety: not thread-safe.
See also
ra8_lpm_clear_dpsifr, ra8_lpm_set_dpsiegr
Since
0.1.0

Definition at line 502 of file ra8_lpm.c.

References internal_dpsier_offset(), internal_dpsifr_offset(), k_ra8_err_invalid_arg, k_ra8_lpm_dpsier_idx_count, k_ra8_ok, ra8_log_error, ra8_lpm_sysc_reg8(), and s_tag.

Referenced by internal_lpm_dpsby1_arm_wake(), internal_lpm_dpsby2_arm_wake(), and internal_lpm_dpsby3_arm_wake().

◆ ra8_lpm_arm_wupen0_bits()

ra8_err_t ra8_lpm_arm_wupen0_bits ( uint32_t bits)
nodiscard

OR-in additional WUPEN0 bits without disturbing other sources.

Parameters
[in]bitsk_ra8_lpm_wupen0_* mask to set.
Returns
ra8_err_t error code.
Return values
k_ra8_okWUPEN0 updated.
Precondition
IRQs masked or caller holds the LPM lock.
Wake-up source has been configured in its owning peripheral.
Postcondition
WUPEN0 has all bits in bits set; no other change.
No other LPM register has been modified.
Note
Thread safety: not thread-safe.
See also
ra8_lpm_clear_wupen0_bits
Since
0.1.0

Definition at line 465 of file ra8_lpm.c.

References k_ra8_lpm_wupen0_off, k_ra8_ok, and ra8_lpm_icu_reg32().

Referenced by internal_lpm_dpsby1_arm_wake(), internal_lpm_dpsby2_arm_wake(), internal_lpm_dpsby3_arm_wake(), internal_lpm_swstd_arm_wake(), and internal_lpm_wake_arm0().

◆ ra8_lpm_arm_wupen1_bits()

ra8_err_t ra8_lpm_arm_wupen1_bits ( uint32_t bits)
nodiscard

OR-in additional WUPEN1 bits without disturbing other sources.

Parameters
[in]bitsk_ra8_lpm_wupen1_* mask to set.
Returns
ra8_err_t error code.
Return values
k_ra8_okWUPEN1 updated.
Precondition
IRQs masked or caller holds the LPM lock.
Wake-up source has been configured in its owning peripheral.
Postcondition
WUPEN1 has all bits in bits set; no other change.
No other LPM register has been modified.
Note
Thread safety: not thread-safe.
See also
ra8_lpm_clear_wupen1_bits
Since
0.1.0

Definition at line 481 of file ra8_lpm.c.

References k_ra8_lpm_wupen1_off, k_ra8_ok, and ra8_lpm_icu_reg32().

Referenced by internal_lpm_wake_arm1(), internal_lus_arm_wake(), and lpi_arm_wake().

◆ ra8_lpm_clear_dpsifr()

ra8_err_t ra8_lpm_clear_dpsifr ( ra8_lpm_dpsier_idx_t idx)
nodiscard

Clear DPSIFR0..3 so a stale flag does not cancel deep standby.

Parameters
[in]idxDPSIER selector (k_ra8_lpm_dpsier_idx_*).
Returns
ra8_err_t error code.
Return values
k_ra8_okFlag cleared.
k_ra8_err_invalid_argidx out of range.
Precondition
IRQs masked or single-threaded context.
PRCR.PRC1 unlocked.
Postcondition
DPSIFR[idx] == 0 (after the dummy read mandated by HUM Ch 11.2.22 p 459).
No other DPSI* register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 522 of file ra8_lpm.c.

References internal_dpsifr_offset(), k_ra8_err_invalid_arg, k_ra8_lpm_dpsier_idx_count, k_ra8_ok, ra8_log_error, ra8_lpm_sysc_reg8(), and s_tag.

◆ ra8_lpm_clear_wupen0_bits()

ra8_err_t ra8_lpm_clear_wupen0_bits ( uint32_t bits)
nodiscard

AND-out WUPEN0 bits to disarm specific wake-up sources.

Parameters
[in]bitsk_ra8_lpm_wupen0_* mask to clear.
Returns
ra8_err_t error code.
Return values
k_ra8_okWUPEN0 updated.
Precondition
IRQs masked or caller holds the LPM lock.
WUPEN0 was previously armed via ra8_lpm_arm_wupen0_bits.
Postcondition
All bits in bits are clear in WUPEN0; other bits unchanged.
No other LPM register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 473 of file ra8_lpm.c.

References k_ra8_lpm_wupen0_off, k_ra8_ok, and ra8_lpm_icu_reg32().

Referenced by internal_lpm_wake_disarm_all().

◆ ra8_lpm_clear_wupen1_bits()

ra8_err_t ra8_lpm_clear_wupen1_bits ( uint32_t bits)
nodiscard

AND-out WUPEN1 bits to disarm specific wake-up sources.

Parameters
[in]bitsk_ra8_lpm_wupen1_* mask to clear.
Returns
ra8_err_t error code.
Return values
k_ra8_okWUPEN1 updated.
Precondition
IRQs masked or caller holds the LPM lock.
WUPEN1 was previously armed via ra8_lpm_arm_wupen1_bits.
Postcondition
All bits in bits are clear in WUPEN1; other bits unchanged.
No other LPM register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 489 of file ra8_lpm.c.

References k_ra8_lpm_wupen1_off, k_ra8_ok, and ra8_lpm_icu_reg32().

Referenced by internal_lpm_wake_disarm_all().

◆ ra8_lpm_deinit()

ra8_err_t ra8_lpm_deinit ( void )
nodiscard

Restore SBYCR / DPSBYCR / LPSCR / SSCR1 to cold-reset defaults.

Rewrites SBYCR with its reset value (OPE=1, all other bits 0), DPSBYCR with its reset value (DCSSMODE=01b), LPSCR with its reset value (System Active), SSCR1=0, all WUPEN bits=0, all DPSIER bits=0. Used during clean teardown so a stray IRQ does not bring us out of a subsequent sleep with stale wake-up arming.

Returns
ra8_err_t error code.
Return values
k_ra8_okRegisters reset.
Precondition
IRQs masked or single-threaded teardown context.
SYSTEM.PRCR.PRC1 unlocked.
Postcondition
SBYCR == k_ra8_lpm_sbycr_reset_val.
WUPEN0 == 0 and WUPEN1 == 0.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 394 of file ra8_lpm.c.

References k_ra8_lpm_dpsbycr_off, k_ra8_lpm_dpsbycr_reset_val, k_ra8_lpm_dpsier0_off, k_ra8_lpm_dpsier1_off, k_ra8_lpm_dpsier2_off, k_ra8_lpm_dpsier3_off, k_ra8_lpm_lpscr_off, k_ra8_lpm_sbycr_off, k_ra8_lpm_sbycr_reset_val, k_ra8_lpm_sscr1_off, k_ra8_lpm_wupen0_off, k_ra8_lpm_wupen1_off, k_ra8_ok, ra8_log_info, ra8_lpm_icu_reg32(), ra8_lpm_sysc_reg8(), and s_tag.

◆ ra8_lpm_enter_deep_standby()

ra8_err_t ra8_lpm_enter_deep_standby ( void )
nodiscard

Convenience wrapper – enter Deep Software Standby mode 1.

Returns
ra8_err_t error code.
Return values
k_ra8_okWFI returned (cold path: never returns on hardware).
Precondition
WUPEN0/1 + DPSIER0..3 + DPSIEGR0..2 already programmed.
PRCR.PRC1 unlocked.
Postcondition
LPSCR.LPMD == 0x8.
SCR.SLEEPDEEP set before WFI.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 786 of file ra8_lpm.c.

References k_ra8_sleep_mode_deep_standby_1, and ra8_lpm_enter_sleep().

◆ ra8_lpm_enter_sleep()

ra8_err_t ra8_lpm_enter_sleep ( ra8_sleep_mode_t mode)
nodiscard

Programme LPSCR for mode and enter the requested sleep.

Maps mode to the LPSCR.LPMD encoding from HUM 11.2.20 p 457, writes the new LPSCR value, configures SCR.SLEEPDEEP for non-Sleep modes, then executes WFI. For k_ra8_sleep_mode_sleep the LPMD field is left at 0 (System Active) and a plain WFI puts only the CPU to sleep – peripherals stay clocked.

State Machine
Parameters
[in]modeTarget sleep mode (sleep / deep-sleep / software-standby / deep-standby 1..3).
Returns
ra8_err_t error code.
Return values
k_ra8_okMode programmed and WFI returned.
k_ra8_err_invalid_argmode was not a valid encoding.
Precondition
Caller has armed at least one wake-up source via ra8_lpm_set_wakeup_sources / ra8_lpm_arm_dpsier.
SYSTEM.PRCR.PRC1 is unlocked.
Postcondition
On wake, LPSCR.LPMD reads back as mode (the bit is sticky per HUM 11.2.20 p 457).
SCR.SLEEPDEEP restored to its pre-call state.
Note
Thread safety: not thread-safe.
Warning
On host (test) builds WFI is replaced with a no-op so the test binary does not block. The LPSCR write is still observable via the fake mmap.
See also
ra8_lpm_set_wakeup_sources, ra8_lpm_arm_dpsier
Since
0.1.0

Definition at line 735 of file ra8_lpm.c.

References internal_set_sleepdeep(), internal_validate_mode(), internal_wait_for_interrupt(), k_ra8_lpm_lpscr_lpmd_mask, k_ra8_lpm_lpscr_off, k_ra8_ok, k_ra8_sleep_mode_deep_sleep, k_ra8_sleep_mode_deep_standby_1, k_ra8_sleep_mode_deep_standby_2, k_ra8_sleep_mode_deep_standby_3, k_ra8_sleep_mode_sleep, k_ra8_sleep_mode_software_std, ra8_log_info_val, ra8_lpm_sysc_reg8(), RA8_RETURN_ON_ERROR, and s_tag.

Referenced by internal_lpm_demo_one_wake(), lpi_idle_one_period(), main(), pp_demo_cycle_modes(), and ra8_lpm_enter_deep_standby().

◆ ra8_lpm_get_clock_stop()

ra8_err_t ra8_lpm_get_clock_stop ( ra8_lpm_clock_t clock,
bool * stop )
nodiscard

Read the per-oscillator stop bit.

Parameters
[in]clockOscillator selector (k_ra8_lpm_clock_*).
[out]stopReceives the current stop bit (1 = stopped).
Returns
ra8_err_t error code.
Return values
k_ra8_ok*stop populated.
k_ra8_err_invalid_argclock out of range.
k_ra8_err_null_ptrstop was nullptr.
Precondition
stop is non-NULL.
Oscillator's owning module is clocked.
Postcondition
*stop reflects the live OCR.STP bit.
No register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 688 of file ra8_lpm.c.

References internal_clock_offset(), k_ra8_err_invalid_arg, k_ra8_lpm_clock_count, k_ra8_lpm_clock_stop_mask, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_log_error, ra8_lpm_sysc_reg8(), and s_tag.

◆ ra8_lpm_get_dpsi_state()

ra8_err_t ra8_lpm_get_dpsi_state ( uint8_t enables[4],
uint8_t flags[4],
uint8_t edges[3] )
nodiscard

Read DPSIER0..3 + DPSIFR0..3 + DPSIEGR0..2 into a buffer.

Parameters
[out]enablesReceives DPSIER0..3 (must be 4 bytes).
[out]flagsReceives DPSIFR0..3 (must be 4 bytes).
[out]edgesReceives DPSIEGR0..2 (must be 3 bytes).
Returns
ra8_err_t error code.
Return values
k_ra8_okAll buffers populated.
k_ra8_err_null_ptrAny of enables / flags / edges was nullptr.
Precondition
All three pointers are non-NULL.
SYSC bus is clocked.
Postcondition
enables[i] / flags[i] / edges[j] reflect the live register values.
No register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 828 of file ra8_lpm.c.

References k_ra8_lpm_dpsiegr0_off, k_ra8_lpm_dpsiegr1_off, k_ra8_lpm_dpsiegr2_off, k_ra8_lpm_dpsier0_off, k_ra8_lpm_dpsier1_off, k_ra8_lpm_dpsier2_off, k_ra8_lpm_dpsier3_off, k_ra8_lpm_dpsifr0_off, k_ra8_lpm_dpsifr1_off, k_ra8_lpm_dpsifr2_off, k_ra8_lpm_dpsifr3_off, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_lpm_sysc_reg8(), and s_tag.

◆ ra8_lpm_get_exit_cause()

ra8_err_t ra8_lpm_get_exit_cause ( uint64_t * out)
nodiscard

Snapshot WUPEN0 / WUPEN1 into a single 64-bit word.

Returns (WUPEN1 << 32) | WUPEN0 – which sources were armed at the moment of the call. Combined with the post-wake NVIC pending mask the application can decide what woke it.

Parameters
[out]outReceives the packed wake-up enable snapshot.
Returns
ra8_err_t error code.
Return values
k_ra8_ok*out populated.
k_ra8_err_null_ptrout was nullptr.
Precondition
out is non-NULL.
ICU bus is clocked.
Postcondition
*out reflects the live WUPEN0 / WUPEN1 values.
No register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 814 of file ra8_lpm.c.

References k_ra8_lpm_cause_shift_wupen0, k_ra8_lpm_cause_shift_wupen1, k_ra8_lpm_wupen0_off, k_ra8_lpm_wupen1_off, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_lpm_icu_reg32(), and s_tag.

Referenced by internal_lpm_wake_arm0(), internal_lpm_wake_arm1(), and internal_lpm_wake_disarm_all().

◆ ra8_lpm_get_opccr()

ra8_err_t ra8_lpm_get_opccr ( uint8_t * opccr)
nodiscard

Read OPCCR raw byte (OPCM[1:0] + OPCMTSF).

Parameters
[out]opccrReceives the live OPCCR byte.
Returns
ra8_err_t error code.
Return values
k_ra8_ok*opccr populated.
k_ra8_err_null_ptropccr was nullptr.
Precondition
opccr is non-NULL.
SYSC bus is clocked.
Postcondition
*opccr reflects the live OPCCR value at the moment of the read.
No register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 706 of file ra8_lpm.c.

References k_ra8_lpm_opccr_off, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_lpm_sysc_reg8(), and s_tag.

◆ ra8_lpm_get_status()

ra8_err_t ra8_lpm_get_status ( uint32_t * out)
nodiscard

Read LPM status (SBYCR | DPSBYCR | LPSCR | SSCR1) packed.

Packs four single-byte registers into a uint32:

Byte Source
[0] SBYCR
[1] DPSBYCR
[2] LPSCR
[3] SSCR1

Useful for telemetry: "what mode are we in, did IOKEEP latch, is fast-return enabled?".

Parameters
[out]outReceives the packed status word.
Returns
ra8_err_t error code.
Return values
k_ra8_ok*out populated.
k_ra8_err_null_ptrout was nullptr.
Precondition
out is non-NULL.
SYSC bus is clocked.
Postcondition
*out reflects the live register values at the moment of the read.
No register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 796 of file ra8_lpm.c.

References k_ra8_lpm_dpsbycr_off, k_ra8_lpm_lpscr_off, k_ra8_lpm_sbycr_off, k_ra8_lpm_sscr1_off, k_ra8_lpm_status_shift_dpsbycr, k_ra8_lpm_status_shift_lpscr, k_ra8_lpm_status_shift_sbycr, k_ra8_lpm_status_shift_sscr1, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_lpm_sysc_reg8(), and s_tag.

◆ ra8_lpm_graphics_power_on()

ra8_err_t ra8_lpm_graphics_power_on ( uint32_t timeout_iters)
nodiscard

Power the graphics domain on (DRW / GLCDC / MIPI DSI+CSI / VIN).

Clears PDCTRGD.PDDE so the graphics power domain leaves its gated reset state, then waits for the controller to report the transition complete. HUM Ch 11.5.1 Table 11.7 p 480 lists the domain contents: MIPI DSI, MIPI CSI, VIN, DRW and GLCDC. HUM Ch 11.2.14 p 452 gives the register a reset value of 0x81PDPGSF = 1 (gated off) and PDDE = 1 (power off) – so every one of those peripherals is unpowered out of reset and cancelling module-stop alone is not enough to make one respond.

This was the whole of issue #247: the D/AVE 2D engine had never rasterised a pixel on real silicon because nothing ever powered its domain. Bench evidence on an EK-RA8D2 – with PDCTRGD at its 0x81 reset value the DRW HWREVISION register reads 0x00000000; after this call it reads 0x0FBE0107.

Sequence (HUM Ch 11.2.14 p 452 + Ch 11.5.1 p 480):

  1. MOCO must already be running – "when using the power gating function, it should be set MOCOCR.MCSTP to 0 (MOCO is operated) in advance". The call starts MOCO itself so the caller cannot forget.
  2. ``PDDE`` may be moved 1 -> 0 only "after confirmed that the PDCSF = 0 and PDPGSF = 1", so both flags are polled first.
  3. Clear PDDE (the register is PRC1-protected, so the write runs inside an RA8_PROTECTED_WRITE window).
  4. Wait for PDCSF = 0 and PDPGSF = 0 – gating finished, the domain is live.

Idempotent: if the domain is already powered (PDPGSF = 0) the function returns k_ra8_ok without touching the register, so several graphics drivers may each call it during their own init.

Parameters
[in]timeout_itersPoll-loop bound for each flag wait; must be non-zero. Bounds the loop for NASA Rule 2.
Returns
ra8_err_t error code.
Return values
k_ra8_okDomain powered and gating complete.
k_ra8_err_invalid_argtimeout_iters was 0.
k_ra8_err_hw_timeoutA status flag never reached its target state within timeout_iters.
Precondition
timeout_iters > 0.
Single-threaded init context (the polls block the CPU).
Postcondition
On success PDCTRGD.PDPGSF == 0 and PDCTRGD.PDCSF == 0.
On success MOCO is running (MOCOCR.MCSTP == 0).
Note
Thread safety: not thread-safe.
Must run before any DRW / GLCDC / MIPI / VIN register access; reads of an unpowered domain return 0 and writes are lost.
Example:
(void)ra8_drw_init(&drw_cfg);
ra8_err_t ra8_drw_init(const ra8_drw_config_t *cfg)
Power on the DRW block, install the supplied configuration, and arm the IRQ control register.
Definition ra8_drw.c:491
@ k_ra8_lpm_pd_timeout_default
Default power-gate poll bound.
Definition ra8_lpm.h:145
ra8_err_t ra8_lpm_graphics_power_on(uint32_t timeout_iters)
Power the graphics domain on (DRW / GLCDC / MIPI DSI+CSI / VIN).
See also
ra8_lpm_set_clock_stop() Starts the MOCO this call depends on
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 2: both poll loops bounded by timeout_iters.
  • Rule 5: 1 precondition check + 2 postcondition polls.

Definition at line 171 of file ra8_lpm_graphics.c.

References internal_graphics_clear_pdde(), internal_graphics_confirm_powered(), internal_graphics_confirm_ready(), internal_graphics_enable_moco(), k_ra8_err_invalid_arg, k_ra8_lpm_pdctr_pdpgsf_mask, k_ra8_lpm_pdctrgd_off, k_ra8_ok, ra8_log_error, ra8_log_info, ra8_lpm_sysc_reg8(), RA8_RETURN_ON_ERROR, and s_tag.

Referenced by ra8_drw_init().

◆ ra8_lpm_init()

ra8_err_t ra8_lpm_init ( const ra8_lpm_config_t * cfg)
nodiscard

Initialise the LPM block from a config descriptor.

Writes SBYCR.OPE, DPSBYCR (IOKEEP + DCSSMODE), and SSCR1 (SS2FR + SS2LP) from cfg. Clears LPSCR.LPMD to System Active so the next plain WFI does an ordinary CPU sleep until the application explicitly arms a deeper mode via ra8_lpm_enter_sleep.

Parameters
[in]cfgNon-NULL configuration descriptor.
Returns
ra8_err_t error code.
Return values
k_ra8_okAll four registers programmed.
k_ra8_err_null_ptrcfg was nullptr.
Precondition
IRQs masked or single-threaded init context.
System has unlocked SYSTEM.PRCR.PRC1 (or call ra8_lpm_prcr_unlock first).
Postcondition
LPSCR.LPMD == 0 (System Active).
DPSBYCR mirrors cfg->io_port_keep and cfg->dcdc_softstart.
Note
Thread safety: not thread-safe.
See also
ra8_lpm_deinit, ra8_lpm_enter_sleep
Since
0.1.0

Definition at line 358 of file ra8_lpm.c.

References ra8_lpm_config_t::dcdc_softstart, ra8_lpm_config_t::io_port_keep, k_ra8_lpm_dpsbycr_dcssmode_shift, k_ra8_lpm_dpsbycr_iokeep_mask, k_ra8_lpm_dpsbycr_off, k_ra8_lpm_lpscr_off, k_ra8_lpm_sbycr_off, k_ra8_lpm_sbycr_ope_mask, k_ra8_lpm_sscr1_off, k_ra8_lpm_sscr1_ss2fr_mask, k_ra8_lpm_sscr1_ss2lp_shift, k_ra8_ok, ra8_lpm_config_t::opa_bus_keep, RA8_CHECK_NULL_PTR, ra8_log_info, ra8_lpm_sysc_reg8(), s_tag, ra8_lpm_config_t::sscr_fast_return, and ra8_lpm_config_t::sscr_low_power.

Referenced by 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(), lpi_setup_or_halt(), m85_lpm_configure(), and pp_demo_modules_or_halt().

◆ ra8_lpm_prcr_relock()

ra8_err_t ra8_lpm_prcr_relock ( void )
nodiscard

Re-lock PRCR.PRC1 after protected writes.

Returns
ra8_err_t error code.
Return values
k_ra8_okPRC1 locked.
Precondition
Earlier ra8_lpm_prcr_unlock succeeded.
IRQs masked or single-threaded context.
Postcondition
PRCR.PRC1 == 0.
Other PRC bits unchanged.
Note
Thread safety: not thread-safe.
See also
ra8_lpm_prcr_unlock
Since
0.1.0

Definition at line 441 of file ra8_lpm.c.

References k_lpm_byte_mask, k_ra8_lpm_prcr_key, k_ra8_lpm_prcr_off, k_ra8_lpm_prcr_prc1_msk, k_ra8_ok, and ra8_lpm_sysc_reg16().

Referenced by m85_gate_hoco(), and m85_lpm_configure().

◆ ra8_lpm_prcr_unlock()

ra8_err_t ra8_lpm_prcr_unlock ( void )
nodiscard

Unlock PRCR.PRC1 to permit writes to LPM control registers.

Writes 0xA502 to SYSTEM.PRCR (key 0xA5 + PRC1=1). The companion ra8_lpm_prcr_relock writes 0xA500 to lock the region again. Pairs with the standby/wake critical section.

Returns
ra8_err_t error code.
Return values
k_ra8_okPRC1 unlocked.
Precondition
IRQs masked or single-threaded context.
Caller has not already nested an unlock.
Postcondition
PRCR.PRC1 == 1.
Other PRC bits unchanged (we only OR in PRC1).
Note
Thread safety: not thread-safe; the unlock/relock pair must be wrapped in the caller's critical section.
See also
ra8_lpm_prcr_relock
Since
0.1.0

Definition at line 430 of file ra8_lpm.c.

References k_lpm_byte_mask, k_ra8_lpm_prcr_key, k_ra8_lpm_prcr_off, k_ra8_lpm_prcr_prc1_msk, k_ra8_ok, and ra8_lpm_sysc_reg16().

Referenced by m85_gate_hoco(), and m85_lpm_configure().

◆ ra8_lpm_set_clock_stop()

ra8_err_t ra8_lpm_set_clock_stop ( ra8_lpm_clock_t clock,
bool stop )
nodiscard

Set or clear the per-oscillator stop bit before sleep entry.

Toggles the STOP bit (bit 0) of the oscillator control register selected by clock – MOSCCR, HOCOCR, MOCOCR, LOCOCR or SOSCCR. Those registers belong to the clock-generation circuit and are PRC0-protected (HUM Ch 13.1 Table 13.1); a write issued while PRC0 is locked is discarded silently by the hardware. The read-modify-write is therefore performed inside a self-contained PRCR CGC unlock window: the caller does not unlock PRCR beforehand, and PRCR is returned to its fully-locked state before return.

Parameters
[in]clockOscillator selector (k_ra8_lpm_clock_*).
[in]stoptrue – request stop; false – request run.
Returns
ra8_err_t error code.
Return values
k_ra8_okStop bit toggled.
k_ra8_err_invalid_argclock out of range.
Precondition
IRQs masked or single-threaded context.
clock selects one of the five oscillator control registers.
Postcondition
On k_ra8_ok, (*OCR & 0x01) reflects stop.
PRCR is left fully locked; no other oscillator has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 661 of file ra8_lpm.c.

References internal_clock_offset(), k_ra8_err_invalid_arg, k_ra8_lpm_clock_count, k_ra8_lpm_clock_stop_mask, k_ra8_ok, k_ra8_prcr_unlock_cgc, ra8_log_error, ra8_lpm_sysc_reg8(), RA8_PROTECTED_WRITE, and s_tag.

Referenced by internal_lus_setup_or_halt(), lpi_setup_or_halt(), and m85_gate_hoco().

◆ ra8_lpm_set_dpsiegr()

ra8_err_t ra8_lpm_set_dpsiegr ( ra8_lpm_dpsier_idx_t idx,
uint8_t value )
nodiscard

Programme DPSIEGR0..2 (deep-standby IRQ edge polarity).

Parameters
[in]idxDPSIEGR selector (0..2 only – DPSIEGR3 not used).
[in]value8-bit edge mask: bit=1 selects rising edge.
Returns
ra8_err_t error code.
Return values
k_ra8_okRegister updated.
k_ra8_err_invalid_argidx out of range.
Precondition
IRQs masked or single-threaded context.
PRCR.PRC1 unlocked.
Postcondition
DPSIEGR[idx] == value.
No other LPM register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 535 of file ra8_lpm.c.

References internal_dpsiegr_offset(), k_ra8_err_invalid_arg, k_ra8_lpm_dpsier_idx_count, k_ra8_ok, ra8_log_error, ra8_lpm_sysc_reg8(), and s_tag.

◆ ra8_lpm_set_ldo_standby()

ra8_err_t ra8_lpm_set_ldo_standby ( const ra8_lpm_ldo_cfg_t * cfg)
nodiscard

Programme PLL1LDOCR / PLL2LDOCR / HOCOLDOCR SKEEP bits.

Parameters
[in]cfgNon-NULL LDO retention configuration.
Returns
ra8_err_t error code.
Return values
k_ra8_okAll three LDOCR bytes updated.
k_ra8_err_null_ptrcfg was nullptr.
k_ra8_err_invalid_stateOPCCR.OPCM != 0 (writes prohibited).
Precondition
OPCCR.OPCM == 0 (High-speed mode) per HUM 11.2.1 p 436.
PRCR.PRC1 unlocked.
Postcondition
PLL1LDOCR.SKEEP / PLL2LDOCR.SKEEP / HOCOLDOCR.SKEEP equal the corresponding cfg->* values.
Other bits in *LDOCR are preserved.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 626 of file ra8_lpm.c.

References ra8_lpm_ldo_cfg_t::hoco, k_ra8_err_invalid_state, k_ra8_lpm_hocoldocr_off, k_ra8_lpm_ldocr_skeep_mask, k_ra8_lpm_ldocr_skeep_shift, k_ra8_lpm_opccr_off, k_ra8_lpm_opccr_opcm_mask, k_ra8_lpm_pll1ldocr_off, k_ra8_lpm_pll2ldocr_off, k_ra8_ok, ra8_lpm_ldo_cfg_t::pll1, ra8_lpm_ldo_cfg_t::pll2, RA8_CHECK_NULL_PTR, ra8_log_error, ra8_lpm_sysc_reg8(), and s_tag.

◆ ra8_lpm_set_ram_retention()

ra8_err_t ra8_lpm_set_ram_retention ( const ra8_lpm_ram_retention_t * cfg)
nodiscard

Programme PDRAMSCR0 / PDRAMSCR1 from a retention descriptor.

Parameters
[in]cfgNon-NULL retention configuration.
Returns
ra8_err_t error code.
Return values
k_ra8_okBoth registers programmed.
k_ra8_err_null_ptrcfg was nullptr.
Precondition
IRQs masked or single-threaded context.
PRCR.PRC1 unlocked.
Postcondition
PDRAMSCR0 == cfg->pdramscr0_bits.
PDRAMSCR1 mirrors cpu0_tcm_keep and cpu1_tcm_keep.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 606 of file ra8_lpm.c.

References ra8_lpm_ram_retention_t::cpu0_tcm_keep, ra8_lpm_ram_retention_t::cpu1_tcm_keep, k_ra8_lpm_pdramscr0_off, k_ra8_lpm_pdramscr0_writable, k_ra8_lpm_pdramscr1_off, k_ra8_lpm_pdramscr1_rkeep0_mask, k_ra8_lpm_pdramscr1_rkeep1_mask, k_ra8_ok, ra8_lpm_ram_retention_t::pdramscr0_bits, RA8_CHECK_NULL_PTR, ra8_lpm_sysc_reg16(), ra8_lpm_sysc_reg8(), and s_tag.

◆ ra8_lpm_set_wakeup_sources()

ra8_err_t ra8_lpm_set_wakeup_sources ( uint32_t wupen0,
uint32_t wupen1 )
nodiscard

Programme the raw WUPEN0 / WUPEN1 masks.

Writes wupen0 to ICU.WUPEN0 and wupen1 to ICU.WUPEN1 verbatim. Use the k_ra8_lpm_wupen0_* / k_ra8_lpm_wupen1_* helper enums to assemble bit patterns.

Parameters
[in]wupen0Mask for WUPEN0 (IRQ0..15 + IWDT/PVD/RTC/USB...).
[in]wupen1Mask for WUPEN1 (ULPT/I3C/SOSC/CMP).
Returns
ra8_err_t error code.
Return values
k_ra8_okMasks written.
Precondition
IRQs masked or caller holds the LPM lock.
Wake-up sources have already been wired in their owning peripheral (e.g. RTC alarm scheduled, IRQ pin configured).
Postcondition
WUPEN0 == wupen0 and WUPEN1 == wupen1.
No other LPM register has been modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 456 of file ra8_lpm.c.

References k_ra8_lpm_wupen0_off, k_ra8_lpm_wupen1_off, k_ra8_ok, and ra8_lpm_icu_reg32().

◆ ra8_lpm_snooze_set_end_sources()

ra8_err_t ra8_lpm_snooze_set_end_sources ( bool ulpt0,
bool ulpt1,
bool usbfs,
bool usbhs )
nodiscard

Configure end-of-snooze sources via DPSIER3 (ULPT/USB hooks).

Mirrors the FSP "snooze end" concept by writing the relevant DPSIER3 bits (DULPT0IE / DULPT1IE / DUSBFSIE / DUSBHSIE) so a subsequent deep-standby entry can be cancelled by the same peripheral that woke it from snooze.

Parameters
[in]ulpt0Set DPSIER3.DULPT0IE.
[in]ulpt1Set DPSIER3.DULPT1IE.
[in]usbfsSet DPSIER3.DUSBFSIE.
[in]usbhsSet DPSIER3.DUSBHSIE.
Returns
ra8_err_t error code.
Return values
k_ra8_okDPSIER3 updated.
Precondition
IRQs masked or single-threaded context.
PRCR.PRC1 unlocked.
Postcondition
DPSIER3 has the requested bits set; non-target bits in DPSIER3 are preserved.
DPSIFR3 cleared to ensure no stale flag carries over.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 575 of file ra8_lpm.c.

References k_ra8_lpm_dpsier3_dulpt0ie_mask, k_ra8_lpm_dpsier3_dulpt1ie_mask, k_ra8_lpm_dpsier3_dusbfsie_mask, k_ra8_lpm_dpsier3_dusbhsie_mask, k_ra8_lpm_dpsier3_off, k_ra8_lpm_dpsifr3_off, k_ra8_ok, and ra8_lpm_sysc_reg8().

◆ ra8_lpm_snooze_set_request_sources()

ra8_err_t ra8_lpm_snooze_set_request_sources ( bool ulpt0_underflow,
bool ulpt1_underflow,
bool acmphs0 )
nodiscard

Configure ULPT-driven snooze request sources.

RA8D2 does not implement the dedicated SNZCR/SNZEDCR/SNZREQCR register block found on older RA Gen-1 parts. Instead, the chip supports a "Software Standby + ULPT wake" pattern where ULPT0 (or ULPT1) periodically wakes the MCU from Software Standby to sample an ADC channel or service an I2C transaction. This helper writes the ULPT-related bits in WUPEN1 to enable that pattern.

Parameters
[in]ulpt0_underflowSet to enable ULPT0 underflow wake.
[in]ulpt1_underflowSet to enable ULPT1 underflow wake.
[in]acmphs0Set to enable ACMPHS0 comparator wake.
Returns
ra8_err_t error code.
Return values
k_ra8_okWUPEN1 updated.
Precondition
Caller has armed the underlying ULPT / ACMPHS peripheral.
IRQs masked or LPM lock held.
Postcondition
WUPEN1 has the requested bits set; other WUPEN1 bits unchanged.
WUPEN0 unchanged.
Note
Thread safety: not thread-safe.
See also
ra8_lpm_snooze_set_end_sources
Since
0.1.0

Definition at line 553 of file ra8_lpm.c.

References k_ra8_lpm_wupen0_acmphs0, k_ra8_lpm_wupen0_off, k_ra8_lpm_wupen1_off, k_ra8_lpm_wupen1_ulpt0u, k_ra8_lpm_wupen1_ulpt1u, k_ra8_ok, and ra8_lpm_icu_reg32().

◆ ra8_lpm_wait_for_opccr()

ra8_err_t ra8_lpm_wait_for_opccr ( uint32_t poll_limit)
nodiscard

Wait for OPCCR.OPCMTSF to clear (mode-transition complete).

Parameters
[in]poll_limitMaximum number of polling iterations.
Returns
ra8_err_t error code.
Return values
k_ra8_okOPCMTSF cleared within budget.
k_ra8_err_hw_timeoutpoll_limit exhausted with OPCMTSF=1.
Precondition
poll_limit > 0.
SYSC bus is clocked.
Postcondition
On success, OPCCR.OPCMTSF == 0.
No register has been modified by this call.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 714 of file ra8_lpm.c.

References k_ra8_err_hw_timeout, k_ra8_err_invalid_arg, k_ra8_lpm_opccr_off, k_ra8_lpm_opccr_opcmtsf_msk, k_ra8_ok, ra8_log_error, ra8_lpm_sysc_reg8(), and s_tag.