2020
2121LOG_MODULE_REGISTER (entropy , CONFIG_ENTROPY_LOG_LEVEL );
2222
23+ #if SOC_LP_TIMER_SUPPORTED
24+ #include "hal/lp_timer_hal.h"
25+ #endif
26+
27+ #if defined CONFIG_SOC_SERIES_ESP32S3
28+ /* If APB clock is 80 MHz, the maximum sampling frequency is around 45 KHz */
29+ /* 45 KHz reading frequency is the maximum we have tested so far on S3 */
30+ #define APB_CYCLE_WAIT_NUM (1778)
31+ #elif defined CONFIG_SOC_SERIES_ESP32C6
32+ /* On ESP32C6, we only read one byte at a time, then XOR the value with
33+ * an asynchronous timer (see code below).
34+ * The current value translates to a sampling frequency of around 62.5 KHz
35+ * for reading 8 bit samples, which is the rate at which the RNG was tested,
36+ * plus additional overhead for the calculation, making it slower.
37+ */
38+ #define APB_CYCLE_WAIT_NUM (160 * 16)
39+ #else
40+ #define APB_CYCLE_WAIT_NUM (16)
41+ #endif
42+
2343static inline uint32_t entropy_esp32_get_u32 (void )
2444{
2545 /* The PRNG which implements WDEV_RANDOM register gets 2 bits
@@ -30,18 +50,29 @@ static inline uint32_t entropy_esp32_get_u32(void)
3050 * wait a bit longer due to extra time spent in arithmetic and branch statements.
3151 */
3252
33- uint32_t cpu_to_apb_freq_ratio =
34- esp_clk_cpu_freq () / esp_clk_apb_freq ();
53+ uint32_t cpu_to_apb_freq_ratio = esp_clk_cpu_freq () / esp_clk_apb_freq ();
3554
3655 static uint32_t last_ccount ;
3756 uint32_t ccount ;
38-
57+ uint32_t result = 0 ;
58+ #if SOC_LP_TIMER_SUPPORTED
59+ for (size_t i = 0 ; i < sizeof (result ); i ++ ) {
60+ do {
61+ ccount = esp_cpu_get_cycle_count ();
62+ result ^= REG_READ (WDEV_RND_REG );
63+ } while (ccount - last_ccount < cpu_to_apb_freq_ratio * APB_CYCLE_WAIT_NUM );
64+ uint32_t current_rtc_timer_counter = (lp_timer_hal_get_cycle_count () & 0xFF );
65+
66+ result ^= ((result ^ current_rtc_timer_counter ) & 0xFF ) << (i * 8 );
67+ }
68+ #else
3969 do {
4070 ccount = esp_cpu_get_cycle_count ();
41- } while (ccount - last_ccount < cpu_to_apb_freq_ratio * 16 );
71+ result ^= REG_READ (WDEV_RND_REG );
72+ } while (ccount - last_ccount < cpu_to_apb_freq_ratio * APB_CYCLE_WAIT_NUM );
73+ #endif
4274 last_ccount = ccount ;
43-
44- return REG_READ (WDEV_RND_REG );
75+ return result ^ REG_READ (WDEV_RND_REG );
4576}
4677
4778static int entropy_esp32_get_entropy (const struct device * dev , uint8_t * buf ,
0 commit comments