|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Internal Voltage Regulator (DCDC / LDO) driver implementation. More...
#include "ra8_vreg.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_log.h"#include "ra8_vreg_regs.h"Go to the source code of this file.
Data Structures | |
| struct | ra8_vreg_state_t |
| Cached "desired" state used by the enter/exit-standby pair. More... | |
Functions | |
| static ra8_err_t | internal_validate_cfg (const ra8_vreg_cfg_t *cfg) |
| Validate every field of a ra8_vreg_cfg_t snapshot. | |
| static uint8_t | internal_lvocr_from_profile (ra8_vreg_lv_profile_t profile) |
| Translate a ra8_vreg_lv_profile_t enum to its LVOCR bit pattern. | |
| static ra8_vreg_lv_profile_t | internal_profile_from_lvocr (uint8_t lvocr) |
| Decode an LVOCR byte back into the profile enum. | |
| static ra8_vreg_ocp_t | internal_ocp_from_dcdcctl (uint8_t dcdcctl) |
| Decode the live DCDCCTL byte into the OCP enum. | |
| static uint8_t | internal_pack_ldo_dcdcctl (const ra8_vreg_cfg_t *cfg) |
| Build the DCDCCTL value for a given config snapshot in LDO mode. | |
| static void | internal_dcdc_enable_sequence (bool fast) |
| Run the FSP-style LDO->DCDC handshake (writes only – caller owns the inter-step delays). | |
| static void | internal_dcdc_disable_sequence (bool keep_lcboost) |
| Switch DCDC -> LDO. | |
| ra8_err_t | ra8_vreg_init (const ra8_vreg_cfg_t *cfg) |
| Initialise the internal voltage regulator from a config descriptor. | |
| ra8_err_t | ra8_vreg_deinit (void) |
| Tear down the regulator – return DCDCCTL/VCCSEL/LVOCR to reset state. | |
| ra8_err_t | ra8_vreg_set_mode (ra8_vreg_mode_t mode) |
| Switch between LDO and DCDC at runtime. | |
| ra8_err_t | ra8_vreg_set_vccsel (ra8_vreg_vccsel_t sel) |
| Set the DCDC supply-voltage-range select. | |
| ra8_err_t | ra8_vreg_set_ocp (ra8_vreg_ocp_t level) |
| Program the DCDC over-current-protection level. | |
| ra8_err_t | ra8_vreg_set_fast_startup (bool enable) |
| Enable / disable the DCDC fast-startup sequence. | |
| ra8_err_t | ra8_vreg_set_ldo_boost (bool enable) |
| Enable / disable the LDO charge-pump boost. | |
| ra8_err_t | ra8_vreg_set_lv_profile (ra8_vreg_lv_profile_t profile) |
| Select a low-voltage operation profile. | |
| ra8_err_t | ra8_vreg_get_status (ra8_vreg_status_t *out) |
| Read the regulator status into a caller-supplied snapshot. | |
| ra8_err_t | ra8_vreg_clear_status (uint8_t mask) |
| Clear the bits in DCDCCTL named by mask. | |
| ra8_err_t | ra8_vreg_reset (void) |
| Reset the regulator to its OFS-byte default state. | |
| ra8_err_t | ra8_vreg_enter_standby (ra8_vreg_standby_t variant) |
| Park the regulator for one of the Software Standby variants. | |
| ra8_err_t | ra8_vreg_enter_stop (void) |
| Legacy alias for ra8_vreg_enter_standby(k_ra8_vreg_standby_software). | |
| ra8_err_t | ra8_vreg_exit_standby (void) |
| Restore the regulator after Software Standby exit. | |
| ra8_err_t | ra8_vreg_exit_stop (void) |
| Legacy alias for ra8_vreg_exit_standby(). | |
| ra8_err_t | ra8_vreg_attach_handler (ra8_vreg_event_fn_t fn, void *ctx) |
| Attach a fault callback (LVD / over-current dispatch hook). | |
| void | ra8_vreg_dispatch (void) |
| Fire the registered fault callback with the current DCDCCTL value. | |
Variables | |
| static const char * | s_tag = "VREG" |
| Logging tag for ra8_log_* calls. | |
| static ra8_vreg_state_t | s_state |
| Cached desired regulator state for standby / restore. | |
| static ra8_vreg_event_fn_t | s_vreg_fn |
| Registered fault callback. | |
| static void * | s_vreg_ctx |
| Context forwarded to the registered callback. | |
Internal Voltage Regulator (DCDC / LDO) driver implementation.
Full HUM Ch 68 coverage for the RA8D2 internal voltage regulator. Implements every documented register field, every operating mode transition (LDO <-> DCDC, with and without fast-startup, with the LDO charge-pump boost engaged), every Software Standby variant (HUM Ch 68.2.2 incompatibility table), the DCDC over-current threshold programming surface, the low-voltage operation profiles (LVOCR.LVO0E / LVO1E), and the diagnostic status snapshot.
The DCDC enable / disable sequences mirror the FSP bsp_power.c reference (see CLAUDE.md for the no-FSP-copy rule). Only the write order is borrowed – every line is hand-authored.
The driver does NOT call ra8_mstp_*: the regulator block is part of the always-on SYSC region and has no module-stop bit.
Definition in file ra8_vreg.c.
|
static |
Switch DCDC -> LDO.
Single-write transition that takes the DCDC offline and stops the IO buffer.
| [in] | keep_lcboost | Preserve DCDCCTL.LCBOOST through the transition. |
See implementation.
Definition at line 331 of file ra8_vreg.c.
References k_ra8_vreg_mask_lcboost, RA8_INTERNAL, and ra8_vreg_dcdcctl().
Referenced by ra8_vreg_enter_standby(), and ra8_vreg_set_mode().
|
static |
Run the FSP-style LDO->DCDC handshake (writes only – caller owns the inter-step delays).
Steps:
If fast is true, steps 3 and 4 are folded into a single write of 0x53 (STOPZA + DCDCON + OCPEN + FST), matching the fast-startup sequence documented in the LPM chapter.
| [in] | fast | True for fast-startup, false for the conservative 5-step handshake. |
Definition at line 280 of file ra8_vreg.c.
References k_ra8_vreg_dcdc_step_dcdc_on, k_ra8_vreg_dcdc_step_fast_on, k_ra8_vreg_dcdc_step_lp_vref, k_ra8_vreg_dcdc_step_with_ocp, k_ra8_vreg_mask_pd, k_ra8_vreg_mask_stopza, RA8_INTERNAL, ra8_vreg_dcdcctl(), and s_state.
Referenced by ra8_vreg_init(), and ra8_vreg_set_mode().
|
static |
Translate a ra8_vreg_lv_profile_t enum to its LVOCR bit pattern.
| [in] | profile | Validated profile enum. |
See implementation.
| k_ra8_ok | Operation succeeded. |
Definition at line 157 of file ra8_vreg.c.
References k_ra8_vreg_lv_p0, k_ra8_vreg_lv_p1, k_ra8_vreg_mask_lvo0e, k_ra8_vreg_mask_lvo1e, and RA8_INTERNAL.
Referenced by ra8_vreg_init(), and ra8_vreg_set_lv_profile().
|
static |
Decode the live DCDCCTL byte into the OCP enum.
| [in] | dcdcctl | Live DCDCCTL register read. |
See implementation.
| k_ra8_ok | Operation succeeded. |
Definition at line 210 of file ra8_vreg.c.
References k_ra8_vreg_mask_ocpen, k_ra8_vreg_ocp_normal, k_ra8_vreg_ocp_off, RA8_INTERNAL, and s_state.
Referenced by ra8_vreg_get_status().
|
static |
Build the DCDCCTL value for a given config snapshot in LDO mode.
Used by ra8_vreg_init only when cfg->mode == k_ra8_vreg_mode_ldo. DCDC mode goes through internal_dcdc_enable_sequence() instead.
| [in] | cfg | Validated configuration descriptor (must be non-NULL). |
| k_ra8_ok | Operation succeeded. |
Definition at line 239 of file ra8_vreg.c.
References ra8_vreg_cfg_t::fast_startup, k_ra8_vreg_mask_fst, k_ra8_vreg_mask_lcboost, k_ra8_vreg_mask_ocpen, k_ra8_vreg_ocp_off, ra8_vreg_cfg_t::ldo_boost, ra8_vreg_cfg_t::ocp, and RA8_INTERNAL.
Referenced by ra8_vreg_init().
|
static |
Decode an LVOCR byte back into the profile enum.
| [in] | lvocr | Live LVOCR register read. |
See implementation.
| k_ra8_ok | Operation succeeded. |
Definition at line 183 of file ra8_vreg.c.
References k_ra8_vreg_lv_off, k_ra8_vreg_lv_p0, k_ra8_vreg_lv_p1, k_ra8_vreg_mask_lvo0e, k_ra8_vreg_mask_lvo1e, k_ra8_vreg_mask_lvo_all, and RA8_INTERNAL.
Referenced by ra8_vreg_get_status().
|
static |
Validate every field of a ra8_vreg_cfg_t snapshot.
| [in] | cfg | Non-NULL config pointer. |
| k_ra8_ok | All fields in range. |
| k_ra8_err_invalid_arg | A field is out of range. |
See implementation.
Definition at line 125 of file ra8_vreg.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_vreg_lv_p1, k_ra8_vreg_mode_dcdc, k_ra8_vreg_ocp_high, k_ra8_vreg_vccsel_3v0_to_3v6, ra8_vreg_cfg_t::lv_profile, ra8_vreg_cfg_t::mode, ra8_vreg_cfg_t::ocp, RA8_INTERNAL, and ra8_vreg_cfg_t::vccsel.
Referenced by ra8_vreg_init().
|
nodiscard |
Attach a fault callback (LVD / over-current dispatch hook).
The callback is invoked synchronously from ra8_vreg_dispatch(). Setting fn = nullptr detaches.
| [in] | fn | Callback or nullptr to clear. |
| [in] | ctx | Context forwarded to the callback. |
| k_ra8_ok | Always. |
Definition at line 657 of file ra8_vreg.c.
References k_ra8_ok, s_vreg_ctx, and s_vreg_fn.
|
nodiscard |
Clear the bits in DCDCCTL named by mask.
Convenience helper for ISR bookkeeping. The caller passes a mask built from k_ra8_vreg_mask_* values; the corresponding bits are cleared in DCDCCTL while the rest are preserved. Any bits outside k_ra8_vreg_mask_dcdcctl_all are rejected with k_ra8_err_invalid_arg.
| [in] | mask | Bit mask of DCDCCTL bits to clear. |
| k_ra8_ok | Success. |
| k_ra8_err_invalid_arg | mask includes reserved bits. |
Definition at line 577 of file ra8_vreg.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_vreg_mask_dcdcctl_all, ra8_vreg_dcdcctl(), and s_state.
|
nodiscard |
Tear down the regulator – return DCDCCTL/VCCSEL/LVOCR to reset state.
Forces the chip back into LDO mode (DCDCCTL = 0) and clears VCCSEL and LVOCR. Safe to call from any state; if the chip was running in DCDC mode it transitions to LDO first.
| k_ra8_ok | Always (no failure path). |
Definition at line 408 of file ra8_vreg.c.
References k_ra8_ok, k_ra8_vreg_lv_off, k_ra8_vreg_ocp_off, k_ra8_vreg_vccsel_2v4_to_2v7, ra8_vreg_dcdcctl(), ra8_vreg_lvocr(), ra8_vreg_vccsel(), and s_state.
Referenced by ra8_vreg_reset().
| void ra8_vreg_dispatch | ( | void | ) |
Fire the registered fault callback with the current DCDCCTL value.
Intended to be called from the LVD / fault-router ISR. Snapshots DCDCCTL (HUM Ch 11 "Voltage Regulator (VREG)", p 581) and forwards the value to the registered callback. No-op when no callback is attached.
Definition at line 664 of file ra8_vreg.c.
References ra8_vreg_dcdcctl(), s_vreg_ctx, and s_vreg_fn.
|
nodiscard |
Park the regulator for one of the Software Standby variants.
Software Standby, Deep Software Standby modes 1/2/3, Battery Backup and Voltage Scaling Control are all incompatible with DCDC mode (HUM Ch 68.2.2 p 4033). The driver:
The actual WFI is the caller's responsibility (see ra8_lpm).
| [in] | variant | Software Standby variant the caller intends to enter. |
| k_ra8_ok | Regulator parked. |
| k_ra8_err_invalid_arg | variant outside the enum. |
Definition at line 610 of file ra8_vreg.c.
References internal_dcdc_disable_sequence(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_vreg_standby_battery_backup, and s_state.
Referenced by ra8_vreg_enter_stop().
|
nodiscard |
Legacy alias for ra8_vreg_enter_standby(k_ra8_vreg_standby_software).
Kept as a thin wrapper because the lower-level LPM driver still calls the older signature. Internally just forwards.
| k_ra8_ok | Always. |
Definition at line 625 of file ra8_vreg.c.
References k_ra8_vreg_standby_software, and ra8_vreg_enter_standby().
|
nodiscard |
Restore the regulator after Software Standby exit.
If the firmware was running in DCDC mode before ra8_vreg_enter_standby, this restores VCCSEL and re-enables DCDC with OCP. Otherwise it leaves the LDO running.
| k_ra8_ok | Success. |
Definition at line 630 of file ra8_vreg.c.
References k_ra8_ok, k_ra8_vreg_vccsel_mask, ra8_vreg_dcdcctl(), ra8_vreg_lvocr(), ra8_vreg_vccsel(), and s_state.
Referenced by ra8_vreg_exit_stop().
|
nodiscard |
Legacy alias for ra8_vreg_exit_standby().
Definition at line 647 of file ra8_vreg.c.
References ra8_vreg_exit_standby().
|
nodiscard |
Read the regulator status into a caller-supplied snapshot.
| [out] | out | Non-NULL receiver for the snapshot. |
| k_ra8_ok | Success. |
| k_ra8_err_null_ptr | out was NULL. |
Definition at line 544 of file ra8_vreg.c.
References ra8_vreg_status_t::dcdc_ready, ra8_vreg_status_t::dcdcctl, ra8_vreg_status_t::fast_startup, internal_ocp_from_dcdcctl(), internal_profile_from_lvocr(), ra8_vreg_status_t::io_buf_on, k_ra8_ok, k_ra8_vreg_mask_dcdcon, k_ra8_vreg_mask_fst, k_ra8_vreg_mask_lcboost, k_ra8_vreg_mask_pd, k_ra8_vreg_mask_stopza, k_ra8_vreg_mode_dcdc, k_ra8_vreg_mode_ldo, k_ra8_vreg_vccsel_mask, ra8_vreg_status_t::ldo_boost, ra8_vreg_status_t::lv_profile, ra8_vreg_status_t::lvocr, ra8_vreg_status_t::mode, ra8_vreg_status_t::ocp, RA8_CHECK_NULL_PTR, ra8_vreg_dcdcctl(), ra8_vreg_lvocr(), ra8_vreg_vccsel(), s_tag, ra8_vreg_status_t::vccsel, and ra8_vreg_status_t::vccsel_dec.
|
nodiscard |
Initialise the internal voltage regulator from a config descriptor.
Programs DCDCCTL / VCCSEL / LVOCR according to cfg. Selecting k_ra8_vreg_mode_dcdc runs the FSP-style four-step DCDC enable sequence (enable IO buffer -> turn on Vref -> low-power Vref -> switch DCDC + LDO off + OCP enable). The transition is purely register writes here; on real silicon the caller must hold the 22 us / 60 us delays prescribed by HUM Ch 68 between steps.
Algorithm:
| [in] | cfg | Non-NULL configuration descriptor. |
| k_ra8_ok | Success. |
| k_ra8_err_null_ptr | cfg was NULL. |
| k_ra8_err_invalid_arg | cfg->vccsel, cfg->ocp or cfg->lv_profile was out of range. |
Definition at line 353 of file ra8_vreg.c.
References ra8_vreg_cfg_t::fast_startup, internal_dcdc_enable_sequence(), internal_lvocr_from_profile(), internal_pack_ldo_dcdcctl(), internal_validate_cfg(), k_ra8_ok, k_ra8_vreg_mode_dcdc, k_ra8_vreg_standby_software, k_ra8_vreg_vccsel_mask, ra8_vreg_cfg_t::ldo_boost, ra8_vreg_cfg_t::lv_profile, ra8_vreg_cfg_t::mode, ra8_vreg_cfg_t::ocp, RA8_CHECK_NULL_PTR, ra8_log_info, ra8_vreg_dcdcctl(), ra8_vreg_lvocr(), ra8_vreg_vccsel(), s_state, s_tag, and ra8_vreg_cfg_t::vccsel.
|
nodiscard |
Reset the regulator to its OFS-byte default state.
Equivalent to ra8_vreg_deinit() followed by clearing the cached "desired" state – useful for restarting after a recoverable fault (LVD trip, watchdog warning) without having to re-derive the full config.
| k_ra8_ok | Always. |
Definition at line 596 of file ra8_vreg.c.
References k_ra8_vreg_standby_software, ra8_vreg_deinit(), and s_state.
|
nodiscard |
Enable / disable the DCDC fast-startup sequence.
When fast-startup is enabled, the LDO->DCDC handshake skips the long Vref soak and uses a single 22 us total transition (vs the default ~32 us). Useful when the firmware needs to leave Software Standby quickly and the analog Vref can be guaranteed stable from the previous run.
| [in] | enable | True to set DCDCCTL.FST, false to clear. |
| k_ra8_ok | Always. |
Definition at line 490 of file ra8_vreg.c.
References k_ra8_ok, k_ra8_vreg_mask_fst, ra8_vreg_dcdcctl(), and s_state.
|
nodiscard |
Enable / disable the LDO charge-pump boost.
The LDO needs the charge-pump boost (DCDCCTL.LCBOOST) when the chip is targeted for Subosc-speed mode – without it the LDO cannot regulate VDD all the way down. FSP enables LCBOOST as part of the "LDO_BOOST" power-mode enum returned by R_BSP_PowerModeSet; this driver exposes it as a standalone toggle so the caller can mix it with arbitrary OPCCR settings.
| [in] | enable | True to set LCBOOST, false to clear. |
| k_ra8_ok | Always. |
Definition at line 507 of file ra8_vreg.c.
References k_ra8_ok, k_ra8_vreg_mask_lcboost, ra8_vreg_dcdcctl(), and s_state.
|
nodiscard |
Select a low-voltage operation profile.
Writes LVOCR to enforce mutual exclusion of LVO0E and LVO1E. Callers that just want full-speed timing pass k_ra8_vreg_lv_off.
| [in] | profile | One of k_ra8_vreg_lv_off / lv_p0 / lv_p1. |
| k_ra8_ok | Success. |
| k_ra8_err_invalid_arg | profile outside the enum. |
Definition at line 523 of file ra8_vreg.c.
References internal_lvocr_from_profile(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_vreg_lv_p1, ra8_vreg_lvocr(), and s_state.
|
nodiscard |
Switch between LDO and DCDC at runtime.
Performs the LDO->DCDC or DCDC->LDO transition. On real silicon the caller must respect the 22 us / 60 us blocking windows; in driver code the writes are issued immediately and the caller supplies the timer.
| [in] | mode | Target regulator mode. |
| k_ra8_ok | Success. |
| k_ra8_err_invalid_arg | mode outside the enum. |
Definition at line 438 of file ra8_vreg.c.
References internal_dcdc_disable_sequence(), internal_dcdc_enable_sequence(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_vreg_mask_lcboost, k_ra8_vreg_mode_dcdc, k_ra8_vreg_mode_ldo, and s_state.
|
nodiscard |
Program the DCDC over-current-protection level.
Sets or clears DCDCCTL.OCPEN according to level. The non-off levels program the same hardware bit today (the silicon only has one OCP threshold) but the driver records the requested level so a future stepping can grow the API without breaking callers.
| [in] | level | OCP level enum. |
| k_ra8_ok | Success. |
| k_ra8_err_invalid_arg | level outside the enum. |
Definition at line 471 of file ra8_vreg.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_vreg_mask_ocpen, k_ra8_vreg_ocp_high, k_ra8_vreg_ocp_off, ra8_vreg_dcdcctl(), and s_state.
|
nodiscard |
Set the DCDC supply-voltage-range select.
VCCSEL is only consulted by the chip in DCDC mode – this driver still permits writing it in any mode so the caller can pre-stage the value before switching modes.
| [in] | sel | One of k_ra8_vreg_vccsel_*. |
| k_ra8_ok | Success. |
| k_ra8_err_invalid_arg | sel is outside the 2-bit field. |
Definition at line 459 of file ra8_vreg.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_vreg_vccsel_3v0_to_3v6, k_ra8_vreg_vccsel_mask, ra8_vreg_vccsel(), and s_state.
|
static |
Cached desired regulator state for standby / restore.
Definition at line 95 of file ra8_vreg.c.
|
static |
Logging tag for ra8_log_* calls.
Definition at line 72 of file ra8_vreg.c.
|
static |
Context forwarded to the registered callback.
Definition at line 101 of file ra8_vreg.c.
Referenced by ra8_vreg_attach_handler(), and ra8_vreg_dispatch().
|
static |
Registered fault callback.
Definition at line 98 of file ra8_vreg.c.
Referenced by ra8_vreg_attach_handler(), and ra8_vreg_dispatch().