From 52a6ad71eecff141f18759cf0f903aca5d6e0fd0 Mon Sep 17 00:00:00 2001 From: Laukik Hase Date: Mon, 6 Jul 2026 17:25:17 +0530 Subject: [PATCH] feat(hal): Add LL-API to check whether RNG is enabled - Also add RNG LL-APIs for ESP32-C61 - Add SOC_RNG_CLOCK_IS_INDEPENDENT for ESP32-C61: now that rng_ll_disable() actually clears the RNG clock gate, the application needs the esp_hw_support startup hook to re-enable the RNG after bootloader_random_disable() --- components/hal/esp32c5/include/hal/rng_ll.h | 23 +++++ components/hal/esp32c6/include/hal/rng_ll.h | 7 ++ components/hal/esp32c61/include/hal/rng_ll.h | 93 ++++++++++++++++++- components/hal/esp32h2/include/hal/rng_ll.h | 7 ++ components/hal/esp32h4/include/hal/rng_ll.h | 24 +++++ components/hal/esp32p4/include/hal/rng_ll.h | 5 + components/hal/esp32s31/include/hal/rng_ll.h | 10 ++ .../esp32c61/include/soc/Kconfig.soc_caps.in | 4 + .../soc/esp32c61/include/soc/soc_caps.h | 1 + 9 files changed, 172 insertions(+), 2 deletions(-) diff --git a/components/hal/esp32c5/include/hal/rng_ll.h b/components/hal/esp32c5/include/hal/rng_ll.h index 0d02b155351..14b9f78746a 100644 --- a/components/hal/esp32c5/include/hal/rng_ll.h +++ b/components/hal/esp32c5/include/hal/rng_ll.h @@ -15,6 +15,8 @@ //For ESP32C5, RNG needs to be reset and enabled again when wakeup from sleep #define RNG_LL_NEEDS_RESET_WHEN_WAKEUP 1 +//Default value for the RNG timer clock divider +#define RNG_LL_CFG_PSCALE 255 #ifdef __cplusplus extern "C" { @@ -40,6 +42,16 @@ static inline void rng_ll_enable_sample(bool enable) LPPERI.rng_cfg.rng_sample_enable = enable; } +/** + * @brief Set RNG timer prescaler + * + * @param prescaler Timer prescaler value (0-255) + */ +static inline void rng_ll_set_timer_prescaler(uint8_t prescaler) +{ + LPPERI.rng_cfg.rng_timer_pscale = prescaler; +} + /** * @brief Enable or disable rng xor rtc timer. * @@ -77,6 +89,7 @@ static inline void rng_ll_reset(void) static inline void rng_ll_enable(void) { _lp_clkrst_ll_enable_rng_clock(true); + rng_ll_set_timer_prescaler(RNG_LL_CFG_PSCALE); rng_ll_enable_sample(true); rng_ll_enable_rtc_timer(true); rng_ll_enable_rng_timer(true); @@ -95,6 +108,16 @@ static inline void rng_ll_disable(void) _lp_clkrst_ll_enable_rng_clock(false); } +/** + * @brief Check that the RNG is live: clocked and out of reset. + * + * @return True if the RNG is enabled and operational, false otherwise. + */ +static inline bool rng_ll_is_enabled(void) +{ + return LPPERI.clk_en.rng_ck_en && !LPPERI.reset_en.lp_rng_reset_en; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/rng_ll.h b/components/hal/esp32c6/include/hal/rng_ll.h index d7d93333538..24c854e3ec8 100644 --- a/components/hal/esp32c6/include/hal/rng_ll.h +++ b/components/hal/esp32c6/include/hal/rng_ll.h @@ -6,9 +6,11 @@ #pragma once +#include #include #include "soc/soc.h" #include "soc/lpperi_reg.h" +#include "soc/lpperi_struct.h" #include "hal/lp_clkrst_ll.h" #ifdef __cplusplus @@ -30,6 +32,11 @@ static inline void rng_ll_disable(void) _lp_clkrst_ll_enable_rng_clock(false); } +static inline bool rng_ll_is_enabled(void) +{ + return LPPERI.clk_en.rng_ck_en; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c61/include/hal/rng_ll.h b/components/hal/esp32c61/include/hal/rng_ll.h index e6697a2979b..00273620954 100644 --- a/components/hal/esp32c61/include/hal/rng_ll.h +++ b/components/hal/esp32c61/include/hal/rng_ll.h @@ -6,26 +6,115 @@ #pragma once +#include #include #include "soc/soc.h" #include "soc/lpperi_reg.h" +#include "soc/lpperi_struct.h" + +//For ESP32C61, RNG needs to be reset and enabled again when wakeup from sleep +#define RNG_LL_NEEDS_RESET_WHEN_WAKEUP 1 +//Default value for the RNG timer clock divider +#define RNG_LL_CFG_PSCALE 255 #ifdef __cplusplus extern "C" { #endif +/** + * @brief Read random data from RNG + * + * @return 32-bit random data + */ static inline uint32_t rng_ll_read_data(void) { return REG_READ(LPPERI_RNG_DATA_SYNC_REG); } -/* For compatibility. */ -static inline void rng_ll_enable(void) +/** + * @brief Enable or disable RNG sampling. + * + * @param enable True to enable, False to disable + */ +static inline void rng_ll_enable_sample(bool enable) { + LPPERI.rng_cfg.rng_sample_enable = enable; } +/** + * @brief Set RNG timer prescaler + * + * @param prescaler Timer prescaler value (0-255) + */ +static inline void rng_ll_set_timer_prescaler(uint8_t prescaler) +{ + LPPERI.rng_cfg.rng_timer_pscale = prescaler; +} + +/** + * @brief Enable or disable rng xor rtc timer. + * + * @param enable True to enable, False to disable + */ +static inline void rng_ll_enable_rtc_timer(bool enable) +{ + LPPERI.rng_cfg.rtc_timer_en = enable ? 0x3 : 0x0; +} + +/** + * @brief Enable or disable rng xor async rng timer. + * + * @param enable True to enable, False to disable + */ +static inline void rng_ll_enable_rng_timer(bool enable) +{ + LPPERI.rng_cfg.rng_timer_en = enable; +} + +/** + * @brief Reset RNG. + */ +static inline void rng_ll_reset(void) +{ + LPPERI.reset_en.lp_rng_reset_en = 1; + LPPERI.reset_en.lp_rng_reset_en = 0; +} + +/** + * @brief Enable RNG module + * + * TODO: unify in rng_hal.c + */ +static inline void rng_ll_enable(void) +{ + LPPERI.clk_en.rng_ck_en = 1; + rng_ll_set_timer_prescaler(RNG_LL_CFG_PSCALE); + rng_ll_enable_sample(true); + rng_ll_enable_rtc_timer(true); + rng_ll_enable_rng_timer(true); +} + +/** + * @brief Disable RNG module + * + * TODO: unify in rng_hal.c + */ static inline void rng_ll_disable(void) { + rng_ll_enable_sample(false); + rng_ll_enable_rtc_timer(false); + rng_ll_enable_rng_timer(false); + LPPERI.clk_en.rng_ck_en = 0; +} + +/** + * @brief Check that the RNG is live: clocked and out of reset. + * + * @return True if the RNG is enabled and operational, false otherwise. + */ +static inline bool rng_ll_is_enabled(void) +{ + return LPPERI.clk_en.rng_ck_en && !LPPERI.reset_en.lp_rng_reset_en; } #ifdef __cplusplus diff --git a/components/hal/esp32h2/include/hal/rng_ll.h b/components/hal/esp32h2/include/hal/rng_ll.h index d7d93333538..d6ed15f98b7 100644 --- a/components/hal/esp32h2/include/hal/rng_ll.h +++ b/components/hal/esp32h2/include/hal/rng_ll.h @@ -6,9 +6,11 @@ #pragma once +#include #include #include "soc/soc.h" #include "soc/lpperi_reg.h" +#include "soc/lpperi_struct.h" #include "hal/lp_clkrst_ll.h" #ifdef __cplusplus @@ -30,6 +32,11 @@ static inline void rng_ll_disable(void) _lp_clkrst_ll_enable_rng_clock(false); } +static inline bool rng_ll_is_enabled(void) +{ + return LPPERI_REG_GET(clk_en.rng_ck_en); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32h4/include/hal/rng_ll.h b/components/hal/esp32h4/include/hal/rng_ll.h index 1a0bdc83df3..ab453fecddf 100644 --- a/components/hal/esp32h4/include/hal/rng_ll.h +++ b/components/hal/esp32h4/include/hal/rng_ll.h @@ -14,6 +14,9 @@ #include "soc/lpperi_struct.h" #include "hal/lp_clkrst_ll.h" +//Default value for the RNG timer clock divider +#define RNG_LL_CFG_PSCALE 255 + #ifdef __cplusplus extern "C" { #endif @@ -38,6 +41,16 @@ static inline void rng_ll_enable_sample(bool enable) REG_SET_FIELD(RNG_CFG_REG, RNG_SAMPLE_ENABLE, enable); } +/** + * @brief Set RNG timer prescaler + * + * @param prescaler Timer prescaler value (0-255) + */ +static inline void rng_ll_set_timer_prescaler(uint8_t prescaler) +{ + REG_SET_FIELD(RNG_CFG_REG, RNG_TIMER_PSCALE, prescaler); +} + /** * @brief Enable or disable rng xor rtc timer. * @@ -75,6 +88,7 @@ static inline void rng_ll_reset(void) static inline void rng_ll_enable(void) { _lp_clkrst_ll_enable_rng_clock(true); + rng_ll_set_timer_prescaler(RNG_LL_CFG_PSCALE); rng_ll_enable_sample(true); rng_ll_enable_rtc_timer(true); rng_ll_enable_rng_timer(true); @@ -93,6 +107,16 @@ static inline void rng_ll_disable(void) _lp_clkrst_ll_enable_rng_clock(false); } +/** + * @brief Check that the RNG is live: clocked and out of reset. + * + * @return True if the RNG is enabled and operational, false otherwise. + */ +static inline bool rng_ll_is_enabled(void) +{ + return LPPERI.clk_en.rng_ck_en && LPPERI.clk_en.rng_apb_ck_en && !LPPERI.reset_en.lp_rng_apb_reset_en; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/rng_ll.h b/components/hal/esp32p4/include/hal/rng_ll.h index cc051e73eb2..7a3250b8b67 100644 --- a/components/hal/esp32p4/include/hal/rng_ll.h +++ b/components/hal/esp32p4/include/hal/rng_ll.h @@ -13,6 +13,10 @@ #if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 #include "soc/trng_reg.h" #include "soc/trng_struct.h" + +//Default value for the RNG timer clock divider +#define RNG_LL_CFG_PSCALE 255 + #else #include "soc/lp_system_reg.h" #endif @@ -121,6 +125,7 @@ static inline void rng_ll_enable(void) #if HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 300 rng_ll_enable_clock(true); rng_ll_reset(); + rng_ll_set_timer_prescaler(RNG_LL_CFG_PSCALE); rng_ll_enable_timer(true); rng_ll_enable_sample(true); #endif diff --git a/components/hal/esp32s31/include/hal/rng_ll.h b/components/hal/esp32s31/include/hal/rng_ll.h index 5d4513b97ac..62163ae6e06 100644 --- a/components/hal/esp32s31/include/hal/rng_ll.h +++ b/components/hal/esp32s31/include/hal/rng_ll.h @@ -96,6 +96,16 @@ static inline void rng_ll_disable(void) rng_ll_enable_bus_clock(false); } +/** + * @brief Check that the RNG is live: clocked and out of reset. + * + * @return True if the RNG is enabled and operational, false otherwise. + */ +static inline bool rng_ll_is_enabled(void) +{ + return LP_PERI_CLKRST.rng_ctrl.lp_rng_clk_en && !LP_PERI_CLKRST.rng_ctrl.lp_rng_rst_en; +} + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 0c5a1c339ed..231d9b9a124 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -1099,6 +1099,10 @@ config SOC_MODEM_CLOCK_IS_INDEPENDENT bool default y +config SOC_RNG_CLOCK_IS_INDEPENDENT + bool + default y + config SOC_CLK_XTAL32K_SUPPORTED bool default y diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index d6a5c95f701..a2c9695607d 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -451,6 +451,7 @@ /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) #define SOC_MODEM_CLOCK_IS_INDEPENDENT (1) +#define SOC_RNG_CLOCK_IS_INDEPENDENT (1) #define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */ #define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */