|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Ref-counted Module Stop Control wrapper for the RA8D2. More...
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. | |
Ref-counted Module Stop Control wrapper for the RA8D2.
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:
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.
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.
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.
|
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().
| [in] | id | Peripheral identifier from ra8_mstp_t. |
| k_ra8_ok | Gated successfully (or still in use by another caller). |
| k_ra8_err_invalid_arg | id decodes to an out-of-range register or bit position. |
| k_ra8_err_invalid_state | Refcount was already 0 – caller disabled a peripheral they had not enabled. |
| k_ra8_err_hw_timeout | Bit did not read back as set within the spin budget. |
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().
|
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:
| [in] | id | Peripheral identifier from ra8_mstp_t. |
| k_ra8_ok | Ungated successfully (or already on). |
| k_ra8_err_invalid_arg | id decodes to an out-of-range register or bit position. |
| k_ra8_err_hw_timeout | Bit did not read back as cleared within the spin budget. |
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().
|
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.
| [in] | id | Peripheral identifier from ra8_mstp_t. |
| [out] | out_ref | On success, the current ref count value. |
| k_ra8_ok | Ref count returned in *out_ref. |
| k_ra8_err_null_ptr | out_ref was nullptr. |
| k_ra8_err_invalid_arg | id decodes to an out-of-range register or bit position. |
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.
|
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:
After ra8_mstp_init() returns, every subsequent ra8_mstp_enable() is the first request for that module.
| k_ra8_ok | Refcount table reset and hardware confirmed all-stopped. |
| k_ra8_err_hw_timeout | Read-back loop did not observe the expected value within budget. |
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().
|
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.
| [in] | id | Peripheral identifier from ra8_mstp_t. |
| [out] | out_stopped | On success, true if the bit is set. |
| k_ra8_ok | Bit value returned in *out_stopped. |
| k_ra8_err_null_ptr | out_stopped was nullptr. |
| k_ra8_err_invalid_arg | id is out of range. |
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.