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

Ref-counted Module Stop Control wrapper for the RA8D2. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_mstp_regs.h"
Include dependency graph for ra8_mstp.h:

Go to the source code of this file.

Functions

ra8_err_t ra8_mstp_init (void)
 Re-establish the ra8_mstp ref-count table from current hardware state.
ra8_err_t ra8_mstp_enable (ra8_mstp_t id)
 Reference-counted "ungate this peripheral" request.
ra8_err_t ra8_mstp_disable (ra8_mstp_t id)
 Reference-counted "gate this peripheral" request.
ra8_err_t ra8_mstp_get_refcount (ra8_mstp_t id, uint8_t *out_ref)
 Read the current ref count for an MSTP id.
ra8_err_t ra8_mstp_is_stopped (ra8_mstp_t id, bool *out_stopped)
 Read the current MSTP bit value for an id.

Detailed Description

Ref-counted Module Stop Control wrapper for the RA8D2.

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

Public API of the substrate module that owns every write to the RA8D2 MSTPCRA..MSTPCRE registers (HUM Ch 11, sections 11.2.6..11.2.10, pages 443..450).

Drivers must call ra8_mstp_enable() before they touch the peripheral's registers and ra8_mstp_disable() when they tear down. Calls are reference-counted: two unrelated drivers that both depend on the same MSTP bit (DMAC + DTC, RSIP + TRNG, ...) can each request and release independently and the underlying bit only flips when the last user lets go.

Why a ref count when each peripheral is normally owned by one driver? Two cases that the wave plan needs:

  1. Shared MSTP bits: MSTPA22 covers both DMAC0 and DTC0 (HUM 11.2.6 Note 1). The DMAC and DTC drivers will both request that bit, and we cannot disable it until both have released.
  2. Wake-up coordination: the secure-side LPM handler walks every requested module to figure out what should still be running across a software-standby trip. A ref count is the simplest way to remember "is anyone still using this module?".

The bit-twiddling itself respects HUM 11.2.6 Note 2: "When changing the value of this bit, only execute subsequent instructions after reading this bit to check that the value was updated." ra8_mstp_enable() / disable() therefore read the register back after the modify-write and return k_ra8_err_hw_timeout if the read does not see the new value within a small bounded budget.

Threading

Not thread-safe. Call only from single-threaded init or with interrupts masked. The bare-metal v0.x project has no RTOS, so this is satisfied trivially.

Peripheral identifiers

The full list of peripherals lives in ra8_mstp_regs.h as the ra8_mstp_t enum. Each entry packs the (register, bit) pair from the HUM register description into a 16-bit value.

Definition in file ra8_mstp.h.

Function Documentation

◆ ra8_mstp_disable()

ra8_err_t ra8_mstp_disable ( ra8_mstp_t id)
nodiscard

Reference-counted "gate this peripheral" request.

Decrements the ref count for id. If the count transitions 1 -> 0, sets the corresponding MSTP bit so the peripheral stops receiving its clock. If the count was greater than 1, the bit is left cleared (other users are still active).

Honors the same read-back protocol as ra8_mstp_enable().

Parameters
[in]idPeripheral identifier from ra8_mstp_t.
Returns
ra8_err_t error code.
Return values
k_ra8_okGated successfully (or still in use by another caller).
k_ra8_err_invalid_argid decodes to an out-of-range register or bit position.
k_ra8_err_invalid_stateRefcount was already 0 – caller disabled a peripheral they had not enabled.
k_ra8_err_hw_timeoutBit did not read back as set within the spin budget.
Precondition
IRQs masked or single-threaded init context.
Caller previously called ra8_mstp_enable(id).
Postcondition
On success, ref count is decremented by 1.
If ref count reached 0, the peripheral is gated.
Warning
HUM 11.2.6 Note 1: when releasing k_ra8_mstp_dmac0_dtc0 or k_ra8_mstp_dmac1_dtc1 (the shared DMAC/DTC bits), the caller must first stop every channel of both DMAC and DTC. ra8_mstp does not enforce this; the substrate driver libs/ra8_hal/src/ra8_dma.c is responsible.
Note
Thread safety: not thread-safe.
See also
ra8_mstp_enable
ra8_mstp_get_refcount
Since
0.1.0

Definition at line 382 of file ra8_mstp.c.

References internal_decode(), internal_reg_ptr(), internal_wait_readback(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, ra8_log_error_val, s_refcount, and s_tag.

Referenced by internal_agt_mstp_release(), ra8_acmphs_channel_deinit(), ra8_acmphs_enter_stop(), ra8_adc_deinit(), ra8_adc_enter_stop(), ra8_cac_deinit(), ra8_cac_enter_stop(), ra8_canfd_enter_stop(), ra8_ceu_deinit(), ra8_ceu_enter_stop(), ra8_cnecc_deinit(), ra8_crc_deinit(), ra8_crc_enter_stop(), ra8_dac_b_deinit(), ra8_dac_b_enter_stop(), ra8_dma_deinit(), ra8_dmac_stop(), ra8_dotf_deinit(), ra8_dotf_enter_stop(), ra8_drw_deinit(), ra8_drw_enter_stop(), ra8_dtc_deinit(), ra8_dtc_enter_stop(), ra8_elc_deinit(), ra8_eth_close(), ra8_eth_coma_deinit(), ra8_eth_coma_enter_stop(), ra8_eth_deinit(), ra8_eth_enter_stop(), ra8_eth_gptp_deinit(), ra8_eth_gptp_enter_stop(), ra8_eth_gwca_deinit(), ra8_eth_gwca_enter_stop(), ra8_eth_mfwd_deinit(), ra8_eth_mfwd_enter_stop(), ra8_glcdc_deinit(), ra8_glcdc_enter_stop(), ra8_gpt_deinit(), ra8_gpt_enter_stop(), ra8_i2c_deinit(), ra8_i3c_deinit(), ra8_i3c_enter_stop(), ra8_i3c_i2c_deinit(), ra8_i3c_i2c_peripheral_close(), ra8_mipi_csi_deinit(), ra8_mipi_csi_enter_stop(), ra8_mipi_dsi_deinit(), ra8_mipi_dsi_enter_stop(), ra8_pdg_deinit(), ra8_pdm_deinit(), ra8_poeg_deinit(), ra8_poeg_enter_stop(), ra8_pwr_module_release(), ra8_rsip_deinit(), ra8_rsip_enter_stop(), ra8_rsip_exit_stop(), ra8_rsip_init(), ra8_sci_deinit(), ra8_sci_enter_stop(), ra8_sci_spi_deinit(), ra8_sdhi_deinit(), ra8_sdhi_enter_stop(), ra8_spi_deinit(), ra8_spi_enter_stop(), ra8_sram_deinit(), ra8_sram_enter_stop(), ra8_ssie_deinit(), ra8_ssie_enter_stop(), ra8_tsn_deinit(), ra8_tsn_enter_stop(), ra8_ulpt_deinit(), ra8_ulpt_enter_stop(), ra8_usb_device_deinit(), ra8_usb_enter_stop(), ra8_usb_host_deinit(), ra8_vin_deinit(), ra8_vin_enter_stop(), ra8_xspi_deinit(), and ra8_xspi_enter_stop().

◆ ra8_mstp_enable()

ra8_err_t ra8_mstp_enable ( ra8_mstp_t id)
nodiscard

Reference-counted "ungate this peripheral" request.

Increments the ref count for id. If the count transitions 0 -> 1, clears the corresponding MSTP bit so the peripheral starts receiving its clock. If the count was already non-zero, the bit is left as-is (someone else is already using the module) and the function returns success without touching hardware.

Implements the read-back protocol from HUM 11.2.6 Note 2: after the bit-clear, the register is read repeatedly until the cleared bit is observed or the polling budget runs out.

Algorithm:

  1. Validate id: register index must be 0..4, bit must be 0..31.
  2. Increment ref count.
  3. If ref count was 0 before increment: a. Read MSTPCRx, clear the target bit, write back. b. Poll the same bit until it reads as 0 or the polling budget expires.
  4. Return.
Parameters
[in]idPeripheral identifier from ra8_mstp_t.
Returns
ra8_err_t error code.
Return values
k_ra8_okUngated successfully (or already on).
k_ra8_err_invalid_argid decodes to an out-of-range register or bit position.
k_ra8_err_hw_timeoutBit did not read back as cleared within the spin budget.
Precondition
IRQs masked or single-threaded init context.
ra8_mstp_init() has run (or this is the first request against a fresh ref-count table).
Postcondition
On success, the peripheral is clocked and the ref count for id is at least 1.
HUM 11.2.6 Note 2 read-back has been observed.
Note
Thread safety: not thread-safe.
For shared bits (DMAC + DTC, OSPI + DOTF, ...) every user must call this function for the count to balance correctly.
}
@ k_ra8_err_hw_init_failed
Hardware peripheral failed to initialise.
Definition ra8_err.h:290
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_t ra8_mstp_enable(ra8_mstp_t id)
Reference-counted "ungate this peripheral" request.
Definition ra8_mstp.c:343
@ k_ra8_mstp_sci0
MSTPB31 SCI0.
See also
ra8_mstp_disable
ra8_mstp_get_refcount
Since
0.1.0
NASA Power of 10 Compliance:
  • Rule 5: 2 preconditions, 2 postconditions
  • Rule 7: returns ra8_err_t, marked [[nodiscard]]

Definition at line 343 of file ra8_mstp.c.

References internal_decode(), internal_reg_ptr(), internal_wait_readback(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, ra8_log_error_val, s_refcount, and s_tag.

Referenced by ehb_run_once(), internal_agt_mstp_acquire(), internal_apply_instance(), internal_i3c_i2c_block_bringup(), internal_open_prep(), internal_reset_channel(), internal_ssie_power_up(), internal_usbhs_clock_and_mstp(), internal_validate_and_ungate(), priv_ra8_board_eth_eswm_bring_up(), ra8_acmphs_channel_init(), ra8_acmphs_exit_stop(), ra8_adc_exit_stop(), ra8_adc_init(), ra8_adc_init_configured(), ra8_cac_exit_stop(), ra8_cac_init(), ra8_canfd_exit_stop(), ra8_canfd_init(), ra8_ceu_exit_stop(), ra8_ceu_init(), ra8_cgc_eswclk_init(), ra8_crc_exit_stop(), ra8_crc_init(), ra8_dac_b_exit_stop(), ra8_dac_b_init(), ra8_dac_b_init_configured(), ra8_dma_init(), ra8_dmac_start(), ra8_doc_init(), ra8_dotf_exit_stop(), ra8_dotf_init(), ra8_drw_exit_stop(), ra8_drw_init(), ra8_dtc_exit_stop(), ra8_dtc_init(), ra8_elc_init(), ra8_eth_coma_exit_stop(), ra8_eth_coma_init(), ra8_eth_exit_stop(), ra8_eth_gptp_exit_stop(), ra8_eth_gptp_init(), ra8_eth_gwca_exit_stop(), ra8_eth_gwca_init(), ra8_eth_init(), ra8_eth_mfwd_exit_stop(), ra8_eth_mfwd_init(), ra8_etha_init(), ra8_glcdc_exit_stop(), ra8_glcdc_init(), ra8_gpt_exit_stop(), ra8_gpt_init(), ra8_gpt_start_free_run(), ra8_i2c_init(), ra8_i3c_exit_stop(), ra8_i3c_i2c_peripheral_open(), ra8_i3c_init(), ra8_mipi_csi_exit_stop(), ra8_mipi_csi_init(), ra8_mipi_dsi_exit_stop(), ra8_mipi_dsi_init(), ra8_pdg_init(), ra8_pdm_init(), ra8_poeg_exit_stop(), ra8_poeg_init(), ra8_pwr_module_request(), ra8_rmac_init(), ra8_rsip_exit_stop(), ra8_rsip_init(), ra8_sci_exit_stop(), ra8_sci_init(), ra8_sci_spi_init(), ra8_sdhi_exit_stop(), ra8_sdhi_init(), ra8_spi_b_target_init(), ra8_spi_exit_stop(), ra8_spi_init(), ra8_sram_exit_stop(), ra8_ssie_exit_stop(), ra8_tsn_exit_stop(), ra8_tsn_init(), ra8_ulpt_exit_stop(), ra8_ulpt_init(), ra8_usb_device_init(), ra8_usb_exit_stop(), ra8_usb_host_init(), ra8_vin_exit_stop(), ra8_vin_init(), ra8_xspi_exit_stop(), and ra8_xspi_init().

◆ ra8_mstp_get_refcount()

ra8_err_t ra8_mstp_get_refcount ( ra8_mstp_t id,
uint8_t * out_ref )
nodiscard

Read the current ref count for an MSTP id.

Diagnostic accessor. Used by unit tests to verify that ra8_mstp_enable() / disable() pairs balance correctly. Should not appear on hot paths – production code should not need to branch on the ref count.

Parameters
[in]idPeripheral identifier from ra8_mstp_t.
[out]out_refOn success, the current ref count value.
Returns
ra8_err_t error code.
Return values
k_ra8_okRef count returned in *out_ref.
k_ra8_err_null_ptrout_ref was nullptr.
k_ra8_err_invalid_argid decodes to an out-of-range register or bit position.
Precondition
out_ref is non-NULL.
id is a value from ra8_mstp_t.
Postcondition
On success, *out_ref holds the live ref count.
No hardware state is modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 420 of file ra8_mstp.c.

References internal_decode(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, s_refcount, and s_tag.

◆ ra8_mstp_init()

ra8_err_t ra8_mstp_init ( void )
nodiscard

Re-establish the ra8_mstp ref-count table from current hardware state.

After a cold reset every MSTP bit is 1 (peripheral stopped) and every ref-count is 0. After a warm reset or a NS->S transition, the table may be out of sync with hardware and the caller wants to start clean.

Calling this function:

  1. Sets every ref count back to 0.
  2. Writes 0xFFFFFFFF to every MSTPCR (everything stopped).
  3. Reads each register back to confirm the write took effect.

After ra8_mstp_init() returns, every subsequent ra8_mstp_enable() is the first request for that module.

Returns
ra8_err_t error code.
Return values
k_ra8_okRefcount table reset and hardware confirmed all-stopped.
k_ra8_err_hw_timeoutRead-back loop did not observe the expected value within budget.
Precondition
Caller holds single-threaded init context (no concurrent driver init in progress).
IRQs masked while this function runs.
Postcondition
Every ra8_mstp_t id reports ref-count 0.
Every MSTPCR register reads back as 0xFFFFFFFF.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 291 of file ra8_mstp.c.

References internal_reg_ptr(), k_ra8_err_hw_timeout, k_ra8_mstp_all_stopped, k_ra8_mstp_bit_count, k_ra8_mstp_reg_count, k_ra8_mstp_safe_stopped_a, k_ra8_ok, priv_ra8_mstp_ns_mask_internal(), priv_ra8_mstp_wait_reg_settle_internal(), ra8_log_error_val, ra8_log_info, s_refcount, and s_tag.

Referenced by adc_diag_setup_or_halt(), al_setup_or_halt(), app_bringup_clocks(), bm_setup_or_halt(), bs_setup_or_halt(), c6_fwver_setup_or_halt(), c6_hosted_setup_or_halt(), c6_join_setup_or_halt(), c6_probe_clocks_or_halt(), c6_wifi_setup_or_halt(), cam_bringup(), ch_setup_or_halt(), cm_bringup_clocks(), combo_clocks_or_halt(), demo_setup_or_halt(), drw_blend_setup_or_halt(), drw_demo_setup_or_halt(), dtc_arm_setup_or_halt(), dtc_coh_setup_or_halt(), dtc_demo_setup_or_halt(), ec_setup_or_halt(), ef_setup_or_halt(), ehb_setup_or_halt(), eop_setup_or_halt(), ep_bringup_core(), ep_setup_or_halt(), erb_setup_or_halt(), es_setup_or_halt(), est_setup_or_halt(), ez_bringup_clocks(), fc_setup_or_halt(), gh_setup_or_halt(), gpt_ecc_clocks_or_halt(), gptp_setup_or_halt(), i3c_demo_clocks_or_halt(), iic_setup_or_halt(), imu_demo_clocks_or_halt(), internal_bkup_demo_setup_or_halt(), internal_c6_cam_setup_or_halt(), internal_clocks_or_halt(), internal_clocks_or_halt(), internal_dotf_demo_setup_or_halt(), internal_eth_loopback_setup_or_halt(), internal_lcd_bringup_clocks(), internal_lvd_demo_setup_or_halt(), internal_mecc_setup_or_halt(), internal_motor_3phase_init_clocks_and_led(), internal_pdg_demo_setup_or_halt(), internal_poeg_demo_setup_or_halt(), internal_rc_setup_or_halt(), internal_setup_or_halt(), internal_ssie_loop_setup_or_halt(), internal_tc_setup_or_halt(), internal_td_setup_or_halt(), iu_setup_or_halt(), iv_setup_or_halt(), kb_setup_or_halt(), l3_setup_or_halt(), lcd_bringup_clocks(), lk_setup_or_halt(), mem_setup_or_halt(), mg_bringup_clocks(), modem_clocks_or_halt(), pdm_demo_clocks_or_halt(), pp_demo_clocks_or_halt(), ra8_nsc_periph_init(), ra8_pwr_init(), riic_target_clocks_or_halt(), sbns_console_bringup(), scb_demo_setup_or_halt(), sd_setup_or_halt(), sdram_demo_setup_or_halt(), sfr_bringup_clocks(), sh_setup_or_halt(), tb_setup_or_halt(), timer_demo_setup_or_halt(), tsn_setup_or_halt(), wa_setup_or_halt(), wc_setup_or_halt(), wd_setup_or_halt(), webp_demo_setup_or_halt(), wifi_hal_setup_or_halt(), and wk_setup_or_halt().

◆ ra8_mstp_is_stopped()

ra8_err_t ra8_mstp_is_stopped ( ra8_mstp_t id,
bool * out_stopped )
nodiscard

Read the current MSTP bit value for an id.

Diagnostic accessor. Returns true if the peripheral is currently STOPPED (bit set), false if it is RUNNING (bit clear). Mostly used by tests; production code should track its own state via ra8_mstp_get_refcount() or simply call ra8_mstp_enable() again.

Parameters
[in]idPeripheral identifier from ra8_mstp_t.
[out]out_stoppedOn success, true if the bit is set.
Returns
ra8_err_t error code.
Return values
k_ra8_okBit value returned in *out_stopped.
k_ra8_err_null_ptrout_stopped was nullptr.
k_ra8_err_invalid_argid is out of range.
Precondition
out_stopped is non-NULL.
id is a value from ra8_mstp_t.
Postcondition
On success, *out_stopped reflects the live bit value.
No hardware state is modified.
Note
Thread safety: not thread-safe.
Since
0.1.0

Definition at line 432 of file ra8_mstp.c.

References internal_decode(), internal_reg_ptr(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.