20
20
21
21
LOG_MODULE_REGISTER (entropy , CONFIG_ENTROPY_LOG_LEVEL );
22
22
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
+
23
43
static inline uint32_t entropy_esp32_get_u32 (void )
24
44
{
25
45
/* The PRNG which implements WDEV_RANDOM register gets 2 bits
@@ -30,18 +50,29 @@ static inline uint32_t entropy_esp32_get_u32(void)
30
50
* wait a bit longer due to extra time spent in arithmetic and branch statements.
31
51
*/
32
52
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 ();
35
54
36
55
static uint32_t last_ccount ;
37
56
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
39
69
do {
40
70
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
42
74
last_ccount = ccount ;
43
-
44
- return REG_READ (WDEV_RND_REG );
75
+ return result ^ REG_READ (WDEV_RND_REG );
45
76
}
46
77
47
78
static int entropy_esp32_get_entropy (const struct device * dev , uint8_t * buf ,
0 commit comments