ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_pwr.c
Go to the documentation of this file.
1
25
26#include "ra8_pwr.h"
27
28#include <stdint.h>
29
30#include "ra8_attributes.h"
31#include "ra8_cgc.h"
32#include "ra8_check.h"
33#include "ra8_err.h"
34#include "ra8_hw_intrinsics.h"
35#include "ra8_log.h"
36#include "ra8_lpm_regs.h"
37#include "ra8_mstp.h"
38#include "ra8_mstp_regs.h"
39#include "ra8_system_regs.h"
40
41/* =============================================================================
42 * Local constants
43 * =============================================================================
44 */
45
46static const char* s_tag = "PWR";
47
49typedef enum : uint16_t {
52
57typedef enum : uint8_t {
61
62/* =============================================================================
63 * Internal helpers
64 * =============================================================================
65 */
66
74RA8_INTERNAL static volatile uint32_t* internal_wupen_ptr(uint8_t reg)
75{
76 const uintptr_t base = k_ra8_system_base_addr;
77 if (reg == 0U) {
78 return (volatile uint32_t*)(base + (uintptr_t)k_ra8_lpm_wupen0_off);
79 }
80 return (volatile uint32_t*)(base + (uintptr_t)k_ra8_lpm_wupen1_off);
81}
82
100RA8_INTERNAL static bool
101internal_decode_wake(ra8_pwr_wake_t source, uint8_t* out_reg, uint8_t* out_bit)
102{
103 const uint8_t reg = (uint8_t)(((uint16_t)source >> 8) & k_pwr_byte_mask);
104 const uint8_t bit = (uint8_t)((uint16_t)source & k_pwr_byte_mask);
105 if (reg >= k_ra8_pwr_wupen_count) {
106 return false;
107 }
108 if (bit >= k_ra8_pwr_wupen_bits) {
109 return false;
110 }
111 *out_reg = reg;
112 *out_bit = bit;
113 return true;
114}
115
131RA8_INTERNAL static inline void internal_wfi(void)
132{
133 ra8_hw_wfi();
134}
135
136/* =============================================================================
137 * Public API
138 * =============================================================================
139 */
140
142{
143 ra8_log_info(s_tag, "ra8_pwr_init");
144
145 const ra8_err_t mst_err = ra8_mstp_init();
146 if (mst_err != k_ra8_ok) {
147 ra8_log_error_val(s_tag, "mstp init failed", (uint32_t)mst_err);
148 return mst_err;
149 }
150
151 /* HUM Ch 14.2.19 "WUPEN0 : Wake Up Interrupt Enable Register 0", p 550 */
152 *internal_wupen_ptr(0U) = 0U;
153 /* HUM Ch 14.2.20 "WUPEN1 : Wake Up Interrupt Enable Register 1", p 552 */
154 *internal_wupen_ptr(1U) = 0U;
155 return k_ra8_ok;
156}
157
162
167
169{
170 uint8_t reg = 0U;
171 uint8_t bit = 0U;
172 if (!internal_decode_wake(source, &reg, &bit)) {
173 ra8_log_error_val(s_tag, "set_wake: invalid source", (uint32_t)source);
175 }
176 /* HUM Ch 14.2.19 "WUPEN0 : Wake Up Interrupt Enable Register 0", p 550 */
177 volatile uint32_t* p = internal_wupen_ptr(reg);
178 const uint32_t mask = (uint32_t)1U << bit;
179 *p = *p | mask;
180 return k_ra8_ok;
181}
182
184{
185 uint8_t reg = 0U;
186 uint8_t bit = 0U;
187 if (!internal_decode_wake(source, &reg, &bit)) {
188 ra8_log_error_val(s_tag, "clear_wake: invalid source", (uint32_t)source);
190 }
191 /* HUM Ch 14.2.19 "WUPEN0 : Wake Up Interrupt Enable Register 0", p 550 */
192 volatile uint32_t* p = internal_wupen_ptr(reg);
193 const uint32_t mask = (uint32_t)1U << bit;
194 *p = *p & ~mask;
195 return k_ra8_ok;
196}
197
199{
200 RA8_CHECK_NULL_PTR(out_enabled, s_tag, "wake_source_is_enabled: out_enabled");
201 uint8_t reg = 0U;
202 uint8_t bit = 0U;
203 if (!internal_decode_wake(source, &reg, &bit)) {
205 }
206 volatile const uint32_t* p = internal_wupen_ptr(reg);
207 const uint32_t mask = (uint32_t)1U << bit;
208 *out_enabled = ((*p & mask) != 0U);
209 return k_ra8_ok;
210}
211
213{
214 internal_wfi();
215}
216
218{
219 /* Validate at least one wake source is armed -- entering Software
220 * Standby with WUPEN0 == WUPEN1 == 0 wedges the chip. */
221 /* HUM Ch 14.2.19 "WUPEN0", p 550 */
222 const uint32_t wupen0 = *internal_wupen_ptr(0U);
223 /* HUM Ch 14.2.20 "WUPEN1", p 552 */
224 const uint32_t wupen1 = *internal_wupen_ptr(1U);
225 if ((wupen0 == 0U) && (wupen1 == 0U)) {
226 ra8_log_error(s_tag, "software_standby with no wake source armed");
228 }
229
230 /* The full LPMD + SLEEPDEEP + SBYCR sequence is implemented in
231 * along with the RTC alarm bring-up. For the
232 * helper just issues WFI; the chip stays in normal sleep until
233 * the wake source fires. This keeps the host build a no-op and
234 * lets driver code that calls this function compile and link
235 * cleanly. */
236 internal_wfi();
237 return k_ra8_ok;
238}
239
241{
242 return ra8_cgc_get_clock_hz(id, out_hz);
243}
static const char * s_tag
Logging / check tag.
Definition ra8_app.c:17
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
High-level Clock Generation Circuit driver.
ra8_err_t ra8_cgc_get_clock_hz(ra8_clock_id_t id, uint32_t *out_hz)
Query the current frequency of a clock-tree domain.
Definition ra8_cgc.c:132
ra8_clock_id_t
Identifiers for the clock-tree frequencies queryable at runtime.
Definition ra8_cgc.h:69
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Shared CPU-intrinsic seam for the HAL drivers (host/target split).
static void ra8_hw_wfi(void)
Wait For Interrupt: place the core in low-power wait.
Lightweight Logging Interface for ra8-firmware.
#define ra8_log_error_val(tag, message, value)
RA8 log error val.
Definition ra8_log.h:337
#define ra8_log_info(tag, message)
RA8 log info.
Definition ra8_log.h:364
#define ra8_log_error(tag, message)
RA8 log error.
Definition ra8_log.h:335
Low Power Mode (LPM) register layout for the Renesas RA8D2.
@ k_ra8_lpm_wupen0_off
WUPEN0 (32b) – HUM Ch 14.2.19 p 550.
@ k_ra8_lpm_wupen1_off
WUPEN1 (32b) – HUM Ch 14.2.20 p 552.
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
Definition ra8_mstp.c:343
ra8_err_t ra8_mstp_init(void)
Re-establish the ra8_mstp ref-count table from current hardware state.
Definition ra8_mstp.c:291
ra8_err_t ra8_mstp_disable(ra8_mstp_t id)
Reference-counted "gate this peripheral" request.
Definition ra8_mstp.c:382
Module Stop Control (MSTP) register layout for the Renesas RA8D2.
ra8_mstp_t
Packed (reg << 8) | bit module-stop identifier.
ra8_err_t ra8_pwr_module_request(ra8_mstp_t id)
Ask for a peripheral's clock to be enabled.
Definition ra8_pwr.c:158
ra8_pwr_dim_t
WUPEN address-decode bounds.
Definition ra8_pwr.c:57
@ k_ra8_pwr_wupen_bits
32 bits per register.
Definition ra8_pwr.c:59
@ k_ra8_pwr_wupen_count
WUPEN0 + WUPEN1.
Definition ra8_pwr.c:58
static void internal_wfi(void)
WFI wrapper.
Definition ra8_pwr.c:131
void ra8_pwr_enter_sleep(void)
Enter CPU sleep mode (peripherals continue running).
Definition ra8_pwr.c:212
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.
Definition ra8_pwr.c:101
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.
Definition ra8_pwr.c:198
ra8_err_t ra8_pwr_init(void)
Initialise the LPM substrate.
Definition ra8_pwr.c:141
ra8_err_t ra8_pwr_enter_software_standby(void)
Enter Software Standby mode.
Definition ra8_pwr.c:217
ra8_err_t ra8_pwr_module_release(ra8_mstp_t id)
Release a previously-requested peripheral.
Definition ra8_pwr.c:163
static volatile uint32_t * internal_wupen_ptr(uint8_t reg)
Pointer to one of the 32-bit WUPEN registers.
Definition ra8_pwr.c:74
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.
Definition ra8_pwr.c:240
pwr_mask_t
Low-byte mask for register/bit decomposition.
Definition ra8_pwr.c:49
@ k_pwr_byte_mask
Pwr byte mask.
Definition ra8_pwr.c:50
ra8_err_t ra8_pwr_set_wake_source(ra8_pwr_wake_t source)
Enable an LPM wake source.
Definition ra8_pwr.c:168
ra8_err_t ra8_pwr_clear_wake_source(ra8_pwr_wake_t source)
Disable an LPM wake source.
Definition ra8_pwr.c:183
Low Power Mode + clock-domain wrapper.
ra8_pwr_wake_t
Packed (WUPEN register, bit) wake-source identifier.
Definition ra8_pwr.h:83
System Control (SYSC) register layout for the Renesas RA8D2.
@ k_ra8_system_base_addr
R_SYSTEM.