|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
High-level Clock Generation Circuit driver. More...
Go to the source code of this file.
Typedefs | |
| typedef void(* | ra8_cgc_ostd_fn_t) (void *ctx) |
| Oscillation-stop-detection callback. | |
Enumerations | |
| enum | ra8_clock_id_t : uint8_t { k_ra8_clock_id_cpuclk0 = 0U , k_ra8_clock_id_cpuclk1 = 1U , k_ra8_clock_id_iclk = 2U , k_ra8_clock_id_pclka = 3U , k_ra8_clock_id_pclkb = 4U , k_ra8_clock_id_pclkc = 5U , k_ra8_clock_id_pclkd = 6U , k_ra8_clock_id_pclke = 7U , k_ra8_clock_id_fclk = 8U , k_ra8_clock_id_mriclk = 9U } |
| Identifiers for the clock-tree frequencies queryable at runtime. More... | |
Functions | |
| ra8_err_t | ra8_cgc_init (void) |
| Configure the clock tree to a safe default. | |
| ra8_err_t | ra8_cgc_use_hoco (void) |
| Switch the system clock source to HOCO (20 MHz). | |
| 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. | |
| ra8_err_t | ra8_cgc_switch_pll1_target (uint32_t new_cpuclk_hz) |
| Retune PLL1 to a new CPUCLK0 target without a full deinit. | |
| ra8_err_t | ra8_cgc_enable_stop_detection (ra8_cgc_ostd_fn_t handler, void *ctx) |
| Enable oscillation-stop detection on the main crystal. | |
| ra8_err_t | ra8_cgc_disable_stop_detection (void) |
| Disable oscillation-stop detection. | |
| ra8_err_t | ra8_cgc_usbhs_pll_enable (void) |
| Bring up the USBHS PHY reference clock + module clock. | |
| ra8_err_t | ra8_cgc_eswclk_init (void) |
| Bring up the Ethernet Switch Module (ESWM / RMAC) clock. | |
| ra8_err_t | ra8_cgc_eswclk_hz (uint32_t *out_hz) |
| Query the current ESWCLK (Ethernet Switch clock) frequency. | |
| ra8_err_t | ra8_cgc_pll2_enable (uint8_t mul_int, uint8_t mul_quarters, ra8_plodiv_t p_div_code) |
| Bring up PLL2 with caller-supplied multiplier and P divider. | |
| ra8_err_t | ra8_cgc_usbfs_clock_enable (void) |
| Bring up the USB-FS module clock (USBCKCR / USBCKDIVCR). | |
| void | ra8_cgc_fake_trigger_stop_detection (void) |
| Test helper: invoke the registered OSTD callback. | |
High-level Clock Generation Circuit driver.
Minimal clock-init surface for bring-up. The RA8D2 defaults to MOCO (~8 MHz) out of reset, which is enough to blink an LED and exercise the IOPORT block without touching CGC at all. Use the helpers here to move up to HOCO (20 MHz) or the full PLL1 path (CPUCLK0 up to 1 GHz) as the firmware grows.
Definition in file ra8_cgc.h.
| typedef void(* ra8_cgc_ostd_fn_t) (void *ctx) |
| enum ra8_clock_id_t : uint8_t |
Identifiers for the clock-tree frequencies queryable at runtime.
|
nodiscard |
Disable oscillation-stop detection.
| k_ra8_ok | Detector disabled. |
Definition at line 874 of file ra8_cgc.c.
References k_ra8_ok, ra8_log_info, s_ostd_ctx, s_ostd_enabled, s_ostd_handler, and s_tag.
|
nodiscard |
Enable oscillation-stop detection on the main crystal.
Programmes OSTDCR to enable the OST detector and installs a callback that fires when the OSTDSR flag is set (oscillator has stopped unexpectedly). The callback runs from the CGC interrupt handler after the driver clears the latched flag.
| [in] | handler | Callback invoked on oscillation-stop event. Must not be NULL. |
| [in] | ctx | Stored context passed to the callback. |
| k_ra8_ok | Detector armed. |
| k_ra8_err_null_ptr | handler was NULL. |
Definition at line 857 of file ra8_cgc.c.
References k_ra8_err_null_ptr, k_ra8_ok, ra8_log_info, s_ostd_ctx, s_ostd_enabled, s_ostd_handler, and s_tag.
|
nodiscard |
Query the current ESWCLK (Ethernet Switch clock) frequency.
Computed from the most recent ra8_cgc_eswclk_init call. Returns 0 if the ESWCLK has not been configured. Used by ra8_rmac_init (callers fill ra8_rmac_config_t.eswclk_hz from this value) to compute the MPIC.PSMCS divider code.
| [out] | out_hz | On success, the live ESWCLK frequency in Hz. |
| k_ra8_ok | ESWCLK frequency written to *out_hz. |
| k_ra8_err_null_ptr | out_hz is nullptr. |
Definition at line 336 of file ra8_cgc_eswclk.c.
References k_ra8_err_null_ptr, k_ra8_ok, and s_eswclk_hz.
Referenced by gptp_arm(), priv_ra8_board_eth_eswm_bring_up(), and tsn_arm_time_base().
|
nodiscard |
Bring up the Ethernet Switch Module (ESWM / RMAC) clock.
On RA8D2 the RMAC PHY-station-management hardware (MPSM/MPIC) is fed by ESWCLK, a dedicated peripheral clock with its own source- select (ESWCKCR) and divider (ESWCKDIVCR) registers. After power-on reset ESWCKCR reads as 0 (ESWCKSEL = HOCO ~20 MHz) which is fine for MDC but the source-select handshake (CKSREQ -> CKSRDY) must still be exercised for the divider write to take effect. Symptom on a chip where this routine has not run: ra8_rmac_mdio_c22_read returns k_ra8_err_hw_timeout for every PHY address even though the wire is physically connected and the PHY is out of reset.
Sequence per FSP bsp_peripheral_clock_set and the HUM Ch 9 "Clock selection switching procedure":
This implementation picks PLL1P / 8 = 125 MHz as the ESWCLK source, matching what every FSP example for the EK-RA8D2 ships with. The resulting 125 MHz fans out to:
The same eswclk_hz value is what the caller passes via ra8_rmac_config_t::eswclk_hz so internal_calc_psmcs can compute the right MPIC.PSMCS divider code.
| k_ra8_ok | ESWCLK selected and running. |
| k_ra8_err_hw_timeout | CKSRDY handshake never completed. |
Definition at line 303 of file ra8_cgc_eswclk.c.
References internal_eswclk_power_on_domain(), internal_eswclk_program_cks(), k_ra8_cgc_eswclk_target_hz, k_ra8_mstp_ethphyclk, k_ra8_ok, priv_ra8_cgc_ensure_hoco_running_for_usb_ck(), ra8_log_error, ra8_log_info, ra8_mstp_enable(), s_eswclk_hz, and s_tag.
Referenced by ehb_run_once(), gptp_setup_or_halt(), priv_ra8_board_eth_eswm_bring_up(), and tsn_setup_or_halt().
| void ra8_cgc_fake_trigger_stop_detection | ( | void | ) |
Test helper: invoke the registered OSTD callback.
Unit tests call this to simulate a CGC oscillation-stop interrupt firing, verifying that the callback + context are correctly stored and that OSTDSR is cleared before the handler runs. Target builds use the real ICU / NVIC path plumbed through ra8_isr_dispatch instead.
Definition at line 883 of file ra8_cgc.c.
References s_ostd_ctx, s_ostd_enabled, and s_ostd_handler.
|
nodiscard |
Query the current frequency of a clock-tree domain.
Returns the value last programmed by ra8_cgc_init() (or the reset default MOCO value if ra8_cgc_init() has not yet run). Drivers that need to compute baud rates or sampling periods should always go through this function rather than hard-coding values from ra8_time_constants.h.
| [in] | id | Clock identifier. |
| [out] | out_hz | On success, current frequency in Hz. |
Definition at line 132 of file ra8_cgc.c.
References k_ra8_err_invalid_arg, k_ra8_err_null_ptr, k_ra8_ok, and s_clock_hz.
Referenced by adc_diag_setup_or_halt(), al_setup_or_halt(), app_bringup_clocks(), blc_setup_or_halt(), 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(), cdc_setup_or_halt(), ch_setup_or_halt(), cm_bringup_clocks(), combo_clocks_or_halt(), crc_demo_setup_or_halt(), demo_setup_or_halt(), demo_setup_or_halt(), dfu_setup_or_halt(), drw_blend_setup_or_halt(), drw_demo_setup_or_halt(), dtc_arm_setup_or_halt(), dtc_demo_setup_or_halt(), ec_setup_or_halt(), ef_setup_or_halt(), ehb_setup_or_halt(), eoh_setup_or_halt(), eop_setup_or_halt(), ep_bringup_core(), ep_setup_or_halt(), er_try_load_font(), erb_setup_or_halt(), es_setup_or_halt(), est_setup_or_halt(), etoc_setup_or_halt(), ez_bringup_clocks(), fileops_setup_or_halt(), flash_journal_setup_or_halt(), fs_fmt_setup_or_halt(), gh_setup_or_halt(), gpt_ecc_clocks_or_halt(), gptp_setup_or_halt(), hid_setup_or_halt(), i3c_demo_clocks_or_halt(), iic_setup_or_halt(), imp_setup_or_halt(), imu_demo_clocks_or_halt(), internal_acmphs_demo_setup(), internal_agt_periodic_setup_or_halt(), internal_audio_loopback_init_clocks_and_led(), internal_bkup_demo_setup_or_halt(), internal_can_demo_setup_or_halt(), internal_canfd_demo_setup_or_halt(), internal_canfd_filter_setup_or_halt(), internal_clock_check_verify_all(), internal_clocks_or_halt(), internal_clocks_or_halt(), internal_dac_b_demo_setup_or_halt(), internal_dac_demo_setup_or_halt(), internal_demo_clocks_or_halt(), internal_demo_setup_or_halt(), internal_dotf_demo_setup_or_halt(), internal_eth_loopback_setup_or_halt(), internal_gpio_demo_setup_or_halt(), internal_gpt_3p_demo_setup_or_halt(), internal_gpt_irq_demo_setup_or_halt(), internal_gpt_pwm_demo_setup_or_halt(), internal_icu_extint_demo_setup_or_halt(), internal_iic_peripheral_setup_or_halt(), internal_kat_setup_or_halt(), internal_kint_demo_setup_or_halt(), internal_lcd_bringup_clocks(), 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(), internal_lvd_demo_setup_or_halt(), internal_mecc_setup_or_halt(), internal_motor_3phase_init_clocks_and_led(), internal_mpu_simple_setup_or_halt(), internal_pc_setup_or_halt(), internal_pdg_demo_setup_or_halt(), internal_poeg_demo_setup_or_halt(), internal_program_data_phase(), internal_rc_setup_or_halt(), internal_rcs_setup_or_halt(), internal_rng_demo_setup_or_halt(), internal_rtc_demo_setup_or_halt(), internal_sd_demo_setup_or_halt(), internal_setup_or_halt(), internal_ssie_loop_setup_or_halt(), internal_tc_setup_or_halt(), internal_td_setup_or_halt(), internal_uart_hello_setup_or_halt(), internal_usb_audio_clocks_or_halt(), internal_wdt_demo_setup_or_halt(), ipc_demo_setup_or_halt(), iu_setup_or_halt(), iv_setup_or_halt(), kat_setup_or_halt(), kb_setup_or_halt(), l3_setup_or_halt(), lcd_bringup_clocks(), lin_hil_setup_or_halt(), lk_setup_or_halt(), lpi_setup_or_halt(), main(), mem_setup_or_halt(), mg_bringup_clocks(), microsd_setup_or_halt(), mlun_setup_or_halt(), modem_clocks_or_halt(), ospirw_setup_or_halt(), pp_demo_clocks_or_halt(), priv_ra8_esp_hosted_rtos_init(), ra8_board_camera_xclk_start(), ra8_board_touch_open(), ra8_board_uart_console_init(), ra8_canfd_set_bitrate(), ra8_nsc_cgc_get_clock_hz(), ra8_pwr_get_clock_hz(), ra8_threadx_systick_retune(), riic_target_clocks_or_halt(), rot_setup_or_halt(), sb_setup_or_halt(), scb_demo_setup_or_halt(), sd_demo_setup_or_halt(), sd_setup_or_halt(), sdhi_card_setup_or_halt(), sdhi_demo_setup_or_halt(), sdmsc_setup_or_halt(), sdram_demo_setup_or_halt(), selftest_setup_or_halt(), sfr_bringup_clocks(), sh_sd_mount(), sh_setup_or_halt(), tb_setup_or_halt(), timer_demo_setup_or_halt(), tsn_setup_or_halt(), tx_application_define(), uart_irq_setup_or_halt(), wa_setup_or_halt(), wc_setup_or_halt(), wd_setup_or_halt(), wdt_rr_setup_or_halt(), wdt_window_demo_setup_or_halt(), webp_demo_setup_or_halt(), wifi_hal_setup_or_halt(), wk_setup_or_halt(), and wlun_setup_or_halt().
|
nodiscard |
Configure the clock tree to a safe default.
For v0.x bring-up this function is intentionally a no-op: the firmware runs on MOCO (8 MHz) until a real PLL bring-up lands. Returning k_ra8_ok lets main() keep the pattern:
which will automatically start using the real implementation once this function is filled out.
Definition at line 727 of file ra8_cgc.c.
References internal_cgc_init_protected(), internal_clear_pfb(), internal_publish_clocks(), internal_route_sciclk(), internal_set_pfb(), k_ra8_ok, k_ra8_prcr_unlock_cgc, ra8_log_error_val, ra8_log_info, RA8_PROTECTED_WRITE, and s_tag.
Referenced by adc_diag_setup_or_halt(), al_setup_or_halt(), app_bringup_clocks(), app_launch_hil_console_init(), app_setup(), app_shell_hil_console_init(), blc_setup_or_halt(), 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(), cache_hal_setup(), cache_mpu_setup(), cam_bringup(), cdc_setup_or_halt(), ch_setup_or_halt(), cm_bringup_clocks(), combo_clocks_or_halt(), crc_demo_setup_or_halt(), demo_setup_or_halt(), demo_setup_or_halt(), dfu_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(), dualcore_bg_hil_console_init(), dualcore_mailbox_hil_console_init(), ec_setup_or_halt(), ef_setup_or_halt(), ehb_setup_or_halt(), eoh_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(), etoc_setup_or_halt(), ez_bringup_clocks(), fc_setup_or_halt(), fileops_setup_or_halt(), flash_journal_setup_or_halt(), fs_fmt_setup_or_halt(), gh_setup_or_halt(), gpt_ecc_clocks_or_halt(), gptp_setup_or_halt(), hid_setup_or_halt(), i3c_demo_clocks_or_halt(), iic_setup_or_halt(), imp_setup_or_halt(), imu_demo_clocks_or_halt(), internal_acmphs_demo_setup(), internal_agt_periodic_setup_or_halt(), internal_audio_loopback_init_clocks_and_led(), internal_bkup_demo_setup_or_halt(), internal_can_demo_setup_or_halt(), internal_canfd_demo_setup_or_halt(), internal_canfd_filter_setup_or_halt(), internal_clocks_or_halt(), internal_clocks_or_halt(), internal_console_init(), internal_dac_b_demo_setup_or_halt(), internal_dac_demo_setup_or_halt(), internal_demo_clocks_or_halt(), internal_demo_setup_or_halt(), internal_dotf_demo_setup_or_halt(), internal_eth_loopback_setup_or_halt(), internal_gpio_demo_setup_or_halt(), internal_gpt_3p_demo_setup_or_halt(), internal_gpt_irq_demo_setup_or_halt(), internal_gpt_pwm_demo_setup_or_halt(), internal_icu_extint_demo_setup_or_halt(), internal_iic_peripheral_setup_or_halt(), internal_kat_setup_or_halt(), internal_kint_demo_setup_or_halt(), internal_lcd_bringup_clocks(), 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(), internal_lvd_demo_setup_or_halt(), internal_mecc_setup_or_halt(), internal_motor_3phase_init_clocks_and_led(), internal_mpu_simple_setup_or_halt(), internal_npu_infer_setup_or_halt(), internal_npu_smoke_setup_or_halt(), internal_npu_vela_setup_or_halt(), internal_pc_setup_or_halt(), internal_pdg_demo_setup_or_halt(), internal_poeg_demo_setup_or_halt(), internal_rc_setup_or_halt(), internal_rcs_setup_or_halt(), internal_rng_demo_setup_or_halt(), internal_rtc_demo_setup_or_halt(), internal_sd_demo_setup_or_halt(), internal_setup_or_halt(), internal_ssie_loop_setup_or_halt(), internal_tc_setup_or_halt(), internal_td_setup_or_halt(), internal_uart_hello_setup_or_halt(), internal_usb_audio_clocks_or_halt(), internal_wdt_demo_setup_or_halt(), ipc_demo_setup_or_halt(), iu_setup_or_halt(), iv_setup_or_halt(), kat_setup_or_halt(), kb_setup_or_halt(), l3_setup_or_halt(), lcd_bringup_clocks(), lin_hil_setup_or_halt(), lk_setup_or_halt(), lpi_setup_or_halt(), main(), mem_setup_or_halt(), mg_bringup_clocks(), microsd_setup_or_halt(), mlun_setup_or_halt(), modem_clocks_or_halt(), mpu_boot_setup(), ospirw_setup_or_halt(), pp_demo_clocks_or_halt(), ra8_board_clocks_init(), riic_target_clocks_or_halt(), rot_setup_or_halt(), sb_setup_or_halt(), scb_demo_setup_or_halt(), sd_demo_setup_or_halt(), sd_setup_or_halt(), sdhi_card_setup_or_halt(), sdhi_demo_setup_or_halt(), sdmsc_setup_or_halt(), sdram_demo_setup_or_halt(), selftest_setup_or_halt(), sfr_bringup_clocks(), sh_setup_or_halt(), SystemInit(), tb_setup_or_halt(), timer_demo_setup_or_halt(), tsn_setup_or_halt(), uart_irq_setup_or_halt(), wa_setup_or_halt(), wc_setup_or_halt(), wd_setup_or_halt(), wdt_rr_setup_or_halt(), wdt_window_demo_setup_or_halt(), webp_demo_setup_or_halt(), wifi_hal_setup_or_halt(), wk_setup_or_halt(), and wlun_setup_or_halt().
|
nodiscard |
Bring up PLL2 with caller-supplied multiplier and P divider.
Sequence (mirrors FSP bsp_clocks.c PLL2 path and HUM Ch 9.2.10..12):
The multiplier is encoded the same way PLL1 encodes it: the integer part goes in PLL2MUL[15:8] and the quarter-step fractional part in PLL2MULNF[7:6]. Caller passes the integer multiplier (1..255) and the quarter-steps (0..3) separately.
Output dividers use the standard ra8_plodiv_t code-to-ratio map (e.g. /4 = 3, /5 = 4, /6 = 5).
VCO frequency MUST land in the 960..2400 MHz range required by the RA8D2 silicon (per BSP_FEATURE_CGC_PLLCCR_VCO_*). PLL2 output frequency MUST land in 60..1200 MHz (BSP_FEATURE_CGC_PLL2_OUT_*). The driver does not enforce this; the caller is responsible.
Input source is fixed to the main XTAL on EK-RA8D2 (PL2SRCSEL = 0) and input divider is fixed to /2 so the PLL pre-scale lands at 12 MHz, matching what the FSP quickstart does for the 24 MHz crystal.
| [in] | mul_int | Integer multiplier (1..255). Effective multiplier is mul_int + (mul_quarters / 4). |
| [in] | mul_quarters | Fractional quarter-steps (0..3). |
| [in] | p_div_code | Output divider P code from ra8_plodiv_t (e.g. k_ra8_plodiv_div4 for /4). |
| k_ra8_ok | PLL2 locked. |
| k_ra8_err_invalid_arg | mul_int is 0 or mul_quarters > 3. |
| k_ra8_err_hw_timeout | PLL2SF stop or start handshake exhausted its spin budget. |
Bring up PLL2 with caller-supplied multiplier and P divider.
Idempotent: if OSCSF.PLL2SF is already asserted on entry the function returns k_ra8_ok without touching PLL2CCR / PLL2CCR2 / PLL2CR. This lets the FS and HS USB bring-up paths (which both want the same 960 MHz VCO with PLL2P = /4 = 240 MHz) coexist on the same boot without re-programming a live PLL2 (HUM Ch 9 forbids writing PLL2CCR while PLL2 is running, and downstream consumers – including USBCKCR sourced from PLL2P after the FS path runs – would lose their clock during the re-program).
Stops PLL2 (with bounded poll on OSCSF.PLL2SF clear), programmes PLL2CCR + PLL2CCR2, then starts PLL2 (bounded poll on OSCSF.PLL2SF set). Input divider is hard-wired to /2 and source to main XTAL because that is the only configuration the EK-RA8D2 (24 MHz crystal) needs today; broaden the API once a second board lands.
| [in] | mul_int | Integer multiplier (1..255). |
| [in] | mul_quarters | Quarter-step fractional multiplier (0..3). |
| [in] | p_div_code | ra8_plodiv_t code for the P output divider. |
| k_ra8_ok | PLL2 locked. |
| k_ra8_err_invalid_arg | mul_int is 0 or mul_quarters > 3. |
| k_ra8_err_hw_timeout | PLL2SF stop or start handshake timed out. |
Definition at line 258 of file ra8_cgc_usb.c.
References internal_pll2_program_protected(), k_ra8_cgc_quarters_per_unit, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_oscsf_bit_pll2sf, k_ra8_plidiv_div2, k_ra8_pll2_max_quarters, k_ra8_pll2ccr_mask_plidiv, k_ra8_pll2ccr_mask_quarters, k_ra8_pllccr2_shift_plodivp, k_ra8_pllccr2_shift_plodivq, k_ra8_pllccr2_shift_plodivr, k_ra8_pllccr_shift_plsrcsel, k_ra8_pllccr_shift_quarters, k_ra8_plodiv_div6, k_ra8_plsrcsel_main, ra8_log_info, ra8_log_info_val, ra8_sys_oscsf(), and s_tag.
Referenced by ra8_cgc_usbfs_clock_enable(), ra8_cgc_usbhs_pll_enable(), and ra8_nsc_cgc_pll2_enable().
|
nodiscard |
Retune PLL1 to a new CPUCLK0 target without a full deinit.
Walks through the safe transition sequence from HUM Ch 9.2 (p 317):
| [in] | new_cpuclk_hz | Target CPUCLK0 frequency in Hz. Must be a multiple of the crystal divided by 32 (the PLLCCR2 fractional step). |
| k_ra8_ok | Clock switched to the new target. |
| k_ra8_err_invalid_arg | new_cpuclk_hz is 0. |
| k_ra8_err_hw_timeout | PLL lock or MOCO wait timed out. |
Definition at line 814 of file ra8_cgc.c.
References internal_program_and_start_pll1(), internal_publish_clocks(), internal_stop_pll1(), k_ra8_cksel_moco, k_ra8_cksel_pll1, k_ra8_clock_id_cpuclk0, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_prcr_unlock_cgc, ra8_log_error_val, ra8_log_info_val, RA8_PROTECTED_WRITE, ra8_sys_sckscr(), s_clock_hz, and s_tag.
|
nodiscard |
Bring up the USB-FS module clock (USBCKCR / USBCKDIVCR).
On RA8D2 the USB-FS controller is not clocked merely by ungating MSTPCRB.MSTPB11 – the System Control block has a dedicated USBCKCR / USBCKDIVCR pair (HUM Ch 9, USBCKCR p 365) that selects the source clock for the controller's 48 MHz reference. After power-on reset USBCKCR reads as 0 (USBCKSEL = HOCO, ~20 MHz) which is not a valid USB-FS reference, and the SIE will never bus-reset a connected device. Symptom on EK-RA8D2: DVSTCTR0 stuck at 0x0002 (Powered, never Default), INTSTS0.CTRT = 0, no SETUP packet ever delivered.
Sequence per FSP bsp_clocks.c and HUM Ch 9 "Clock selection switching procedure" (canonical example: SPICKCR p 370):
Source picked here is PLL2P with USBCKDIVCR = /5 codepoint. PLL2 is brought up via ra8_cgc_pll2_enable to land on VCO = 24 MHz / 2 * 80 = 960 MHz, then PL2ODIVP = /4 -> PLL2P = 240 MHz. USBCKDIVCR = /5 then yields exactly 48.000 MHz, which is within the USB-FS spec (48 MHz +/- 2500 ppm = +/- 0.25 %).
| k_ra8_ok | USB-FS module clock running. |
| k_ra8_err_hw_timeout | USBCKSRDY handshake never completed. |
Bring up the USB-FS module clock (USBCKCR / USBCKDIVCR).
| k_ra8_ok | USB-FS clock running at exactly 48 MHz. |
| k_ra8_err_hw_init_failed | PLL2 enable failed; see log. |
| k_ra8_err_hw_timeout | USBCKCR SREQ/SRDY handshake timed out. |
Definition at line 364 of file ra8_cgc_usb.c.
References internal_usbckcr_switch_to_pll2p_div5(), k_ra8_hococr_hcstp, k_ra8_mstpb11_usbfs_mask, k_ra8_ok, k_ra8_oscsf_bit_hocosf, k_ra8_pll2_usbfs_mul, k_ra8_pll2_usbfs_quarters, k_ra8_plodiv_div4, k_ra8_prcr_unlock_cgc, r_mstp_regs_t::MSTPCRB, priv_ra8_cgc_wait_oscsf_set(), ra8_cgc_pll2_enable(), ra8_log_error, ra8_log_error_val, ra8_log_info, ra8_mstp(), RA8_PROTECTED_WRITE, ra8_sys_hococr(), and s_tag.
Referenced by blc_setup_or_halt(), cdc_setup_or_halt(), dfu_setup_or_halt(), fileops_setup_or_halt(), hid_setup_or_halt(), main(), microsd_setup_or_halt(), mlun_setup_or_halt(), ospirw_setup_or_halt(), ra8_nsc_cgc_usbfs_clock_enable(), sdmsc_setup_or_halt(), selftest_setup_or_halt(), and wlun_setup_or_halt().
|
nodiscard |
Bring up the USBHS PHY reference clock + module clock.
The RA8D2 USB 2.0 High-Speed controller drives an internal PHY whose 480 MHz CDR PLL needs a stable 12 MHz reference derived from the main XTAL (24 MHz / 2). The CGC-side gating for that path lives in the System Control block; the procedure (per HUM Ch 9 "Clock Generation Circuit", USBCKCR / USBCKDIVCR description, p 365) is:
After this returns k_ra8_ok the caller is free to invoke ra8_mstp_enable for k_ra8_mstp_usbhs (typically routed through ra8_usb_device_init / ra8_usb_host_init) and the controller's SYSCFG.USBE bit will see a clocked PHY underneath it.
| k_ra8_ok | USBHS clock subsystem armed. |
| k_ra8_err_hw_timeout | Main XTAL never reported stable. |
Bring up the USBHS PHY reference clock + module clock.
The USBHS PHY's internal 480 MHz CDR PLL requires a stable 12 MHz reference, derived inside the PHY from a /5 division of the 60 MHz USB60CLK. This routine programmes USB60CKCR / USB60CKDIVCR (HUM Ch 9 "Clock Generation Circuit") so USB60CLK = PLL2P / 4 = 60.000 MHz exactly (PLL2P = 240 MHz from the same configuration the FS path uses, see ra8_cgc_usbfs_clock_enable). Mirrors the canonical FSP bsp_clocks.c bsp_peripheral_clock_set SREQ/SRDY ordering.
Sequence:
| k_ra8_ok | USBHS 60 MHz clock running on PLL2P/4. |
| k_ra8_err_hw_timeout | Main XTAL, HOCO, or USB60CKSRDY handshake timed out. |
| k_ra8_err_invalid_arg | PLL2 mul/quarters out of range (propagated from ra8_cgc_pll2_enable). |
Definition at line 624 of file ra8_cgc_usb.c.
References internal_usb60ckcr_switch_to_pll2p_div4(), k_ra8_mstpb12_usbhs_mask, k_ra8_ok, k_ra8_oscsf_bit_moscsf, k_ra8_pll2_usbfs_mul, k_ra8_pll2_usbfs_quarters, k_ra8_plodiv_div4, r_mstp_regs_t::MSTPCRB, priv_ra8_cgc_ensure_hoco_running_for_usb_ck(), priv_ra8_cgc_wait_oscsf_set(), ra8_cgc_pll2_enable(), ra8_log_error, ra8_log_error_val, ra8_log_info, ra8_mstp(), and s_tag.
Referenced by cdc_setup_or_halt(), dfu_setup_or_halt(), fileops_setup_or_halt(), hid_setup_or_halt(), internal_usbhs_clock_and_mstp(), main(), microsd_setup_or_halt(), mlun_setup_or_halt(), ospirw_setup_or_halt(), selftest_setup_or_halt(), and wlun_setup_or_halt().
|
nodiscard |
Switch the system clock source to HOCO (20 MHz).
Starts the HOCO if it is stopped, waits for it to stabilise, then writes k_ra8_cksel_hoco to SCKSCR. Requires a PRCR unlock around the SCKSCR write.
| k_ra8_ok | Clock switched. |
| k_ra8_err_hw_timeout | HOCO failed to report ready within the timeout window. |
Definition at line 763 of file ra8_cgc.c.
References k_ra8_cksel_hoco, k_ra8_hococr_hcstp, k_ra8_ok, k_ra8_oscsf_bit_hocosf, k_ra8_prcr_unlock_cgc, priv_ra8_cgc_wait_oscsf_set(), ra8_log_info, RA8_PROTECTED_WRITE, ra8_sys_hococr(), ra8_sys_sckscr(), and s_tag.