From 4565d9f6e6c7acf44ddfd8d664d39491d79feb9c Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Thu, 4 Apr 2024 17:17:53 +0200 Subject: [PATCH 01/16] interstate --- esp-hal/src/rng.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index 3a4579d576a..05a89fca7de 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -119,3 +119,23 @@ impl rand_core::RngCore for Rng { Ok(()) } } + +#[derive(Clone, Copy)] +pub struct Trng<'d, ADC> { + pub rng: Rng, + _adc1: PeripheralRef<'d, ADCI>, + #[cfg(esp32c3, )]>, +} + +impl Trng { + /// Create a new True Random Number Generator instance + pub fn new(rng: impl Peripheral

) -> Self { + let gen = Rng::new(rng); + #[cfg(not(esp32p4))] + crate::soc::trng::ensure_randomness(); + Self{rng: gen} + } +} + +#[cfg(not(esp32p4))] +impl rand_core::CryptoRng for Rng {} From dc94ca0dc57be38a3e78ec7d9d0776f194aa7349 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Fri, 5 Apr 2024 16:54:45 +0200 Subject: [PATCH 02/16] Use type-state over creating new struct --- esp-hal/src/rng.rs | 83 ++++++++++++++++++++--------------------- examples/src/bin/rng.rs | 30 +++++++++++++-- 2 files changed, 66 insertions(+), 47 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index 05a89fca7de..01ef6d20322 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -46,50 +46,45 @@ use core::marker::PhantomData; use crate::{peripheral::Peripheral, peripherals::RNG}; +pub trait BasicRng {} +pub trait SecureRng {} + +pub struct Basic; +pub struct Secure; + +impl BasicRng for Basic {} +impl SecureRng for Secure {} + /// Random number generator driver #[derive(Clone, Copy)] -pub struct Rng { - _phantom: PhantomData, +pub struct Rng { + _phantom: PhantomData<(RNG, T)>, } -impl Rng { +impl Rng { /// Create a new random number generator instance pub fn new(_rng: impl Peripheral

) -> Self { Self { _phantom: PhantomData, } } +} - #[inline] - /// Reads currently available `u32` integer from `RNG` - pub fn random(&mut self) -> u32 { - // SAFETY: read-only register access - unsafe { &*crate::peripherals::RNG::PTR } - .data() - .read() - .bits() - } - - #[inline] - /// Reads enough bytes from hardware random number generator to fill - /// `buffer`. - /// - /// If any error is encountered then this function immediately returns. The - /// contents of buf are unspecified in this case. - /// - /// If this function returns an error, it is unspecified how many bytes it - /// has read, but it will never read more than would be necessary to - /// completely fill the buffer. - pub fn read(&mut self, buffer: &mut [u8]) { - for chunk in buffer.chunks_mut(4) { - let bytes = self.random().to_le_bytes(); - chunk.copy_from_slice(&bytes[..chunk.len()]); +impl Rng { + /// Create a new secure random number generator (or TRNG) instance + pub fn new<'d>( + rng: impl Peripheral

, + _adc: impl Peripheral

+ 'd, + ) -> Self { + crate::soc::trng::ensure_randomness(); + Self { + _phantom: PhantomData, } } } #[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::blocking::rng::Read for Rng { +impl embedded_hal_02::blocking::rng::Read for Rng { type Error = core::convert::Infallible; fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> { @@ -98,7 +93,7 @@ impl embedded_hal_02::blocking::rng::Read for Rng { } } -impl rand_core::RngCore for Rng { +impl rand_core::RngCore for Rng { fn next_u32(&mut self) -> u32 { self.random() } @@ -120,22 +115,24 @@ impl rand_core::RngCore for Rng { } } -#[derive(Clone, Copy)] -pub struct Trng<'d, ADC> { - pub rng: Rng, - _adc1: PeripheralRef<'d, ADCI>, - #[cfg(esp32c3, )]>, -} +// Common RNG functionality that applies to both basic and true RNG +impl Rng { + pub fn read(&mut self, buffer: &mut [u8]) { + for chunk in buffer.chunks_mut(4) { + let bytes = self.random().to_le_bytes(); + chunk.copy_from_slice(&bytes[..chunk.len()]); + } + } -impl Trng { - /// Create a new True Random Number Generator instance - pub fn new(rng: impl Peripheral

) -> Self { - let gen = Rng::new(rng); - #[cfg(not(esp32p4))] - crate::soc::trng::ensure_randomness(); - Self{rng: gen} + /// Reads currently available `u32` integer from `RNG` + pub fn random(&mut self) -> u32 { + // SAFETY: read-only register access + unsafe { &*crate::peripherals::RNG::PTR } + .data() + .read() + .bits() } } #[cfg(not(esp32p4))] -impl rand_core::CryptoRng for Rng {} +impl rand_core::CryptoRng for Rng {} diff --git a/examples/src/bin/rng.rs b/examples/src/bin/rng.rs index fc87b7d8fda..ee86e46bb42 100644 --- a/examples/src/bin/rng.rs +++ b/examples/src/bin/rng.rs @@ -6,20 +6,42 @@ #![no_main] use esp_backtrace as _; -use esp_hal::{peripherals::Peripherals, prelude::*, rng::Rng}; +use esp_hal::{peripherals::Peripherals, prelude::*, rng::{Rng, Secure}, + analog::adc::{AdcConfig, Attenuation, ADC}, + clock::ClockControl, + delay::Delay, + gpio::IO, + peripherals::ADC1}; use esp_println::println; #[entry] fn main() -> ! { let peripherals = Peripherals::take(); - let mut rng = Rng::new(peripherals.RNG); + let mut trng = Rng::::new(peripherals.RNG, peripherals.ADC1); + + // let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); + // cfg_if::cfg_if! { + // if #[cfg(feature = "esp32")] { + // let analog_pin = io.pins.gpio32.into_analog(); + // } else if #[cfg(any(feature = "esp32s2", feature = "esp32s3"))] { + // let analog_pin = io.pins.gpio3.into_analog(); + // } else { + // let analog_pin = io.pins.gpio2.into_analog(); + // } + // } + + // // Create ADC instances + // let mut adc1_config = AdcConfig::new(); + // let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); + // let mut adc1 = ADC::::new(peripherals.ADC1, adc1_config); + // Generate a random word (u32): - println!("Random u32: {}", rng.random()); + println!("Random u32: {}", trng.random()); // Fill a buffer with random bytes: let mut buf = [0u8; 16]; - rng.read(&mut buf); + trng.read(&mut buf); println!("Random bytes: {:?}", buf); loop {} From f9f5f80566baf382d83b2d5bd5ebdbbd5b357060 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Fri, 5 Apr 2024 20:39:13 +0200 Subject: [PATCH 03/16] Getting revert_trng function into the driver --- esp-hal/src/rng.rs | 106 +++++---- esp-hal/src/soc/esp32/trng.rs | 186 +++++++++++++++ esp-hal/src/soc/esp32c2/trng.rs | 202 +++++++++++++++++ esp-hal/src/soc/esp32c3/trng.rs | 205 +++++++++++++++++ esp-hal/src/soc/esp32c6/trng.rs | 363 +++++++++++++++++++++++++++++ esp-hal/src/soc/esp32s2/trng.rs | 389 ++++++++++++++++++++++++++++++++ esp-hal/src/soc/esp32s3/trng.rs | 236 +++++++++++++++++++ examples/src/bin/rng.rs | 26 +-- 8 files changed, 1651 insertions(+), 62 deletions(-) create mode 100644 esp-hal/src/soc/esp32/trng.rs create mode 100644 esp-hal/src/soc/esp32c2/trng.rs create mode 100644 esp-hal/src/soc/esp32c3/trng.rs create mode 100644 esp-hal/src/soc/esp32c6/trng.rs create mode 100644 esp-hal/src/soc/esp32s2/trng.rs create mode 100644 esp-hal/src/soc/esp32s3/trng.rs diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index 01ef6d20322..9a9582d159d 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -44,47 +44,52 @@ use core::marker::PhantomData; -use crate::{peripheral::Peripheral, peripherals::RNG}; - -pub trait BasicRng {} -pub trait SecureRng {} - -pub struct Basic; -pub struct Secure; - -impl BasicRng for Basic {} -impl SecureRng for Secure {} +use crate::{peripheral::{Peripheral, PeripheralRef} , peripherals::RNG}; /// Random number generator driver #[derive(Clone, Copy)] -pub struct Rng { - _phantom: PhantomData<(RNG, T)>, +pub struct Rng { + _phantom: PhantomData, } -impl Rng { +impl Rng { /// Create a new random number generator instance pub fn new(_rng: impl Peripheral

) -> Self { Self { _phantom: PhantomData, } } -} -impl Rng { - /// Create a new secure random number generator (or TRNG) instance - pub fn new<'d>( - rng: impl Peripheral

, - _adc: impl Peripheral

+ 'd, - ) -> Self { - crate::soc::trng::ensure_randomness(); - Self { - _phantom: PhantomData, + #[inline] + /// Reads currently available `u32` integer from `RNG` + pub fn random(&mut self) -> u32 { + // SAFETY: read-only register access + unsafe { &*crate::peripherals::RNG::PTR } + .data() + .read() + .bits() + } + + #[inline] + /// Reads enough bytes from hardware random number generator to fill + /// `buffer`. + /// + /// If any error is encountered then this function immediately returns. The + /// contents of buf are unspecified in this case. + /// + /// If this function returns an error, it is unspecified how many bytes it + /// has read, but it will never read more than would be necessary to + /// completely fill the buffer. + pub fn read(&mut self, buffer: &mut [u8]) { + for chunk in buffer.chunks_mut(4) { + let bytes = self.random().to_le_bytes(); + chunk.copy_from_slice(&bytes[..chunk.len()]); } } } #[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::blocking::rng::Read for Rng { +impl embedded_hal_02::blocking::rng::Read for Rng { type Error = core::convert::Infallible; fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> { @@ -93,7 +98,7 @@ impl embedded_hal_02::blocking::rng::Read for Rng { } } -impl rand_core::RngCore for Rng { +impl rand_core::RngCore for Rng { fn next_u32(&mut self) -> u32 { self.random() } @@ -115,24 +120,49 @@ impl rand_core::RngCore for Rng { } } -// Common RNG functionality that applies to both basic and true RNG -impl Rng { - pub fn read(&mut self, buffer: &mut [u8]) { - for chunk in buffer.chunks_mut(4) { - let bytes = self.random().to_le_bytes(); - chunk.copy_from_slice(&bytes[..chunk.len()]); +#[cfg(not(esp32p4))] +pub struct Trng<'d>{ + pub rng: Rng, + adc: PeripheralRef<'d, crate::peripherals::ADC1>, +} + +#[cfg(not(esp32p4))] +impl<'d> Trng<'d> { + /// Create a new True Random Number Generator instance + pub fn new(rng: impl Peripheral

, adc: impl Peripheral

+ 'd) -> Self { + crate::into_ref!(adc); + let gen = Rng::new(rng); + crate::soc::trng::ensure_randomness(); + Self{ + rng: gen, + adc, } } - /// Reads currently available `u32` integer from `RNG` pub fn random(&mut self) -> u32 { - // SAFETY: read-only register access - unsafe { &*crate::peripherals::RNG::PTR } - .data() - .read() - .bits() + self.rng.random() + } + + pub fn read(&mut self, buffer: &mut [u8]) { + self.rng.read(buffer) + } + + /// Downgrade Trng to Rng and release ADC1 + pub fn downgrade(self) -> (Rng, PeripheralRef<'d, crate::peripherals::ADC1>) { + crate::soc::trng::revert_trng(); + (self.rng, self.adc) + } +} + +#[cfg(feature = "embedded-hal-02")] +impl embedded_hal_02::blocking::rng::Read for Trng { + type Error = core::convert::Infallible; + + fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> { + self.rng.read(buffer); + Ok(()) } } #[cfg(not(esp32p4))] -impl rand_core::CryptoRng for Rng {} +impl rand_core::CryptoRng for Trng<'_> {} diff --git a/esp-hal/src/soc/esp32/trng.rs b/esp-hal/src/soc/esp32/trng.rs new file mode 100644 index 00000000000..d18825688e7 --- /dev/null +++ b/esp-hal/src/soc/esp32/trng.rs @@ -0,0 +1,186 @@ +const DR_REG_RTCCNTL_BASE: u32 = 0x3ff48000; +const RTC_CNTL_TEST_MUX_REG: u32 = DR_REG_RTCCNTL_BASE + 0xa8; +const RTC_CNTL_DTEST_RTC: u32 = 0x00000003; +const RTC_CNTL_DTEST_RTC_S: u32 = 30; +const RTC_CNTL_ENT_RTC: u32 = 1 << 29; +const SENS_SAR_START_FORCE_REG: u32 = 0x3ff48800 + 0x002c; +const SENS_SAR2_EN_TEST: u32 = 1 << 4; +const DPORT_PERIP_CLK_EN_REG: u32 = 0x3ff00000 + 0x0c0; +const DPORT_I2C_EXT0_CLK_EN: u32 = 1 << 7; + +const DPORT_PERIP_RST_EN_REG: u32 = 0x3ff00000 + 0x0c4; +const DPORT_I2C_EXT0_RST: u32 = 1 << 7; + +const SENS_ULP_CP_FORCE_START_TOP: u32 = 1 << 8; +const SENS_ULP_CP_START_TOP: u32 = 1 << 9; + +const DR_REG_I2S_BASE: u32 = 0x3ff4f000; + +const DR_REG_SYSCON_BASE: u32 = 0x3ff66000; +const SYSCON_SARADC_CTRL_REG: u32 = DR_REG_SYSCON_BASE + 0x10; +const SYSCON_SARADC_FSM_REG: u32 = DR_REG_SYSCON_BASE + 0x18; +const SYSCON_SARADC_SAR2_PATT_TAB1_REG: u32 = DR_REG_SYSCON_BASE + 0x2c; +const SYSCON_SARADC_SAR2_PATT_TAB2_REG: u32 = DR_REG_SYSCON_BASE + 0x30; +const SYSCON_SARADC_SAR2_PATT_TAB3_REG: u32 = DR_REG_SYSCON_BASE + 0x34; +const SYSCON_SARADC_SAR2_PATT_TAB4_REG: u32 = DR_REG_SYSCON_BASE + 0x38; +const SYSCON_SARADC_SAR2_MUX: u32 = 1 << 2; +const SYSCON_SARADC_SAR_CLK_DIV: u32 = 0x000000FF; +const SYSCON_SARADC_SAR_CLK_DIV_S: u32 = 7; +const SYSCON_SARADC_RSTB_WAIT: u32 = 0x000000FF; +const SYSCON_SARADC_RSTB_WAIT_S: u32 = 0; +const SYSCON_SARADC_START_WAIT: u32 = 1 << 2; +const SYSCON_SARADC_START_WAIT_S: u32 = 1 << 2; +const SYSCON_SARADC_WORK_MODE: u32 = 0x00000003; +const SYSCON_SARADC_WORK_MODE_S: u32 = 3; +const SYSCON_SARADC_SAR_SEL: u32 = 1 << 5; +const I2S_RX_BCK_DIV_NUM: u32 = 0x0000003F; +const I2S_RX_BCK_DIV_NUM_S: u32 = 6; +const SYSCON_SARADC_DATA_TO_I2S: u32 = 1 << 16; +const SYSCON_SARADC_DATA_SAR_SEL: u32 = 1 << 25; + +const I2S_CAMERA_EN: u32 = 1 << 0; +const I2S_LCD_EN: u32 = 1 << 5; +const I2S_DATA_ENABLE: u32 = 1 << 4; +const I2S_DATA_ENABLE_TEST_EN: u32 = 1 << 3; +const I2S_RX_START: u32 = 1 << 5; +const I2S_RX_RESET: u32 = 1 << 1; + +const DR_REG_SENS_BASE: u32 = 0x3ff48800; +const SENS_SAR_MEAS_WAIT2_REG: u32 = DR_REG_SENS_BASE + 0x000c; +const SENS_SAR_READ_CTRL_REG: u32 = DR_REG_SENS_BASE; +const SENS_SAR_READ_CTRL2_REG: u32 = DR_REG_SENS_BASE + 0x0090; +const SENS_FORCE_XPD_SAR: u32 = 0x00000003; +const SENS_FORCE_XPD_SAR_S: u32 = 18; +const SENS_SAR1_DIG_FORCE: u32 = 1 << 27; +const SENS_SAR2_DIG_FORCE: u32 = 1 << 28; + +const I2S_CONF_REG0: u32 = DR_REG_I2S_BASE + 0x00a8; + +pub fn ensure_randomness() { + set_peri_reg_bits( + RTC_CNTL_TEST_MUX_REG, + RTC_CNTL_DTEST_RTC, + 2, + RTC_CNTL_DTEST_RTC_S, + ); + + set_peri_reg_mask(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC); + set_peri_reg_mask(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST); + + // periph_module_enable(PERIPH_I2S0_MODULE); + set_peri_reg_mask(DPORT_PERIP_CLK_EN_REG, DPORT_I2C_EXT0_CLK_EN); + clear_peri_reg_mask(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT0_RST); + + clear_peri_reg_mask(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP); + clear_peri_reg_mask(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_START_TOP); + + // Test pattern configuration byte 0xAD: + //--[7:4] channel_sel: 10-->en_test + //--[3:2] bit_width : 3-->12bit + //--[1:0] atten : 1-->3dB attenuation + write_peri_reg(SYSCON_SARADC_SAR2_PATT_TAB1_REG, 0xADADADAD); + write_peri_reg(SYSCON_SARADC_SAR2_PATT_TAB2_REG, 0xADADADAD); + write_peri_reg(SYSCON_SARADC_SAR2_PATT_TAB3_REG, 0xADADADAD); + write_peri_reg(SYSCON_SARADC_SAR2_PATT_TAB4_REG, 0xADADADAD); + + set_peri_reg_bits( + SENS_SAR_MEAS_WAIT2_REG, + SENS_FORCE_XPD_SAR, + 3, + SENS_FORCE_XPD_SAR_S, + ); + + set_peri_reg_mask(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE); + set_peri_reg_mask(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE); + + set_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX); + set_peri_reg_bits( + SYSCON_SARADC_CTRL_REG, + SYSCON_SARADC_SAR_CLK_DIV, + 4, + SYSCON_SARADC_SAR_CLK_DIV_S, + ); + set_peri_reg_bits( + SYSCON_SARADC_FSM_REG, + SYSCON_SARADC_RSTB_WAIT, + 8, + SYSCON_SARADC_RSTB_WAIT_S, + ); + set_peri_reg_bits( + SYSCON_SARADC_FSM_REG, + SYSCON_SARADC_START_WAIT, + 10, + SYSCON_SARADC_START_WAIT_S, + ); + set_peri_reg_bits( + SYSCON_SARADC_CTRL_REG, + SYSCON_SARADC_WORK_MODE, + 0, + SYSCON_SARADC_WORK_MODE_S, + ); + + set_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL); + clear_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_SAR_SEL); + + set_peri_reg_bits( + DR_REG_I2S_BASE + 0x00b0, + I2S_RX_BCK_DIV_NUM, + 20, + I2S_RX_BCK_DIV_NUM_S, + ); + + set_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_TO_I2S); + + clear_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_CAMERA_EN); + set_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_LCD_EN); + set_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_DATA_ENABLE); + set_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_DATA_ENABLE_TEST_EN); + set_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_RX_START); +} + +pub fn revert_trng() +{ + clear_peri_reg_mask(I2S_CONF_REG0, I2S_RX_START); + set_peri_reg_mask(I2S_CONF_REG0, I2S_RX_RESET); + clear_peri_reg_mask(I2S_CONF_REG0, I2S_RX_RESET); + clear_peri_reg_mask(I2S_CONF_REG0, I2S_CAMERA_EN); + clear_peri_reg_mask(I2S_CONF_REG0, I2S_LCD_EN); + clear_peri_reg_mask(I2S_CONF_REG0, I2S_DATA_ENABLE_TEST_EN); + clear_peri_reg_mask(I2S_CONF_REG0, I2S_DATA_ENABLE); + + clear_peri_reg_mask(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE); + clear_peri_reg_mask(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE); + + clear_peri_reg_mask(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST); + clear_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX | SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S); + + set_peri_reg_bits(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S); + + set_peri_reg_bits(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 8, SYSCON_SARADC_START_WAIT_S); +} + +fn set_peri_reg_bits(reg: u32, bitmap: u32, value: u32, shift: u32) { + unsafe { + (reg as *mut u32).write_volatile( + ((reg as *mut u32).read_volatile() & !(bitmap << shift)) | ((value & bitmap) << shift), + ); + } +} + +fn set_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + } +} + +fn clear_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + } +} + +fn write_peri_reg(reg: u32, val: u32) { + unsafe { + (reg as *mut u32).write_volatile(val); + } +} \ No newline at end of file diff --git a/esp-hal/src/soc/esp32c2/trng.rs b/esp-hal/src/soc/esp32c2/trng.rs new file mode 100644 index 00000000000..3a4a22fc49c --- /dev/null +++ b/esp-hal/src/soc/esp32c2/trng.rs @@ -0,0 +1,202 @@ +const DR_REG_RTCCNTL_BASE: u32 = 0x60008000; +const RTC_CNTL_SENSOR_CTRL_REG: u32 = DR_REG_RTCCNTL_BASE + 0x108; +const RTC_CNTL_FORCE_XPD_SAR_V: u32 = 0x3; +const RTC_CNTL_FORCE_XPD_SAR_S: u32 = 30; +const RTC_CNTL_ANA_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x2c; +const RTC_CNTL_SAR_I2C_PU_M: u32 = 1 << 22; + +const I2C_SAR_ADC: u8 = 0x69; +const I2C_SAR_ADC_HOSTID: u8 = 0; +const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7; +const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 6; +const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 6; +const ADC_SARADC_DTEST_RTC_ADDR: u8 = 0x7; +const ADC_SARADC_DTEST_RTC_ADDR_MSB: u8 = 1; +const ADC_SARADC_DTEST_RTC_ADDR_LSB: u8 = 0; +const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x7; +const ADC_SARADC_ENT_RTC_ADDR_MSB: u8 = 3; +const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 3; +const ADC_SARADC_ENT_TSENS_ADDR: u8 = 0x07; +const ADC_SARADC_ENT_TSENS_ADDR_MSB: u8 = 2; +const ADC_SARADC_ENT_TSENS_ADDR_LSB: u8 = 2; + +const DR_REG_SYSTEM_BASE: u32 = 0x600c0000; +const SYSTEM_PERIP_CLK_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x10; +const SYSTEM_PERIP_RST_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x18; +const APB_SARADC_CLK_EN_M: u32 = 0x00000001 << 28; +const DR_REG_APB_SARADC_BASE: u32 = 0x60040000; +const APB_SARADC_APB_ADC_CLKM_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x54; +const APB_SARADC_REG_CLK_SEL_V: u32 = 0x00000003; +const APB_SARADC_REG_CLK_SEL_S: u32 = 21; +const APB_SARADC_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE; +const APB_SARADC_SAR_PATT_P_CLEAR_M: u32 = 0x00000001 << 23; +const APB_SARADC_SAR_PATT_LEN_V: u32 = 0x00000007; +const APB_SARADC_SAR_PATT_LEN_S: u32 = 15; +const APB_SARADC_SAR_CLK_GATED_M: u32 = 0x00000001 << 6; +const APB_SARADC_XPD_SAR_FORCE_V: u32 = 0x00000003; +const APB_SARADC_XPD_SAR_FORCE_S: u32 = 27; +const APB_SARADC_SAR_CLK_DIV_V: u32 = 0x000000FF; +const APB_SARADC_SAR_CLK_DIV_S: u32 = 7; +const APB_SARADC_SAR_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x18; +const APB_SARADC_SAR_PATT_TAB2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x1c; +const APB_SARADC_SAR_PATT_TAB1_V: u32 = 0x00FFFFFF; +const APB_SARADC_SAR_PATT_TAB1_S: u32 = 0; +const APB_SARADC_SAR_PATT_TAB2_V: u32 = 0x00FFFFFF; +const APB_SARADC_SAR_PATT_TAB2_S: u32 = 0; +const APB_SARADC_CTRL2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x4; +const APB_SARADC_TIMER_TARGET_V: u32 = 0x00000FFF; +const APB_SARADC_TIMER_TARGET_S: u32 = 12; +const APB_SARADC_REG_CLKM_DIV_NUM_V: u32 = 0x000000FF; +const APB_SARADC_REG_CLKM_DIV_NUM_S: u32 = 0; +const APB_SARADC_MEAS_NUM_LIMIT: u32 = 1 << 0; +const APB_SARADC_DMA_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x50; +const APB_SARADC_APB_ADC_TRANS_M: u32 = 0x00000001 << 31; +const APB_SARADC_TIMER_EN: u32 = 1 << 24; +const APB_SARADC_FSM_WAIT_REG: u32 = DR_REG_APB_SARADC_BASE + 0xc; +const APB_SARADC_RSTB_WAIT_V: u32 = 0x000000FF; +const APB_SARADC_RSTB_WAIT_S: u32 = 8; +const APB_SARADC_XPD_WAIT_V: u32 = 0x000000FF; +const APB_SARADC_XPD_WAIT_S: u32 = 0; +const APB_SARADC_STANDBY_WAIT_V: u32 = 0x000000FF; +const APB_SARADC_STANDBY_WAIT_S: u32 = 16; +const SYSTEM_APB_SARADC_RST_M: u32 = 0x00000001 << 28; +const SYSTEM_APB_SARADC_CLK_EN_M: u32 = 0x00000001 << 28; + +use crate::regi2c_write_mask; + +pub(crate) fn ensure_randomness() { + // RNG module is always clock enabled + reg_set_field( + RTC_CNTL_SENSOR_CTRL_REG, + RTC_CNTL_FORCE_XPD_SAR_V, + RTC_CNTL_FORCE_XPD_SAR_S, + 0x3, + ); + + set_peri_reg_mask(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M); + + // Bridging sar2 internal reference voltage + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); + + // Enable SAR ADC2 internal channel to read adc2 ref voltage for additional + // entropy + set_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN_M); + clear_peri_reg_mask(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST_M); + reg_set_field( + APB_SARADC_APB_ADC_CLKM_CONF_REG, + APB_SARADC_REG_CLK_SEL_V, + APB_SARADC_REG_CLK_SEL_S, + 0x2, + ); + set_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); + set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED_M); + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_XPD_SAR_FORCE_V, + APB_SARADC_XPD_SAR_FORCE_S, + 0x3, + ); + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SAR_CLK_DIV_V, + APB_SARADC_SAR_CLK_DIV_S, + 1, + ); + + reg_set_field( + APB_SARADC_FSM_WAIT_REG, + APB_SARADC_RSTB_WAIT_V, + APB_SARADC_RSTB_WAIT_S, + 8, + ); + + reg_set_field( + APB_SARADC_FSM_WAIT_REG, + APB_SARADC_XPD_WAIT_V, + APB_SARADC_XPD_WAIT_S, + 5, + ); + + reg_set_field( + APB_SARADC_FSM_WAIT_REG, + APB_SARADC_STANDBY_WAIT_V, + APB_SARADC_STANDBY_WAIT_S, + 100, + ); + + set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); + clear_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SAR_PATT_LEN_V, + APB_SARADC_SAR_PATT_LEN_S, + 0, + ); + + reg_set_field( + APB_SARADC_SAR_PATT_TAB1_REG, + APB_SARADC_SAR_PATT_TAB1_V, + APB_SARADC_SAR_PATT_TAB1_S, + 0x9cffff, + ); + reg_set_field( + APB_SARADC_SAR_PATT_TAB2_REG, + APB_SARADC_SAR_PATT_TAB2_V, + APB_SARADC_SAR_PATT_TAB2_S, + 0x9cffff, + ); + + reg_set_field( + APB_SARADC_CTRL2_REG, + APB_SARADC_TIMER_TARGET_V, + APB_SARADC_TIMER_TARGET_S, + 100, + ); + reg_set_field( + APB_SARADC_APB_ADC_CLKM_CONF_REG, + APB_SARADC_REG_CLKM_DIV_NUM_V, + APB_SARADC_REG_CLKM_DIV_NUM_S, + 15, + ); + clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT); + set_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); + set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); +} + +pub(crate) fn revert_trng() { + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); + clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); + clear_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); + reg_set_field(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1_V, APB_SARADC_SAR_PATT_TAB1_S, 0xffffff); + reg_set_field(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2_V, APB_SARADC_SAR_PATT_TAB2_S, 0xffffff); + clear_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); + reg_set_field(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE_V, APB_SARADC_XPD_SAR_FORCE_S, 0); + reg_set_field(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR_V, RTC_CNTL_FORCE_XPD_SAR_S, 0); +} + +fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { + unsafe { + (reg as *mut u32).write_volatile( + ((reg as *mut u32).read_volatile() & !(field_v << field_s)) + | ((value & field_v) << field_s), + ) + } +} + +fn set_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + } +} + +fn clear_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + } +} diff --git a/esp-hal/src/soc/esp32c3/trng.rs b/esp-hal/src/soc/esp32c3/trng.rs new file mode 100644 index 00000000000..a330e1fa434 --- /dev/null +++ b/esp-hal/src/soc/esp32c3/trng.rs @@ -0,0 +1,205 @@ +const DR_REG_RTCCNTL_BASE: u32 = 0x60008000; +const RTC_CNTL_SENSOR_CTRL_REG: u32 = DR_REG_RTCCNTL_BASE + 0x011C; +const RTC_CNTL_FORCE_XPD_SAR_V: u32 = 0x3; +const RTC_CNTL_FORCE_XPD_SAR_S: u32 = 30; +const RTC_CNTL_ANA_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x0034; +const RTC_CNTL_SAR_I2C_PU_M: u32 = 1 << 22; + +const I2C_SAR_ADC: u8 = 0x69; +const I2C_SAR_ADC_HOSTID: u8 = 0; +const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7; +const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 6; +const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 6; +const ADC_SARADC_DTEST_RTC_ADDR: u8 = 0x7; +const ADC_SARADC_DTEST_RTC_ADDR_MSB: u8 = 1; +const ADC_SARADC_DTEST_RTC_ADDR_LSB: u8 = 0; +const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x7; +const ADC_SARADC_ENT_RTC_ADDR_MSB: u8 = 3; +const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 3; +const ADC_SARADC_ENT_TSENS_ADDR: u8 = 0x07; +const ADC_SARADC_ENT_TSENS_ADDR_MSB: u8 = 2; +const ADC_SARADC_ENT_TSENS_ADDR_LSB: u8 = 2; + +const DR_REG_SYSTEM_BASE: u32 = 0x600c0000; +const SYSTEM_PERIP_CLK_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x010; +const SYSTEM_PERIP_RST_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x018; +const APB_SARADC_CLK_EN_M: u32 = 0x00000001 << 20; +const DR_REG_APB_SARADC_BASE: u32 = 0x60040000; +const APB_SARADC_APB_ADC_CLKM_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x054; +const APB_SARADC_CLK_SEL_V: u32 = 0x00000003; +const APB_SARADC_CLK_SEL_S: u32 = 21; +const APB_SARADC_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE; +const APB_SARADC_SAR_PATT_P_CLEAR_M: u32 = 1 << 23; +const APB_SARADC_SAR_PATT_LEN_V: u32 = 7; +const APB_SARADC_SAR_PATT_LEN_S: u32 = 15; +const APB_SARADC_SAR_CLK_GATED_M: u32 = 1 << 6; +const APB_SARADC_XPD_SAR_FORCE_V: u32 = 0x3; +const APB_SARADC_XPD_SAR_FORCE_S: u32 = 27; +const APB_SARADC_SAR_CLK_DIV_V: u32 = 0xFF; +const APB_SARADC_SAR_CLK_DIV_S: u32 = 7; +const APB_SARADC_SAR_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x018; +const APB_SARADC_SAR_PATT_TAB2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x01c; +const APB_SARADC_SAR_PATT_TAB1_V: u32 = 0xFFFFFF; +const APB_SARADC_SAR_PATT_TAB1_S: u32 = 0; +const APB_SARADC_SAR_PATT_TAB2_V: u32 = 0xFFFFFF; +const APB_SARADC_SAR_PATT_TAB2_S: u32 = 0; +const APB_SARADC_CTRL2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x004; +const APB_SARADC_TIMER_TARGET_V: u32 = 0xFFF; +const APB_SARADC_TIMER_TARGET_S: u32 = 12; +const APB_SARADC_CLKM_DIV_NUM_V: u32 = 0xFF; +const APB_SARADC_CLKM_DIV_NUM_S: u32 = 0; +const APB_SARADC_MEAS_NUM_LIMIT: u32 = 1 << 0; +const APB_SARADC_DMA_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x050; +const APB_SARADC_APB_ADC_TRANS_M: u32 = 1 << 31; +const APB_SARADC_TIMER_EN: u32 = 1 << 24; +const APB_SARADC_FSM_WAIT_REG: u32 = DR_REG_APB_SARADC_BASE + 0x00c; +const APB_SARADC_RSTB_WAIT_V: u32 = 0xFF; +const APB_SARADC_RSTB_WAIT_S: u32 = 8; +const APB_SARADC_XPD_WAIT_V: u32 = 0xFF; +const APB_SARADC_XPD_WAIT_S: u32 = 0; +const APB_SARADC_STANDBY_WAIT_V: u32 = 0xFF; +const APB_SARADC_STANDBY_WAIT_S: u32 = 16; +const SYSTEM_APB_SARADC_RST_M: u32 = 1 << 28; +const SYSTEM_APB_SARADC_CLK_EN_M: u32 = 1 << 28; + +use crate::regi2c_write_mask; + +pub(crate) fn ensure_randomness() { + // RNG module is always clock enabled + reg_set_field( + RTC_CNTL_SENSOR_CTRL_REG, + RTC_CNTL_FORCE_XPD_SAR_V, + RTC_CNTL_FORCE_XPD_SAR_S, + 0x3, + ); + + set_peri_reg_mask(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M); + + // Bridging sar2 internal reference voltage + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); + + // Enable SAR ADC2 internal channel to read adc2 ref voltage for additional + // entropy + set_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN_M); + clear_peri_reg_mask(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST_M); + reg_set_field( + APB_SARADC_APB_ADC_CLKM_CONF_REG, + APB_SARADC_CLK_SEL_V, + APB_SARADC_CLK_SEL_S, + 0x2, + ); + set_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); + set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED_M); + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_XPD_SAR_FORCE_V, + APB_SARADC_XPD_SAR_FORCE_S, + 0x3, + ); + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SAR_CLK_DIV_V, + APB_SARADC_SAR_CLK_DIV_S, + 1, + ); + + reg_set_field( + APB_SARADC_FSM_WAIT_REG, + APB_SARADC_RSTB_WAIT_V, + APB_SARADC_RSTB_WAIT_S, + 8, + ); + + reg_set_field( + APB_SARADC_FSM_WAIT_REG, + APB_SARADC_XPD_WAIT_V, + APB_SARADC_XPD_WAIT_S, + 5, + ); + + reg_set_field( + APB_SARADC_FSM_WAIT_REG, + APB_SARADC_STANDBY_WAIT_V, + APB_SARADC_STANDBY_WAIT_S, + 100, + ); + + set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); + clear_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SAR_PATT_LEN_V, + APB_SARADC_SAR_PATT_LEN_S, + 0, + ); + + reg_set_field( + APB_SARADC_SAR_PATT_TAB1_REG, + APB_SARADC_SAR_PATT_TAB1_V, + APB_SARADC_SAR_PATT_TAB1_S, + 0x9cffff, + ); + reg_set_field( + APB_SARADC_SAR_PATT_TAB2_REG, + APB_SARADC_SAR_PATT_TAB2_V, + APB_SARADC_SAR_PATT_TAB2_S, + 0x9cffff, + ); + + reg_set_field( + APB_SARADC_CTRL2_REG, + APB_SARADC_TIMER_TARGET_V, + APB_SARADC_TIMER_TARGET_S, + 100, + ); + reg_set_field( + APB_SARADC_APB_ADC_CLKM_CONF_REG, + APB_SARADC_CLKM_DIV_NUM_V, + APB_SARADC_CLKM_DIV_NUM_S, + 15, + ); + clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT); + set_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); + set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); +} + +pub(crate) fn ensure_randomness() { + /* Restore internal I2C bus state */ + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); + + /* Restore SARADC to default mode */ + clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); + clear_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); + reg_set_field(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1_V, APB_SARADC_SAR_PATT_TAB1_S, 0xffffff); + reg_set_field(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2_V, APB_SARADC_SAR_PATT_TAB2_S, 0xffffff); + clear_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); + reg_set_field(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE_V, APB_SARADC_XPD_SAR_FORCE_S, 0); + reg_set_field(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR_V, RTC_CNTL_FORCE_XPD_SAR_S, 0); +} + +fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { + unsafe { + (reg as *mut u32).write_volatile( + ((reg as *mut u32).read_volatile() & !(field_v << field_s)) + | ((value & field_v) << field_s), + ) + } +} + +fn set_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + } +} + +fn clear_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + } +} \ No newline at end of file diff --git a/esp-hal/src/soc/esp32c6/trng.rs b/esp-hal/src/soc/esp32c6/trng.rs new file mode 100644 index 00000000000..35162e9f4ab --- /dev/null +++ b/esp-hal/src/soc/esp32c6/trng.rs @@ -0,0 +1,363 @@ +const PCR_SARADC_CONF_REG: u32 = 0x60096000 + 0x80; +const PCR_SARADC_RST_EN: u32 = 1 << 1; +const PCR_SARADC_REG_CLK_EN: u32 = 1 << 2; +const PCR_SARADC_CLKM_CONF_REG: u32 = 0x60096000 + 0x84; +const PCR_SARADC_CLKM_EN: u32 = 1 << 22; +const PMU_RF_PWC_REG: u32 = 0x600B0000 + 0x154; +const I2C_SAR_ADC: u8 = 0x69; +const I2C_SAR_ADC_HOSTID: u8 = 0; +const ADC_SARADC_HOST_ADDR: u8 = 0x7; +const DTEST_RTC_MSB: u8 = 1; +const DTEST_RTC_LSB: u8 = 0; +const ENT_RTC_MSB: u8 = 3; +const ENT_RTC_LSB: u8 = 3; +const SARADC1_ENCAL_REF_MSB: u8 = 4; +const SARADC1_ENCAL_REF_LSB: u8 = 4; +const SARADC2_ENCAL_REF_MSB: u8 = 6; +const SARADC2_ENCAL_REF_LSB: u8 = 6; +const SAR2_CHANNEL: u32 = 9; +const SAR2_ATTEN: u32 = 1; +const SAR1_ATTEN: u32 = 1; +const PATTERN_BIT_WIDTH: u32 = 6; +const APB_SARADC_SAR_PATT_TAB1_REG: u32 = 0x60040000 + 0x18; +const APB_SARADC_CTRL_REG: u32 = 0x60040000; +const APB_SARADC_CTRL2_REG: u32 = 0x60040000 + 0x4; + +const DR_REG_MODEM_LPCON_BASE: u32 = 0x600AF000; +const MODEM_LPCON_CLK_CONF_REG: u32 = DR_REG_MODEM_LPCON_BASE + 0x18; +const MODEM_LPCON_CLK_I2C_MST_EN: u32 = 1 << 2; +const DR_REG_LP_I2C_ANA_MST_BASE: u32 = 0x600B2400; +const LP_I2C_ANA_MST_DATE_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x3fc; +const LP_I2C_ANA_MST_I2C_MAT_CLK_EN: u32 = 1 << 28; + +const REGI2C_BBPLL: u8 = 0x66; +const REGI2C_BIAS: u8 = 0x6a; +const REGI2C_DIG_REG: u8 = 0x6d; +const REGI2C_ULP_CAL: u8 = 0x61; +const REGI2C_SAR_I2C: u8 = 0x69; + +const LP_I2C_ANA_MST_DEVICE_EN_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x14; +const REGI2C_BBPLL_DEVICE_EN: u32 = 1 << 5; +const REGI2C_BIAS_DEVICE_EN: u32 = 1 << 4; +const REGI2C_DIG_REG_DEVICE_EN: u32 = 1 << 8; +const REGI2C_ULP_CAL_DEVICE_EN: u32 = 1 << 6; +const REGI2C_SAR_I2C_DEVICE_EN: u32 = 1 << 7; +const REGI2C_RTC_SLAVE_ID_V: u8 = 0xFF; +const REGI2C_RTC_SLAVE_ID_S: u8 = 0; +const REGI2C_RTC_ADDR_V: u8 = 0xFF; +const REGI2C_RTC_ADDR_S: u8 = 8; +const REGI2C_RTC_WR_CNTL_V: u8 = 0x1; +const REGI2C_RTC_WR_CNTL_S: u8 = 24; +const REGI2C_RTC_DATA_V: u8 = 0xFF; +const REGI2C_RTC_DATA_S: u8 = 16; + +const LP_I2C_ANA_MST_I2C0_CTRL_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE; +const LP_I2C_ANA_MST_I2C0_BUSY: u32 = 1 << 25; + +const LP_I2C_ANA_MST_I2C0_DATA_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x8; +const LP_I2C_ANA_MST_I2C0_RDATA_V: u32 = 0x000000FF; +const LP_I2C_ANA_MST_I2C0_RDATA_S: u32 = 0; + +const PCR_SARADC_CLKM_SEL_V: u32 = 0x00000003; +const PCR_SARADC_CLKM_SEL_S: u32 = 20; + +const PCR_SARADC_CLKM_DIV_NUM_V: u32 = 0x000000FF; +const PCR_SARADC_CLKM_DIV_NUM_S: u32 = 12; + +const PMU_PERIF_I2C_RSTB: u32 = 1 << 26; +const PMU_XPD_PERIF_I2C: u32 = 1 << 27; + +const ADC_SARADC_DTEST_RTC_ADDR: u8 = 0x4; +const ADC_SARADC_DTEST_RTC_ADDR_MSB: u8 = 0x3; +const ADC_SARADC_DTEST_RTC_ADDR_LSB: u8 = 0x0; + +const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x3; +const ADC_SARADC_ENT_RTC_ADDR_MSB: u8 = 0x7; +const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 0x0; + +const ADC_SARADC1_ENCAL_REF_ADDR: u8 = 0x1; +const ADC_SARADC1_ENCAL_REF_ADDR_MSB: u8 = 0x3; +const ADC_SARADC1_ENCAL_REF_ADDR_LSB: u8 = 0x0; + +const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x0; +const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 0x7; +const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 0x0; + +const APB_SARADC_SARADC_SAR_PATT_LEN_V: u32 = 0x00000007; +const APB_SARADC_SARADC_SAR_PATT_LEN_S: u32 = 15; +const APB_SARADC_SARADC_SAR_CLK_DIV_V: u32 = 0x000000FF; +const APB_SARADC_SARADC_SAR_CLK_DIV_S: u32 = 7; +const APB_SARADC_SARADC_TIMER_TARGET_V: u32 = 0x00000FFF; +const APB_SARADC_SARADC_TIMER_TARGET_S: u32 = 12; +const APB_SARADC_SARADC_TIMER_EN: u32 = 1 << 24; + +pub(crate) fn ensure_randomness() { + // Pull SAR ADC out of reset + reg_set_bit(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); + reg_clr_bit(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); + + // Enable SAR ADC APB clock + reg_set_bit(PCR_SARADC_CONF_REG, PCR_SARADC_REG_CLK_EN); + + // Enable ADC_CTRL_CLK (SAR ADC function clock) + reg_set_bit(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_EN); + + // Select XTAL clock (40 MHz) source for ADC_CTRL_CLK + reg_set_field( + PCR_SARADC_CLKM_CONF_REG, + PCR_SARADC_CLKM_SEL_V, + PCR_SARADC_CLKM_SEL_S, + 0, + ); + + // Set the clock divider for ADC_CTRL_CLK to default value (in case it has been + // changed) + reg_set_field( + PCR_SARADC_CLKM_CONF_REG, + PCR_SARADC_CLKM_DIV_NUM_V, + PCR_SARADC_CLKM_DIV_NUM_S, + 0, + ); + + // some ADC sensor registers are in power group PERIF_I2C and need to be enabled + // via PMU + set_peri_reg_mask(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); + set_peri_reg_mask(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); + + // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal + // voltage as sampling source + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_HOST_ADDR, + DTEST_RTC_MSB, + DTEST_RTC_LSB, + 2, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_HOST_ADDR, + ENT_RTC_MSB, + ENT_RTC_LSB, + 1, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_HOST_ADDR, + SARADC1_ENCAL_REF_MSB, + SARADC1_ENCAL_REF_LSB, + 1, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_HOST_ADDR, + SARADC2_ENCAL_REF_MSB, + SARADC2_ENCAL_REF_LSB, + 1, + ); + + // SAR2 High ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_DTEST_RTC_ADDR, + ADC_SARADC_DTEST_RTC_ADDR_MSB, + ADC_SARADC_DTEST_RTC_ADDR_LSB, + 0x08, + ); + // SAR2 Low ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_RTC_ADDR, + ADC_SARADC_ENT_RTC_ADDR_MSB, + ADC_SARADC_ENT_RTC_ADDR_LSB, + 0x66, + ); + // SAR1 High ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC1_ENCAL_REF_ADDR, + ADC_SARADC1_ENCAL_REF_ADDR_MSB, + ADC_SARADC1_ENCAL_REF_ADDR_LSB, + 0x08, + ); + // SAR1 Low ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC2_ENCAL_REF_ADDR, + ADC_SARADC2_ENCAL_REF_ADDR_MSB, + ADC_SARADC2_ENCAL_REF_ADDR_LSB, + 0x66, + ); + + // create patterns and set them in pattern table + let pattern_one: u32 = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation + let pattern_two: u32 = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here + let pattern_table: u32 = + (pattern_two << (3 * PATTERN_BIT_WIDTH)) | (pattern_one << (2 * PATTERN_BIT_WIDTH)); + + reg_write(APB_SARADC_SAR_PATT_TAB1_REG, pattern_table); + + // set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0) + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SARADC_SAR_PATT_LEN_V, + APB_SARADC_SARADC_SAR_PATT_LEN_S, + 1, + ); + + // Same as in C3 + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SARADC_SAR_CLK_DIV_V, + APB_SARADC_SARADC_SAR_CLK_DIV_S, + 15, + ); + + // set timer expiry (timer is ADC_CTRL_CLK) + reg_set_field( + APB_SARADC_CTRL2_REG, + APB_SARADC_SARADC_TIMER_TARGET_V, + APB_SARADC_SARADC_TIMER_TARGET_S, + 200, + ); + + // enable timer + reg_set_bit(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); +} + +pub(crate) fn ensure_randomness() { + reg_clr_bit(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); + reg_write(APB_SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC2_ENCAL_REF_ADDR, + ADC_SARADC2_ENCAL_REF_ADDR_MSB, + ADC_SARADC2_ENCAL_REF_ADDR_LSB, + 0x66, + ); + + regi2c_write_mask(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, HIGH) +} + +fn reg_set_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); + } +} + +fn reg_clr_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !bit); + } +} + +fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { + unsafe { + (reg as *mut u32).write_volatile( + ((reg as *mut u32).read_volatile() & !(field_v << field_s)) + | ((value & field_v) << field_s), + ) + } +} + +fn set_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + } +} +fn reg_write(reg: u32, v: u32) { + unsafe { + (reg as *mut u32).write_volatile(v); + } +} + +fn reg_get_bit(reg: u32, b: u32) -> u32 { + unsafe { (reg as *mut u32).read_volatile() & b } +} + +fn reg_get_field(reg: u32, s: u32, v: u32) -> u32 { + unsafe { ((reg as *mut u32).read_volatile() >> s) & v } +} + +fn regi2c_enable_block(block: u8) { + reg_set_bit(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); + reg_set_bit(LP_I2C_ANA_MST_DATE_REG, LP_I2C_ANA_MST_I2C_MAT_CLK_EN); + + // Before config I2C register, enable corresponding slave. + match block { + v if v == REGI2C_BBPLL => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); + } + v if v == REGI2C_BIAS => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); + } + v if v == REGI2C_DIG_REG => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); + } + v if v == REGI2C_ULP_CAL => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); + } + v if v == REGI2C_SAR_I2C => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); + } + _ => (), + } +} + +fn regi2c_disable_block(block: u8) { + match block { + v if v == REGI2C_BBPLL => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); + } + v if v == REGI2C_BIAS => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); + } + v if v == REGI2C_DIG_REG => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); + } + v if v == REGI2C_ULP_CAL => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); + } + v if v == REGI2C_SAR_I2C => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); + } + _ => (), + } +} + +pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, lsb: u8, data: u8) { + assert!(msb - lsb < 8); + regi2c_enable_block(block); + + // Read the i2c bus register + let mut temp: u32 = ((block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) + << REGI2C_RTC_SLAVE_ID_S as u32) + | (reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32; + reg_write(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); + while reg_get_bit(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY) != 0 {} + temp = reg_get_field( + LP_I2C_ANA_MST_I2C0_DATA_REG, + LP_I2C_ANA_MST_I2C0_RDATA_S, + LP_I2C_ANA_MST_I2C0_RDATA_V, + ); + // Write the i2c bus register + temp &= (!(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)); + temp |= (data as u32 & (!(0xFFFFFFFF << (msb as u32 - lsb as u32 + 1)))) << (lsb as u32); + temp = ((block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) << REGI2C_RTC_SLAVE_ID_S as u32) + | ((reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32) + | ((0x1 & REGI2C_RTC_WR_CNTL_V as u32) << REGI2C_RTC_WR_CNTL_S as u32) + | ((temp & REGI2C_RTC_DATA_V as u32) << REGI2C_RTC_DATA_S as u32); + reg_write(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); + while reg_get_bit(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY) != 0 {} + + regi2c_disable_block(block); +} diff --git a/esp-hal/src/soc/esp32s2/trng.rs b/esp-hal/src/soc/esp32s2/trng.rs new file mode 100644 index 00000000000..d9458f259c1 --- /dev/null +++ b/esp-hal/src/soc/esp32s2/trng.rs @@ -0,0 +1,389 @@ +const DR_REG_RTCCNTL_BASE: u32 = 0x3f408000; +const DR_REG_SYSTEM_BASE: u32 = 0x3f4c0000; +const DR_REG_SENS_BASE: u32 = 0x3f408800; +const DR_REG_APB_SARADC_BASE: u32 = 0x3f440000; +const DPORT_APB_SARADC_CLK_EN: u32 = 1 << 28; +const RTC_CNTL_CLK_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x0074; +const RTC_CNTL_DIG_CLK8M_EN: u32 = 1 << 10; +const DPORT_PERIP_CLK_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x040; +const APB_SARADC_APB_ADC_CLKM_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x05c; +const APB_SARADC_CLK_SEL_V: u32 = 0x3; +const APB_SARADC_CLK_SEL_S: u32 = 21; +const RTC_CNTL_ANA_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x0034; +const RTC_CNTL_SAR_I2C_FORCE_PD_M: u32 = 1 << 21; +const RTC_CNTL_SAR_I2C_FORCE_PU_M: u32 = 1 << 22; +const ANA_CONFIG_REG: u32 = 0x6000E044; +const ANA_CONFIG2_REG: u32 = 0x6000E048; +const I2C_SAR_ADC: u8 = 0x69; +const I2C_SAR_ADC_HOSTID: u8 = 1; +const ADC_SAR1_DREF_ADDR: u8 = 0x2; +const ADC_SAR1_DREF_ADDR_MSB: u8 = 0x6; +const ADC_SAR1_DREF_ADDR_LSB: u8 = 0x4; +const ADC_SAR2_DREF_ADDR: u8 = 0x5; +const ADC_SAR2_DREF_ADDR_MSB: u8 = 0x6; +const ADC_SAR2_DREF_ADDR_LSB: u8 = 0x4; +const ADC_SARADC_ENCAL_REF_ADDR: u8 = 0x7; +const ADC_SARADC_ENCAL_REF_ADDR_MSB: u8 = 4; +const ADC_SARADC_ENCAL_REF_ADDR_LSB: u8 = 4; +const ADC_SARADC_ENT_TSENS_ADDR: u8 = 0x7; +const ADC_SARADC_ENT_TSENS_ADDR_MSB: u8 = 2; +const ADC_SARADC_ENT_TSENS_ADDR_LSB: u8 = 2; +const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x7; +const ADC_SARADC_ENT_RTC_ADDR_MSB: u8 = 3; +const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 3; +const APB_SARADC_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE; +const APB_SARADC_SAR1_PATT_LEN_V: u32 = 0xF; +const APB_SARADC_SAR1_PATT_LEN_S: u32 = 15; +const APB_SARADC_SAR1_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x018; +const APB_SARADC_SAR2_PATT_LEN_V: u32 = 0xF; +const APB_SARADC_SAR2_PATT_LEN_S: u32 = 19; +const APB_SARADC_SAR2_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x028; +const SENS_SAR_MEAS1_MUX_REG: u32 = DR_REG_SENS_BASE + 0x0010; +const SENS_SAR1_DIG_FORCE: u32 = 1 << 31; +const APB_SARADC_WORK_MODE_V: u32 = 0x3; +const APB_SARADC_WORK_MODE_S: u32 = 3; + +const APB_SARADC_CTRL2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x004; +const APB_SARADC_MEAS_NUM_LIMIT: u32 = 1 << 0; +const SENS_SAR_POWER_XPD_SAR_REG: u32 = DR_REG_SENS_BASE + 0x003c; +const SENS_FORCE_XPD_SAR: u32 = 0x00000003; +const SENS_FORCE_XPD_SAR_V: u32 = 0x3; +const SENS_FORCE_XPD_SAR_S: u32 = 29; +const APB_SARADC_TIMER_SEL: u32 = 1 << 11; +const APB_SARADC_TIMER_TARGET_V: u32 = 0xFFF; +const APB_SARADC_TIMER_TARGET_S: u32 = 12; +const APB_SARADC_START_FORCE: u32 = 1 << 0; +const APB_SARADC_TIMER_EN: u32 = 1 << 24; + +const I2C_RTC_SLAVE_ID_V: u8 = 0xFF; +const I2C_RTC_SLAVE_ID_S: u8 = 0; +const I2C_RTC_ADDR_V: u8 = 0xFF; +const I2C_RTC_ADDR_S: u8 = 0x8; +const I2C_RTC_CONFIG2: u32 = 0x6000e000; +const I2C_RTC_BUSY: u32 = 1 << 25; +const I2C_RTC_DATA_V: u32 = 0xFF; +const I2C_RTC_DATA_S: u32 = 16; +const I2C_RTC_WR_CNTL_V: u8 = 0x1; +const I2C_RTC_WR_CNTL_S: u8 = 24; +const I2C_RTC_CONFIG0: u32 = 0x6000e048; +const I2C_RTC_CONFIG1: u32 = 0x6000e044; +const I2C_RTC_MAGIC_CTRL_V: u32 = 0x1FFF; +const I2C_RTC_MAGIC_CTRL_S: u32 = 4; +const I2C_RTC_MAGIC_DEFAULT: u32 = 0x1c40; +const I2C_RTC_ALL_MASK_V: u32 = 0x7FFF; +const I2C_RTC_ALL_MASK_S: u32 = 8; +const I2C_RTC_WIFI_CLK_EN: u32 = 0x3f426000 + 0x090; +const I2C_RTC_CLK_GATE_EN: u32 = 1 << 18; +const I2C_BOD: u8 = 0x61; +const I2C_BBPLL: u8 = 0x66; +const I2C_APLL: u8 = 0x6D; +const I2C_RTC_APLL_MASK: u32 = 1 << 14; +const I2C_RTC_BBPLL_MASK: u32 = 1 << 17; +const I2C_RTC_SAR_MASK: u32 = 1 << 18; +const I2C_RTC_BOD_MASK: u32 = 1 << 22; + +pub(crate) fn ensure_randomness() { + // Enable 8M clock source for RNG (this is actually enough to produce strong + // random results, but enabling the SAR ADC as well adds some insurance.) + reg_set_bit(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN); + + // Enable SAR ADC to read a disconnected input for additional entropy + set_peri_reg_mask(DPORT_PERIP_CLK_EN0_REG, DPORT_APB_SARADC_CLK_EN); + + reg_set_field( + APB_SARADC_APB_ADC_CLKM_CONF_REG, + APB_SARADC_CLK_SEL_V, + APB_SARADC_CLK_SEL_S, + 2, + ); + + clear_peri_reg_mask(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M); + set_peri_reg_mask(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); + clear_peri_reg_mask(ANA_CONFIG_REG, 1 << 18); + set_peri_reg_mask(ANA_CONFIG2_REG, 1 << 16); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_DREF_ADDR, + ADC_SAR1_DREF_ADDR_MSB, + ADC_SAR1_DREF_ADDR_LSB, + 0x4, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_DREF_ADDR, + ADC_SAR2_DREF_ADDR_MSB, + ADC_SAR2_DREF_ADDR_LSB, + 0x4, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENCAL_REF_ADDR, + ADC_SARADC_ENCAL_REF_ADDR_MSB, + ADC_SARADC_ENCAL_REF_ADDR_LSB, + 1, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_TSENS_ADDR, + ADC_SARADC_ENT_TSENS_ADDR_MSB, + ADC_SARADC_ENT_TSENS_ADDR_LSB, + 1, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_RTC_ADDR, + ADC_SARADC_ENT_RTC_ADDR_MSB, + ADC_SARADC_ENT_RTC_ADDR_LSB, + 0, + ); + + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SAR1_PATT_LEN_V, + APB_SARADC_SAR1_PATT_LEN_S, + 0, + ); + + write_peri_reg(APB_SARADC_SAR1_PATT_TAB1_REG, 0xafffffff); + + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SAR2_PATT_LEN_V, + APB_SARADC_SAR2_PATT_LEN_S, + 0, + ); + + write_peri_reg(APB_SARADC_SAR2_PATT_TAB1_REG, 0xafffffff); + + set_peri_reg_mask(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE); + + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_WORK_MODE_V, + APB_SARADC_WORK_MODE_S, + 1, + ); + + clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT); + + reg_set_field( + SENS_SAR_POWER_XPD_SAR_REG, + SENS_FORCE_XPD_SAR_V, + SENS_FORCE_XPD_SAR_S, + 3, + ); + + set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_SEL); + + reg_set_field( + APB_SARADC_CTRL2_REG, + APB_SARADC_TIMER_TARGET_V, + APB_SARADC_TIMER_TARGET_S, + 100, + ); + + clear_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_START_FORCE); + set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); +} + +pub fn revert_trng() +{ + // Restore internal I2C bus state + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_DREF_ADDR, + ADC_SAR1_DREF_ADDR_MSB, + ADC_SAR1_DREF_ADDR_LSB, + 0x1 + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_DREF_ADDR, + ADC_SAR2_DREF_ADDR_MSB, + ADC_SAR2_DREF_ADDR_LSB, + 0x1 + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENCAL_REF_ADDR, + ADC_SARADC_ENCAL_REF_ADDR_MSB, + ADC_SARADC_ENCAL_REF_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_TSENS_ADDR, + ADC_SARADC_ENT_TSENS_ADDR_MSB, + ADC_SARADC_ENT_TSENS_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_RTC_ADDR, + ADC_SARADC_ENT_RTC_ADDR_MSB, + ADC_SARADC_ENT_RTC_ADDR_LSB, + 0, + ); + + // Restore SARADC to default mode + clear_peri_reg_mask(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE); + set_peri_reg_mask(DPORT_PERIP_CLK_EN0_REG, DPORT_APB_SARADC_CLK_EN); + set_peri_reg_bits(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S); + clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); +} + +fn reg_set_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); + } +} + +fn reg_write(reg: u32, v: u32) { + unsafe { + (reg as *mut u32).write_volatile(v); + } +} + +fn reg_get_bit(reg: u32, b: u32) -> u32 { + unsafe { (reg as *mut u32).read_volatile() & b } +} + +fn reg_get_field(reg: u32, s: u32, v: u32) -> u32 { + unsafe { ((reg as *mut u32).read_volatile() >> s) & v } +} + +fn reg_clr_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !bit); + } +} + +fn regi2c_enable_block(block: u8) { + reg_set_field( + I2C_RTC_CONFIG0, + I2C_RTC_MAGIC_CTRL_V, + I2C_RTC_MAGIC_CTRL_S, + I2C_RTC_MAGIC_DEFAULT, + ); + reg_set_field( + I2C_RTC_CONFIG1, + I2C_RTC_ALL_MASK_V, + I2C_RTC_ALL_MASK_S, + I2C_RTC_ALL_MASK_V, + ); + + reg_set_bit(I2C_RTC_WIFI_CLK_EN, I2C_RTC_CLK_GATE_EN); + + // Before config I2C register, enable corresponding slave. + match block { + v if v == I2C_APLL => { + reg_set_bit(I2C_RTC_CONFIG1, I2C_RTC_APLL_MASK); + } + v if v == I2C_BBPLL => { + reg_set_bit(I2C_RTC_CONFIG1, I2C_RTC_BBPLL_MASK); + } + v if v == I2C_SAR_ADC => { + reg_set_bit(I2C_RTC_CONFIG1, I2C_RTC_SAR_MASK); + } + v if v == I2C_BOD => { + reg_set_bit(I2C_RTC_CONFIG1, I2C_RTC_BOD_MASK); + } + _ => (), + } +} + +fn regi2c_disable_block(block: u8) { + match block { + v if v == I2C_APLL => { + reg_clr_bit(I2C_RTC_CONFIG1, I2C_RTC_APLL_MASK); + } + v if v == I2C_BBPLL => { + reg_clr_bit(I2C_RTC_CONFIG1, I2C_RTC_BBPLL_MASK); + } + v if v == I2C_SAR_ADC => { + reg_clr_bit(I2C_RTC_CONFIG1, I2C_RTC_SAR_MASK); + } + v if v == I2C_BOD => { + reg_clr_bit(I2C_RTC_CONFIG1, I2C_RTC_BOD_MASK); + } + _ => (), + } +} + +pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, lsb: u8, data: u8) { + assert!(msb - lsb < 8); + regi2c_enable_block(block); + + // Read the i2c bus register + let mut temp: u32 = ((block as u32 & I2C_RTC_SLAVE_ID_V as u32) << I2C_RTC_SLAVE_ID_S as u32) + | (reg_add as u32 & I2C_RTC_ADDR_V as u32) << I2C_RTC_ADDR_S as u32; + reg_write(I2C_RTC_CONFIG2, temp); + while reg_get_bit(I2C_RTC_CONFIG2, I2C_RTC_BUSY) != 0 {} + temp = reg_get_field(I2C_RTC_CONFIG2, I2C_RTC_DATA_S, I2C_RTC_DATA_V); + // Write the i2c bus register + temp &= (!(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)); + temp |= (data as u32 & (!(0xFFFFFFFF << (msb as u32 - lsb as u32 + 1)))) << (lsb as u32); + temp = ((block as u32 & I2C_RTC_SLAVE_ID_V as u32) << I2C_RTC_SLAVE_ID_S as u32) + | ((reg_add as u32 & I2C_RTC_ADDR_V as u32) << I2C_RTC_ADDR_S as u32) + | ((0x1 & I2C_RTC_WR_CNTL_V as u32) << I2C_RTC_WR_CNTL_S as u32) + | ((temp & I2C_RTC_DATA_V) << I2C_RTC_DATA_S); + reg_write(I2C_RTC_CONFIG2, temp); + while reg_get_bit(I2C_RTC_CONFIG2, I2C_RTC_BUSY) != 0 {} + + regi2c_disable_block(block); +} + +fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { + unsafe { + (reg as *mut u32).write_volatile( + ((reg as *mut u32).read_volatile() & !(field_v << field_s)) + | ((value & field_v) << field_s), + ) + } +} + +fn set_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + } +} + +fn set_peri_reg_bits(reg: u32, bitmap: u32, value: u32, shift: u32) { + unsafe { + (reg as *mut u32).write_volatile( + ((reg as *mut u32).read_volatile() & !(bitmap << shift)) + | ((value & bitmap) << shift), + ); + } +} + +fn clear_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + } +} + +fn write_peri_reg(reg: u32, val: u32) { + unsafe { + (reg as *mut u32).write_volatile(val); + } +} \ No newline at end of file diff --git a/esp-hal/src/soc/esp32s3/trng.rs b/esp-hal/src/soc/esp32s3/trng.rs new file mode 100644 index 00000000000..d533d3d661c --- /dev/null +++ b/esp-hal/src/soc/esp32s3/trng.rs @@ -0,0 +1,236 @@ +const DR_REG_SYSCON_BASE: u32 = 0x60026000; +const DR_REG_RTCCNTL_BASE: u32 = 0x60008000; +const DR_REG_SYSTEM_BASE: u32 = 0x600C0000; +const DR_REG_APB_SARADC_BASE: u32 = 0x60040000; +const DR_REG_SENS_BASE: u32 = 0x60008800; +const SYSTEM_WIFI_CLK_EN_REG: u32 = DR_REG_SYSCON_BASE + 0x14; +const SYSTEM_WIFI_CLK_RNG_EN: u32 = 1 << 15; +const RTC_CNTL_CLK_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x74; +const RTC_CNTL_DIG_CLK8M_EN: u32 = 1 << 10; +const SYSTEM_PERIP_CLK_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x18; +const SYSTEM_APB_SARADC_CLK_EN: u32 = 1 << 28; +const APB_SARADC_APB_ADC_CLKM_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x70; +const APB_SARADC_CLK_SEL_V: u32 = 0x3; +const APB_SARADC_CLK_SEL_S: u32 = 21; +const APB_SARADC_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE; +const APB_SARADC_CTRL2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x4; +const APB_SARADC_SAR_CLK_GATED: u32 = 1 << 6; +const APB_SARADC_CLK_EN: u32 = 1 << 20; +const APB_SARADC_CLKM_DIV_NUM_V: u32 = 0xFF; +const APB_SARADC_CLKM_DIV_NUM_S: u32 = 0; +const APB_SARADC_SAR_CLK_DIV_V: u32 = 0xFF; +const APB_SARADC_SAR_CLK_DIV_S: u32 = 7; +const APB_SARADC_TIMER_TARGET_V: u32 = 0xFFF; +const APB_SARADC_TIMER_TARGET_S: u32 = 0x12; +const APB_SARADC_START_FORCE: u32 = 1 << 0; +const SENS_SAR_POWER_XPD_SAR_REG: u32 = DR_REG_SENS_BASE + 0x3C; +const SENS_FORCE_XPD_SAR_V: u32 = 0x3; +const SENS_FORCE_XPD_SAR_S: u32 = 29; +const APB_SARADC_MEAS_NUM_LIMIT: u32 = 1 << 0; +const APB_SARADC_WORK_MODE_V: u32 = 0x3; +const APB_SARADC_WORK_MODE_S: u32 = 0x3; +const APB_SARADC_SAR2_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x28; +const APB_SARADC_SAR2_PATT_LEN_V: u32 = 0xF; +const APB_SARADC_SAR2_PATT_LEN_S: u32 = 19; +const APB_SARADC_SAR1_PATT_LEN_V: u32 = 0xF; +const APB_SARADC_SAR1_PATT_LEN_S: u32 = 15; +const APB_SARADC_SAR1_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x18; +const SENS_SAR_MEAS1_MUX_REG: u32 = DR_REG_SENS_BASE + 0x10; +const SENS_SAR1_DIG_FORCE: u32 = 1 << 31; +const SENS_SAR_MEAS2_MUX_REG: u32 = DR_REG_SENS_BASE + 0x34; +const SENS_SAR2_RTC_FORCE: u32 = 1 << 31; +const APB_SARADC_APB_ADC_ARB_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE + 0x38; +const APB_SARADC_ADC_ARB_GRANT_FORCE: u32 = 1 << 5; +const APB_SARADC_ADC_ARB_FIX_PRIORITY: u32 = 1 << 12; +const APB_SARADC_FILTER_CTRL0_REG: u32 = DR_REG_APB_SARADC_BASE + 0x3C; +const APB_SARADC_FILTER_CHANNEL0_V: u32 = 0x1F; +const APB_SARADC_FILTER_CHANNEL0_S: u32 = 19; +const APB_SARADC_FILTER_CHANNEL1_V: u32 = 0x1F; +const APB_SARADC_FILTER_CHANNEL1_S: u32 = 14; +const APB_SARADC_TIMER_SEL: u32 = 1 << 11; +const APB_SARADC_TIMER_EN: u32 = 1 << 24; +const I2C_SAR_ADC: u8 = 0x69; +const I2C_SAR_ADC_HOSTID: u8 = 1; +const ADC_SARADC_ENCAL_REF_ADDR: u8 = 0x7; +const ADC_SARADC_ENCAL_REF_ADDR_MSB: u32 = 4; +const ADC_SARADC_ENCAL_REF_ADDR_LSB: u32 = 4; +const ADC_SARADC_ENT_TSENS_ADDR: u32 = 0x7; +const ADC_SARADC_ENT_TSENS_ADDR_MSB: u32 = 2; +const ADC_SARADC_ENT_TSENS_ADDR_LSB: u32 = 2; +const ADC_SARADC_ENT_RTC_ADDR: u32 = 0x7; +const ADC_SARADC_ENT_RTC_ADDR_MSB: u32 = 3; +const ADC_SARADC_ENT_RTC_ADDR_LSB: u32 = 3; +const ADC_SARADC_DTEST_RTC_ADDR: u32 = 0x7; +const ADC_SARADC_DTEST_RTC_ADDR_MSB: u32 = 1; +const ADC_SARADC_DTEST_RTC_ADDR_LSB: u32 = 0; +const SYSTEM_PERIP_RST_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x20; +const SYSTEM_APB_SARADC_RST: u32 = 1 << 28; + +use crate::regi2c_write_mask; + +pub(crate) fn ensure_randomness() { + set_peri_reg_mask(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_RNG_EN); + + // Enable 8M clock source for RNG (this is actually enough to produce strong + // random results, but enabling the SAR ADC as well adds some insurance.) + reg_set_bit(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN); + + // Enable SAR ADC to read a disconnected input for additional entropy + set_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN); + clear_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN); + + reg_set_field( + APB_SARADC_APB_ADC_CLKM_CONF_REG, + APB_SARADC_CLK_SEL_V, + APB_SARADC_CLK_SEL_S, + 2, + ); + + set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED); + set_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN); + + reg_set_field( + APB_SARADC_APB_ADC_CLKM_CONF_REG, + APB_SARADC_CLKM_DIV_NUM_V, + APB_SARADC_CLKM_DIV_NUM_S, + 3, + ); + + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SAR_CLK_DIV_V, + APB_SARADC_SAR_CLK_DIV_S, + 3, + ); + + reg_set_field( + APB_SARADC_CTRL2_REG, + APB_SARADC_TIMER_TARGET_V, + APB_SARADC_TIMER_TARGET_S, + 70, + ); + + clear_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_START_FORCE); + reg_set_field( + SENS_SAR_POWER_XPD_SAR_REG, + SENS_FORCE_XPD_SAR_V, + SENS_FORCE_XPD_SAR_S, + 3, + ); + clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT); + + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_WORK_MODE_V, + APB_SARADC_WORK_MODE_S, + 1, + ); + + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SAR2_PATT_LEN_V, + APB_SARADC_SAR2_PATT_LEN_S, + 0, + ); + + write_peri_reg(APB_SARADC_SAR2_PATT_TAB1_REG, 0xafffff); + + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SAR1_PATT_LEN_V, + APB_SARADC_SAR1_PATT_LEN_S, + 0, + ); + + write_peri_reg(APB_SARADC_SAR1_PATT_TAB1_REG, 0xafffff); + + set_peri_reg_mask(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE); + + clear_peri_reg_mask(SENS_SAR_MEAS2_MUX_REG, SENS_SAR2_RTC_FORCE); + + clear_peri_reg_mask( + APB_SARADC_APB_ADC_ARB_CTRL_REG, + APB_SARADC_ADC_ARB_GRANT_FORCE, + ); + clear_peri_reg_mask( + APB_SARADC_APB_ADC_ARB_CTRL_REG, + APB_SARADC_ADC_ARB_FIX_PRIORITY, + ); + + reg_set_field( + APB_SARADC_FILTER_CTRL0_REG, + APB_SARADC_FILTER_CHANNEL0_V, + APB_SARADC_FILTER_CHANNEL0_S, + 0xD, + ); + + reg_set_field( + APB_SARADC_FILTER_CTRL0_REG, + APB_SARADC_FILTER_CHANNEL1_V, + APB_SARADC_FILTER_CHANNEL1_S, + 0xD, + ); + + set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_SEL); + set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 1); +} + +pub fn revert_trng() +{ + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + + reg_set_field(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR_V, SENS_FORCE_XPD_SAR_S, 0); + + clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); + + clear_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, APB_SARADC_CLK_EN); + + set_peri_reg_mask(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST); +} + +fn reg_set_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); + } +} + +fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { + unsafe { + (reg as *mut u32).write_volatile( + ((reg as *mut u32).read_volatile() & !(field_v << field_s)) + | ((value & field_v) << field_s), + ) + } +} + +fn set_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + } +} + +fn clear_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + } +} + +fn write_peri_reg(reg: u32, val: u32) { + unsafe { + (reg as *mut u32).write_volatile(val); + } +} \ No newline at end of file diff --git a/examples/src/bin/rng.rs b/examples/src/bin/rng.rs index ee86e46bb42..79af5dd5dc4 100644 --- a/examples/src/bin/rng.rs +++ b/examples/src/bin/rng.rs @@ -6,35 +6,13 @@ #![no_main] use esp_backtrace as _; -use esp_hal::{peripherals::Peripherals, prelude::*, rng::{Rng, Secure}, - analog::adc::{AdcConfig, Attenuation, ADC}, - clock::ClockControl, - delay::Delay, - gpio::IO, - peripherals::ADC1}; +use esp_hal::{peripherals::Peripherals, prelude::*, rng::Trng}; use esp_println::println; #[entry] fn main() -> ! { let peripherals = Peripherals::take(); - let mut trng = Rng::::new(peripherals.RNG, peripherals.ADC1); - - // let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); - // cfg_if::cfg_if! { - // if #[cfg(feature = "esp32")] { - // let analog_pin = io.pins.gpio32.into_analog(); - // } else if #[cfg(any(feature = "esp32s2", feature = "esp32s3"))] { - // let analog_pin = io.pins.gpio3.into_analog(); - // } else { - // let analog_pin = io.pins.gpio2.into_analog(); - // } - // } - - // // Create ADC instances - // let mut adc1_config = AdcConfig::new(); - // let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); - // let mut adc1 = ADC::::new(peripherals.ADC1, adc1_config); - + let mut trng = Trng::new(peripherals.RNG, peripherals.ADC1); // Generate a random word (u32): println!("Random u32: {}", trng.random()); From 6b7c5633055de72f62100542364c5cdea11064cb Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Sat, 6 Apr 2024 14:56:36 +0200 Subject: [PATCH 04/16] Finish revert functions --- esp-hal/src/soc/esp32c3/trng.rs | 2 +- esp-hal/src/soc/esp32c6/trng.rs | 177 ++++++++++---- esp-hal/src/soc/esp32h2/trng.rs | 411 ++++++++++++++++++++++++++++++++ 3 files changed, 536 insertions(+), 54 deletions(-) create mode 100644 esp-hal/src/soc/esp32h2/trng.rs diff --git a/esp-hal/src/soc/esp32c3/trng.rs b/esp-hal/src/soc/esp32c3/trng.rs index a330e1fa434..0401686c232 100644 --- a/esp-hal/src/soc/esp32c3/trng.rs +++ b/esp-hal/src/soc/esp32c3/trng.rs @@ -169,7 +169,7 @@ pub(crate) fn ensure_randomness() { set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); } -pub(crate) fn ensure_randomness() { +pub(crate) fn revert_trng() { /* Restore internal I2C bus state */ regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); diff --git a/esp-hal/src/soc/esp32c6/trng.rs b/esp-hal/src/soc/esp32c6/trng.rs index 35162e9f4ab..cb4da1b5ad9 100644 --- a/esp-hal/src/soc/esp32c6/trng.rs +++ b/esp-hal/src/soc/esp32c6/trng.rs @@ -6,15 +6,6 @@ const PCR_SARADC_CLKM_EN: u32 = 1 << 22; const PMU_RF_PWC_REG: u32 = 0x600B0000 + 0x154; const I2C_SAR_ADC: u8 = 0x69; const I2C_SAR_ADC_HOSTID: u8 = 0; -const ADC_SARADC_HOST_ADDR: u8 = 0x7; -const DTEST_RTC_MSB: u8 = 1; -const DTEST_RTC_LSB: u8 = 0; -const ENT_RTC_MSB: u8 = 3; -const ENT_RTC_LSB: u8 = 3; -const SARADC1_ENCAL_REF_MSB: u8 = 4; -const SARADC1_ENCAL_REF_LSB: u8 = 4; -const SARADC2_ENCAL_REF_MSB: u8 = 6; -const SARADC2_ENCAL_REF_LSB: u8 = 6; const SAR2_CHANNEL: u32 = 9; const SAR2_ATTEN: u32 = 1; const SAR1_ATTEN: u32 = 1; @@ -67,21 +58,37 @@ const PCR_SARADC_CLKM_DIV_NUM_S: u32 = 12; const PMU_PERIF_I2C_RSTB: u32 = 1 << 26; const PMU_XPD_PERIF_I2C: u32 = 1 << 27; -const ADC_SARADC_DTEST_RTC_ADDR: u8 = 0x4; -const ADC_SARADC_DTEST_RTC_ADDR_MSB: u8 = 0x3; -const ADC_SARADC_DTEST_RTC_ADDR_LSB: u8 = 0x0; +const ADC_SAR2_INITIAL_CODE_HIGH_ADDR: u8 = 0x4; +const ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB: u8 = 0x3; +const ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB: u8 = 0x0; -const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x3; -const ADC_SARADC_ENT_RTC_ADDR_MSB: u8 = 0x7; -const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 0x0; +const ADC_SAR2_INITIAL_CODE_LOW_ADDR: u8 = 0x3; +const ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB: u8 = 0x7; +const ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB: u8 = 0x0; -const ADC_SARADC1_ENCAL_REF_ADDR: u8 = 0x1; -const ADC_SARADC1_ENCAL_REF_ADDR_MSB: u8 = 0x3; -const ADC_SARADC1_ENCAL_REF_ADDR_LSB: u8 = 0x0; +const ADC_SAR1_INITIAL_CODE_HIGH_ADDR: u8 = 0x1; +const ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB: u8 = 0x3; +const ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB: u8 = 0x0; -const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x0; -const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 0x7; -const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 0x0; +const ADC_SAR1_INITIAL_CODE_LOW_ADDR: u8 = 0x0; +const ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB: u8 = 0x7; +const ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB: u8 = 0x0; + +const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7; +const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 1; +const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 0; + +const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x7 +const ADC_SARADC_ENT_RTC_ADDR_MSB: u8 = 3; +const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 3; + +const ADC_SARADC1_ENCAL_REF_ADDR: u8 = 0x7; +const ADC_SARADC1_ENCAL_REF_ADDR_MSB: u8 = 4; +const ADC_SARADC1_ENCAL_REF_ADDR_LSB: u8 = 4; + +const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7; +const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 6; +const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 6; const APB_SARADC_SARADC_SAR_PATT_LEN_V: u32 = 0x00000007; const APB_SARADC_SARADC_SAR_PATT_LEN_S: u32 = 15; @@ -129,70 +136,69 @@ pub(crate) fn ensure_randomness() { regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SARADC_HOST_ADDR, - DTEST_RTC_MSB, - DTEST_RTC_LSB, + ADC_SARADC_DTEST_RTC_ADDR, + ADC_SARADC_DTEST_RTC_ADDR_MSB, + ADC_SARADC_DTEST_RTC_ADDR_LSB, 2, ); regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SARADC_HOST_ADDR, - ENT_RTC_MSB, - ENT_RTC_LSB, + ADC_SARADC_ENT_RTC_ADDR, + ADC_SARADC_ENT_RTC_ADDR_MSB, + ADC_SARADC_ENT_RTC_ADDR_LSB, 1, ); regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SARADC_HOST_ADDR, - SARADC1_ENCAL_REF_MSB, - SARADC1_ENCAL_REF_LSB, + ADC_SARADC1_ENCAL_REF_ADDR, + ADC_SARADC1_ENCAL_REF_ADDR_MSB, + ADC_SARADC1_ENCAL_REF_ADDR_LSB, 1, ); regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SARADC_HOST_ADDR, - SARADC2_ENCAL_REF_MSB, - SARADC2_ENCAL_REF_LSB, + ADC_SARADC1_ENCAL_REF_ADDR, + ADC_SARADC1_ENCAL_REF_ADDR_MSB, + ADC_SARADC1_ENCAL_REF_ADDR_LSB, 1, ); - // SAR2 High ADDR regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SARADC_DTEST_RTC_ADDR, - ADC_SARADC_DTEST_RTC_ADDR_MSB, - ADC_SARADC_DTEST_RTC_ADDR_LSB, - 0x08, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR + ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB, + 0x60, ); - // SAR2 Low ADDR + regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SARADC_ENT_RTC_ADDR, - ADC_SARADC_ENT_RTC_ADDR_MSB, - ADC_SARADC_ENT_RTC_ADDR_LSB, + ADC_SAR2_INITIAL_CODE_LOW_ADDR + ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB, + ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB, 0x66, ); - // SAR1 High ADDR + regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SARADC1_ENCAL_REF_ADDR, - ADC_SARADC1_ENCAL_REF_ADDR_MSB, - ADC_SARADC1_ENCAL_REF_ADDR_LSB, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR + ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB, 0x08, ); - // SAR1 Low ADDR + regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SARADC2_ENCAL_REF_ADDR, - ADC_SARADC2_ENCAL_REF_ADDR_MSB, - ADC_SARADC2_ENCAL_REF_ADDR_LSB, + ADC_SAR1_INITIAL_CODE_LOW_ADDR + ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB, + ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB, 0x66, ); @@ -232,20 +238,85 @@ pub(crate) fn ensure_randomness() { reg_set_bit(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); } -pub(crate) fn ensure_randomness() { +pub(crate) fn revert_trng() { reg_clr_bit(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); reg_write(APB_SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB, + 0x60, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_INITIAL_CODE_LOW_ADDR, + ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB, + ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB, + 0x60, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_INITIAL_CODE_LOW_ADDR, + ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB, + ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_DTEST_RTC_ADDR, + ADC_SARADC_DTEST_RTC_ADDR_MSB, + ADC_SARADC_DTEST_RTC_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_RTC_ADDR, + ADC_SARADC_ENT_RTC_ADDR_MSB, + ADC_SARADC_ENT_RTC_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC1_ENCAL_REF_ADDR, + ADC_SARADC1_ENCAL_REF_ADDR_MSB, + ADC_SARADC1_ENCAL_REF_ADDR_LSB, + 0, + ); + regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, ADC_SARADC2_ENCAL_REF_ADDR, ADC_SARADC2_ENCAL_REF_ADDR_MSB, ADC_SARADC2_ENCAL_REF_ADDR_LSB, - 0x66, + 0, ); - regi2c_write_mask(I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, HIGH) + clear_peri_reg_mask(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); + reg_write(PCR_SARADC_CLKM_CONF_REG, 0x00404000); + reg_write(PCR_SARADC_CONF_REG, 0x5); } fn reg_set_bit(reg: u32, bit: u32) { diff --git a/esp-hal/src/soc/esp32h2/trng.rs b/esp-hal/src/soc/esp32h2/trng.rs new file mode 100644 index 00000000000..ba8ce366270 --- /dev/null +++ b/esp-hal/src/soc/esp32h2/trng.rs @@ -0,0 +1,411 @@ +const PCR_SARADC_CONF_REG: u32 = 0x60096000 + 0x80; +const PCR_SARADC_RST_EN: u32 = 1 << 1; +const PCR_SARADC_REG_CLK_EN: u32 = 1 << 2; +const PCR_SARADC_CLKM_CONF_REG: u32 = 0x60096000 + 0x84; +const PCR_SARADC_CLKM_EN: u32 = 1 << 22; +const PCR_SARADC_CLKM_SEL_V: u32 = 0x00000003; +const PCR_SARADC_CLKM_SEL_S: u32 = 20; +const PCR_SARADC_CLKM_DIV_NUM_V: u32 = 0x000000FF; +const PCR_SARADC_CLKM_DIV_NUM_S: u32 = 12; +const PMU_RF_PWC_REG: u32 = 0x600B0000 + 0x154; +const PMU_XPD_PERIF_I2C: u32 = 1 << 27; +const I2C_SAR_ADC: u8 = 0x69; +const I2C_SAR_ADC_HOSTID: u8 = 0; + +const I2C_SARADC_DTEST: u8 = 7; +const I2C_SARADC_DTEST_MSB: u8 = 1; +const I2C_SARADC_DTEST_LSB: u8 = 0; +const I2C_SARADC_ENT_SAR: u8 = 7; +const I2C_SARADC_ENT_SAR_MSB: u8 = 3; +const I2C_SARADC_ENT_SAR_LSB: u8 = 1; +const I2C_SARADC_EN_TOUT_SAR1_BUS: u8 = 7; +const I2C_SARADC_EN_TOUT_SAR1_BUS_MSB: u8 = 5; +const I2C_SARADC_EN_TOUT_SAR1_BUS_LSB: u8 = 5; + +const I2C_SARADC_SAR2_INIT_CODE_MSB: u8 = 4; +const I2C_SARADC_SAR2_INIT_CODE_MSB_MSB: u8 = 3; +const I2C_SARADC_SAR2_INIT_CODE_MSB_LSB: u8 = 0; +const I2C_SARADC_SAR2_INIT_CODE_LSB: u8 = 3; +const I2C_SARADC_SAR2_INIT_CODE_LSB_MSB: u8 = 7; +const I2C_SARADC_SAR2_INIT_CODE_LSB_LSB: u8 = 0; + +const I2C_SARADC_SAR1_INIT_CODE_MSB: u8 = 1; +const I2C_SARADC_SAR1_INIT_CODE_MSB_MSB: u8 = 3; +const I2C_SARADC_SAR1_INIT_CODE_MSB_LSB: u8 = 0; +const I2C_SARADC_SAR1_INIT_CODE_LSB: u8 = 3; +const I2C_SARADC_SAR1_INIT_CODE_LSB_MSB: u8 = 7; +const I2C_SARADC_SAR1_INIT_CODE_LSB_LSB: u8 = 0; + +const SAR2_CHANNEL: u32 = 9; +const SAR2_ATTEN: u32 = 1; +const SAR1_ATTEN: u32 = 1; +const PATTERN_BIT_WIDTH: u32 = 6; +const APB_SARADC_SAR_PATT_TAB1_REG: u32 = 0x60040000 + 0x18; +const APB_SARADC_CTRL_REG: u32 = 0x60040000; +const APB_SARADC_CTRL2_REG: u32 = 0x60040000 + 0x4; + +const APB_SARADC_SARADC_SAR_PATT_LEN_V: u32 = 0x00000007; +const APB_SARADC_SARADC_SAR_PATT_LEN_S: u32 = 15; +const APB_SARADC_SARADC_SAR_CLK_DIV_V: u32 = 0x000000FF; +const APB_SARADC_SARADC_SAR_CLK_DIV_S: u32 = 7; +const APB_SARADC_SARADC_TIMER_TARGET_V: u32 = 0x00000FFF; +const APB_SARADC_SARADC_TIMER_TARGET_S: u32 = 12; +const APB_SARADC_SARADC_TIMER_EN: u32 = 1 << 24; + +const DR_REG_MODEM_LPCON_BASE: u32 = 0x600AF000; +const MODEM_LPCON_CLK_CONF_REG: u32 = DR_REG_MODEM_LPCON_BASE + 0x18; +const MODEM_LPCON_CLK_I2C_MST_EN: u32 = 1 << 2; +const DR_REG_LP_I2C_ANA_MST_BASE: u32 = 0x600B2400; +const LP_I2C_ANA_MST_DATE_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x3fc; +const LP_I2C_ANA_MST_I2C_MAT_CLK_EN: u32 = 1 << 28; + +const REGI2C_BBPLL: u8 = 0x66; +const REGI2C_BIAS: u8 = 0x6a; +const REGI2C_DIG_REG: u8 = 0x6d; +const REGI2C_ULP_CAL: u8 = 0x61; +const REGI2C_SAR_I2C: u8 = 0x69; + +const LP_I2C_ANA_MST_DEVICE_EN_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x14; +const REGI2C_BBPLL_DEVICE_EN: u32 = 1 << 5; +const REGI2C_BIAS_DEVICE_EN: u32 = 1 << 4; +const REGI2C_DIG_REG_DEVICE_EN: u32 = 1 << 8; +const REGI2C_ULP_CAL_DEVICE_EN: u32 = 1 << 6; +const REGI2C_SAR_I2C_DEVICE_EN: u32 = 1 << 7; +const REGI2C_RTC_SLAVE_ID_V: u8 = 0xFF; +const REGI2C_RTC_SLAVE_ID_S: u8 = 0; +const REGI2C_RTC_ADDR_V: u8 = 0xFF; +const REGI2C_RTC_ADDR_S: u8 = 8; +const REGI2C_RTC_WR_CNTL_V: u8 = 0x1; +const REGI2C_RTC_WR_CNTL_S: u8 = 24; +const REGI2C_RTC_DATA_V: u8 = 0xFF; +const REGI2C_RTC_DATA_S: u8 = 16; + +const LP_I2C_ANA_MST_I2C0_CTRL_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE; +const LP_I2C_ANA_MST_I2C0_BUSY: u32 = 1 << 25; + +const LP_I2C_ANA_MST_I2C0_DATA_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x8; +const LP_I2C_ANA_MST_I2C0_RDATA_V: u32 = 0x000000FF; +const LP_I2C_ANA_MST_I2C0_RDATA_S: u32 = 0; + +pub(crate) fn ensure_randomness() { + // Pull SAR ADC out of reset + reg_set_bit(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); + reg_clr_bit(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); + + // Enable SAR ADC APB clock + reg_set_bit(PCR_SARADC_CONF_REG, PCR_SARADC_REG_CLK_EN); + + // Enable ADC_CTRL_CLK (SAR ADC function clock) + reg_set_bit(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_EN); + + // Select XTAL clock (40 MHz) source for ADC_CTRL_CLK + reg_set_field( + PCR_SARADC_CLKM_CONF_REG, + PCR_SARADC_CLKM_SEL_V, + PCR_SARADC_CLKM_SEL_S, + 0, + ); + + // Set the clock divider for ADC_CTRL_CLK to default value (in case it has been + // changed) + reg_set_field( + PCR_SARADC_CLKM_CONF_REG, + PCR_SARADC_CLKM_DIV_NUM_V, + PCR_SARADC_CLKM_DIV_NUM_S, + 0, + ); + + // some ADC sensor registers are in power group PERIF_I2C and need to be enabled + // via PMU + set_peri_reg_mask(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); + + // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal + // voltage as sampling source + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_DTEST, + I2C_SARADC_DTEST_MSB, + I2C_SARADC_DTEST_LSB, + 2, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_ENT_SAR, + I2C_SARADC_ENT_SAR_MSB, + I2C_SARADC_ENT_SAR_LSB, + 1, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_EN_TOUT_SAR1_BUS, + I2C_SARADC_EN_TOUT_SAR1_BUS_MSB, + I2C_SARADC_EN_TOUT_SAR1_BUS_LSB, + 1, + ); + + // SAR2 High ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR2_INIT_CODE_MSB, + I2C_SARADC_SAR2_INIT_CODE_MSB_MSB, + I2C_SARADC_SAR2_INIT_CODE_MSB_LSB, + 0x08, + ); + // SAR2 Low ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR2_INIT_CODE_LSB, + I2C_SARADC_SAR2_INIT_CODE_LSB_MSB, + I2C_SARADC_SAR2_INIT_CODE_LSB_LSB, + 0x66, + ); + // SAR1 High ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR1_INIT_CODE_MSB, + I2C_SARADC_SAR1_INIT_CODE_MSB_MSB, + I2C_SARADC_SAR1_INIT_CODE_MSB_LSB, + 0x08, + ); + // SAR1 Low ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR1_INIT_CODE_LSB, + I2C_SARADC_SAR1_INIT_CODE_LSB_MSB, + I2C_SARADC_SAR1_INIT_CODE_LSB_LSB, + 0x66, + ); + + // create patterns and set them in pattern table + let pattern_one: u32 = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation + let pattern_two: u32 = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here + let pattern_table: u32 = + (pattern_two << (3 * PATTERN_BIT_WIDTH)) | (pattern_one << (2 * PATTERN_BIT_WIDTH)); + reg_write(APB_SARADC_SAR_PATT_TAB1_REG, pattern_table); + + // set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0) + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SARADC_SAR_PATT_LEN_V, + APB_SARADC_SARADC_SAR_PATT_LEN_S, + 0, + ); + + // Same as in C3 + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_SARADC_SAR_CLK_DIV_V, + APB_SARADC_SARADC_SAR_CLK_DIV_S, + 15, + ); + + // set timer expiry (timer is ADC_CTRL_CLK) + reg_set_field( + APB_SARADC_CTRL2_REG, + APB_SARADC_SARADC_TIMER_TARGET_V, + APB_SARADC_SARADC_TIMER_TARGET_S, + 200, + ); + + // enable timer + reg_set_bit(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); +} + +pub(crate) fn revert_trng() { + // Disable timer + reg_clr_bit(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); + + // Write reset value + reg_write(APB_SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF); + + // Revert ADC I2C configuration and initial voltage source setting + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR2_INIT_CODE_MSB, + I2C_SARADC_SAR2_INIT_CODE_MSB_MSB, + I2C_SARADC_SAR2_INIT_CODE_MSB_LSB, + 0x60, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR2_INIT_CODE_LSB, + I2C_SARADC_SAR2_INIT_CODE_LSB_MSB, + I2C_SARADC_SAR2_INIT_CODE_LSB_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR1_INIT_CODE_MSB, + I2C_SARADC_SAR1_INIT_CODE_MSB_MSB, + I2C_SARADC_SAR1_INIT_CODE_MSB_LSB, + 0x60, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR1_INIT_CODE_LSB, + I2C_SARADC_SAR1_INIT_CODE_LSB_MSB, + I2C_SARADC_SAR1_INIT_CODE_LSB_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_DTEST, + I2C_SARADC_DTEST_MSB, + I2C_SARADC_DTEST_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_ENT_SAR, + I2C_SARADC_ENT_SAR_MSB, + I2C_SARADC_ENT_SAR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_EN_TOUT_SAR1_BUS + I2C_SARADC_EN_TOUT_SAR1_BUS_MSB, + I2C_SARADC_EN_TOUT_SAR1_BUS_LSB, + 0, + ); + + // disable ADC_CTRL_CLK (SAR ADC function clock) + reg_write(PCR_SARADC_CLKM_CONF_REG, 0x00404000); + + // Set PCR_SARADC_CONF_REG to initial state + reg_write(PCR_SARADC_CONF_REG, 0x5); +} + +fn reg_set_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); + } +} + +fn reg_clr_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !bit); + } +} + +fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { + unsafe { + (reg as *mut u32).write_volatile( + ((reg as *mut u32).read_volatile() & !(field_v << field_s)) + | ((value & field_v) << field_s), + ) + } +} + +fn set_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + } +} +fn reg_write(reg: u32, v: u32) { + unsafe { + (reg as *mut u32).write_volatile(v); + } +} + +fn reg_get_bit(reg: u32, b: u32) -> u32 { + unsafe { (reg as *mut u32).read_volatile() & b } +} + +fn reg_get_field(reg: u32, s: u32, v: u32) -> u32 { + unsafe { ((reg as *mut u32).read_volatile() >> s) & v } +} + +fn regi2c_enable_block(block: u8) { + reg_set_bit(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); + reg_set_bit(LP_I2C_ANA_MST_DATE_REG, LP_I2C_ANA_MST_I2C_MAT_CLK_EN); + + // Before config I2C register, enable corresponding slave. + match block { + v if v == REGI2C_BBPLL => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); + } + v if v == REGI2C_BIAS => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); + } + v if v == REGI2C_DIG_REG => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); + } + v if v == REGI2C_ULP_CAL => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); + } + v if v == REGI2C_SAR_I2C => { + reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); + } + _ => (), + } +} + +fn regi2c_disable_block(block: u8) { + match block { + v if v == REGI2C_BBPLL => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); + } + v if v == REGI2C_BIAS => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); + } + v if v == REGI2C_DIG_REG => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); + } + v if v == REGI2C_ULP_CAL => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); + } + v if v == REGI2C_SAR_I2C => { + reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); + } + _ => (), + } +} + +pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, lsb: u8, data: u8) { + assert!(msb - lsb < 8); + regi2c_enable_block(block); + + // Read the i2c bus register + let mut temp: u32 = ((block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) + << REGI2C_RTC_SLAVE_ID_S as u32) + | (reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32; + reg_write(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); + while reg_get_bit(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY) != 0 {} + temp = reg_get_field( + LP_I2C_ANA_MST_I2C0_DATA_REG, + LP_I2C_ANA_MST_I2C0_RDATA_S, + LP_I2C_ANA_MST_I2C0_RDATA_V, + ); + // Write the i2c bus register + temp &= (!(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)); + temp |= (data as u32 & (!(0xFFFFFFFF << (msb as u32 - lsb as u32 + 1)))) << (lsb as u32); + temp = ((block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) << REGI2C_RTC_SLAVE_ID_S as u32) + | ((reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32) + | ((0x1 & REGI2C_RTC_WR_CNTL_V as u32) << REGI2C_RTC_WR_CNTL_S as u32) + | ((temp & REGI2C_RTC_DATA_V as u32) << REGI2C_RTC_DATA_S as u32); + reg_write(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); + while reg_get_bit(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY) != 0 {} + + regi2c_disable_block(block); +} From 83e46bd402936ab3d8febb61c81e325fc25c2270 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 8 Apr 2024 18:09:37 +0200 Subject: [PATCH 05/16] More progress --- esp-hal/src/rng.rs | 13 +++++++------ examples/src/bin/rng.rs | 31 ++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index 9a9582d159d..8addf7a189d 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -43,8 +43,10 @@ #![doc = concat!("[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", crate::soc::chip!(), "/api-reference/system/random.html)")] use core::marker::PhantomData; +use core::ops::Deref; +use crate::analog::adc::ADC; -use crate::{peripheral::{Peripheral, PeripheralRef} , peripherals::RNG}; +use crate::{peripheral::Peripheral , peripherals::RNG}; /// Random number generator driver #[derive(Clone, Copy)] @@ -123,19 +125,18 @@ impl rand_core::RngCore for Rng { #[cfg(not(esp32p4))] pub struct Trng<'d>{ pub rng: Rng, - adc: PeripheralRef<'d, crate::peripherals::ADC1>, + adc: &'d mut ADC<'d, crate::peripherals::ADC1> } #[cfg(not(esp32p4))] impl<'d> Trng<'d> { /// Create a new True Random Number Generator instance - pub fn new(rng: impl Peripheral

, adc: impl Peripheral

+ 'd) -> Self { - crate::into_ref!(adc); + pub fn new(rng: impl Peripheral

, adc: &'d mut ADC<'d, crate::peripherals::ADC1>) -> Self { let gen = Rng::new(rng); crate::soc::trng::ensure_randomness(); Self{ rng: gen, - adc, + adc: adc, } } @@ -148,7 +149,7 @@ impl<'d> Trng<'d> { } /// Downgrade Trng to Rng and release ADC1 - pub fn downgrade(self) -> (Rng, PeripheralRef<'d, crate::peripherals::ADC1>) { + pub fn downgrade(&mut self) -> (Rng, &'d mut ADC<'_, crate::peripherals::ADC1>) { crate::soc::trng::revert_trng(); (self.rng, self.adc) } diff --git a/examples/src/bin/rng.rs b/examples/src/bin/rng.rs index 79af5dd5dc4..ee854799ad4 100644 --- a/examples/src/bin/rng.rs +++ b/examples/src/bin/rng.rs @@ -6,21 +6,38 @@ #![no_main] use esp_backtrace as _; -use esp_hal::{peripherals::Peripherals, prelude::*, rng::Trng}; +use esp_hal::{prelude::*, rng::Trng, + analog::adc::{AdcConfig, Attenuation, ADC}, + clock::ClockControl, + delay::Delay, + gpio::IO, + peripherals::{Peripherals, ADC1}}; + use esp_println::println; #[entry] fn main() -> ! { let peripherals = Peripherals::take(); - let mut trng = Trng::new(peripherals.RNG, peripherals.ADC1); - - // Generate a random word (u32): - println!("Random u32: {}", trng.random()); + let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); + let analog_pin = io.pins.gpio3.into_analog(); + let mut adc1_config = AdcConfig::new(); + let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); + let mut adc1 = ADC::::new(peripherals.ADC1, adc1_config); + let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); + + let mut trng = Trng::new(peripherals.RNG, &mut adc1); + + let (mut rng, adc1) = trng.downgrade(); + // Fill a buffer with random bytes: let mut buf = [0u8; 16]; - trng.read(&mut buf); + // trng.read(&mut buf); println!("Random bytes: {:?}", buf); - loop {} + loop { + println!("Random u32: {}", rng.random()); + let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); + println!("ADC reading = {}", pin_value); + } } From 37a63657f8d9449f87275c264b636edf4c1a9f41 Mon Sep 17 00:00:00 2001 From: playfulfence Date: Sat, 4 May 2024 14:31:15 +0200 Subject: [PATCH 06/16] Adjust for new driver release --- esp-hal/src/rng.rs | 22 +++++++++----------- esp-hal/src/soc/esp32/mod.rs | 1 + esp-hal/src/soc/esp32c2/mod.rs | 1 + esp-hal/src/soc/esp32c3/mod.rs | 1 + esp-hal/src/soc/esp32c6/mod.rs | 1 + esp-hal/src/soc/esp32c6/trng.rs | 36 +++++++++++++++++++-------------- esp-hal/src/soc/esp32h2/mod.rs | 1 + esp-hal/src/soc/esp32s2/mod.rs | 1 + esp-hal/src/soc/esp32s3/mod.rs | 1 + examples/src/bin/rng.rs | 22 +++++++++++--------- 10 files changed, 50 insertions(+), 37 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index 8addf7a189d..fdc5fff3ab6 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -43,10 +43,8 @@ #![doc = concat!("[ESP-IDF documentation](https://docs.espressif.com/projects/esp-idf/en/latest/", crate::soc::chip!(), "/api-reference/system/random.html)")] use core::marker::PhantomData; -use core::ops::Deref; -use crate::analog::adc::ADC; -use crate::{peripheral::Peripheral , peripherals::RNG}; +use crate::{analog::adc::Adc, peripheral::Peripheral, peripherals::RNG}; /// Random number generator driver #[derive(Clone, Copy)] @@ -123,21 +121,21 @@ impl rand_core::RngCore for Rng { } #[cfg(not(esp32p4))] -pub struct Trng<'d>{ +pub struct Trng<'d> { pub rng: Rng, - adc: &'d mut ADC<'d, crate::peripherals::ADC1> + adc: &'d mut Adc<'d, crate::peripherals::ADC1>, } #[cfg(not(esp32p4))] impl<'d> Trng<'d> { /// Create a new True Random Number Generator instance - pub fn new(rng: impl Peripheral

, adc: &'d mut ADC<'d, crate::peripherals::ADC1>) -> Self { - let gen = Rng::new(rng); + pub fn new( + rng: impl Peripheral

, + adc: &'d mut Adc<'d, crate::peripherals::ADC1>, + ) -> Self { + let gen = Rng::new(rng); crate::soc::trng::ensure_randomness(); - Self{ - rng: gen, - adc: adc, - } + Self { rng: gen, adc: adc } } pub fn random(&mut self) -> u32 { @@ -149,7 +147,7 @@ impl<'d> Trng<'d> { } /// Downgrade Trng to Rng and release ADC1 - pub fn downgrade(&mut self) -> (Rng, &'d mut ADC<'_, crate::peripherals::ADC1>) { + pub fn downgrade(&mut self) -> (Rng, &'d mut Adc<'_, crate::peripherals::ADC1>) { crate::soc::trng::revert_trng(); (self.rng, self.adc) } diff --git a/esp-hal/src/soc/esp32/mod.rs b/esp-hal/src/soc/esp32/mod.rs index ecb8f812a66..4d10c0be1be 100644 --- a/esp-hal/src/soc/esp32/mod.rs +++ b/esp-hal/src/soc/esp32/mod.rs @@ -17,6 +17,7 @@ pub mod peripherals; #[cfg(psram)] pub mod psram; pub mod radio_clocks; +pub mod trng; /// The name of the chip ("esp32") as `&str` #[macro_export] diff --git a/esp-hal/src/soc/esp32c2/mod.rs b/esp-hal/src/soc/esp32c2/mod.rs index 6b0b245f0fb..12d0f99f5c1 100644 --- a/esp-hal/src/soc/esp32c2/mod.rs +++ b/esp-hal/src/soc/esp32c2/mod.rs @@ -12,6 +12,7 @@ pub mod efuse; pub mod gpio; pub mod peripherals; pub mod radio_clocks; +pub mod trng; /// The name of the chip ("esp32c2") as `&str` #[macro_export] diff --git a/esp-hal/src/soc/esp32c3/mod.rs b/esp-hal/src/soc/esp32c3/mod.rs index 78e80e91c8b..a099b2a68f0 100644 --- a/esp-hal/src/soc/esp32c3/mod.rs +++ b/esp-hal/src/soc/esp32c3/mod.rs @@ -16,6 +16,7 @@ pub mod efuse; pub mod gpio; pub mod peripherals; pub mod radio_clocks; +pub mod trng; /// The name of the chip ("esp32c3") as `&str` #[macro_export] diff --git a/esp-hal/src/soc/esp32c6/mod.rs b/esp-hal/src/soc/esp32c6/mod.rs index 6a3a6149fb5..46aed344d7f 100644 --- a/esp-hal/src/soc/esp32c6/mod.rs +++ b/esp-hal/src/soc/esp32c6/mod.rs @@ -18,6 +18,7 @@ pub mod gpio; pub mod lp_core; pub mod peripherals; pub mod radio_clocks; +pub mod trng; /// The name of the chip ("esp32c6") as `&str` #[macro_export] diff --git a/esp-hal/src/soc/esp32c6/trng.rs b/esp-hal/src/soc/esp32c6/trng.rs index cb4da1b5ad9..803ec7fcd85 100644 --- a/esp-hal/src/soc/esp32c6/trng.rs +++ b/esp-hal/src/soc/esp32c6/trng.rs @@ -66,21 +66,21 @@ const ADC_SAR2_INITIAL_CODE_LOW_ADDR: u8 = 0x3; const ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB: u8 = 0x7; const ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB: u8 = 0x0; -const ADC_SAR1_INITIAL_CODE_HIGH_ADDR: u8 = 0x1; -const ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB: u8 = 0x3; -const ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB: u8 = 0x0; +const ADC_SAR1_INITIAL_CODE_HIGH_ADDR: u8 = 0x1; +const ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB: u8 = 0x3; +const ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB: u8 = 0x0; const ADC_SAR1_INITIAL_CODE_LOW_ADDR: u8 = 0x0; const ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB: u8 = 0x7; const ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB: u8 = 0x0; -const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7; -const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 1; -const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 0; +const ADC_SARADC_DTEST_RTC_ADDR: u8 = 0x7; +const ADC_SARADC_DTEST_RTC_ADDR_MSB: u8 = 1; +const ADC_SARADC_DTEST_RTC_ADDR_LSB: u8 = 0; -const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x7 +const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x7; const ADC_SARADC_ENT_RTC_ADDR_MSB: u8 = 3; -const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 3; +const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 3; const ADC_SARADC1_ENCAL_REF_ADDR: u8 = 0x7; const ADC_SARADC1_ENCAL_REF_ADDR_MSB: u8 = 4; @@ -169,7 +169,7 @@ pub(crate) fn ensure_randomness() { regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SAR2_INITIAL_CODE_HIGH_ADDR + ADC_SAR2_INITIAL_CODE_HIGH_ADDR, ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB, ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB, 0x60, @@ -178,16 +178,16 @@ pub(crate) fn ensure_randomness() { regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SAR2_INITIAL_CODE_LOW_ADDR + ADC_SAR2_INITIAL_CODE_LOW_ADDR, ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB, ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB, 0x66, ); - + regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SAR1_INITIAL_CODE_HIGH_ADDR + ADC_SAR1_INITIAL_CODE_HIGH_ADDR, ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB, ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB, 0x08, @@ -196,7 +196,7 @@ pub(crate) fn ensure_randomness() { regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SAR1_INITIAL_CODE_LOW_ADDR + ADC_SAR1_INITIAL_CODE_LOW_ADDR, ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB, ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB, 0x66, @@ -239,7 +239,7 @@ pub(crate) fn ensure_randomness() { } pub(crate) fn revert_trng() { - reg_clr_bit(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); + reg_clr_bit(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); reg_write(APB_SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF); regi2c_write_mask( @@ -259,7 +259,7 @@ pub(crate) fn revert_trng() { ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB, 0, ); - + regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, @@ -432,3 +432,9 @@ pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, l regi2c_disable_block(block); } + +fn clear_peri_reg_mask(reg: u32, mask: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + } +} diff --git a/esp-hal/src/soc/esp32h2/mod.rs b/esp-hal/src/soc/esp32h2/mod.rs index d5a1ef426fc..fdbf66a26e9 100644 --- a/esp-hal/src/soc/esp32h2/mod.rs +++ b/esp-hal/src/soc/esp32h2/mod.rs @@ -17,6 +17,7 @@ pub mod efuse; pub mod gpio; pub mod peripherals; pub mod radio_clocks; +pub mod trng; /// The name of the chip ("esp32h2") as `&str` #[macro_export] diff --git a/esp-hal/src/soc/esp32s2/mod.rs b/esp-hal/src/soc/esp32s2/mod.rs index 5d10e73452e..8fbf4a6390d 100644 --- a/esp-hal/src/soc/esp32s2/mod.rs +++ b/esp-hal/src/soc/esp32s2/mod.rs @@ -20,6 +20,7 @@ pub mod peripherals; #[cfg(psram)] pub mod psram; pub mod radio_clocks; +pub mod trng; pub mod ulp_core; diff --git a/esp-hal/src/soc/esp32s3/mod.rs b/esp-hal/src/soc/esp32s3/mod.rs index f0fc69a27ea..5a76765f722 100644 --- a/esp-hal/src/soc/esp32s3/mod.rs +++ b/esp-hal/src/soc/esp32s3/mod.rs @@ -21,6 +21,7 @@ pub mod peripherals; #[cfg(psram)] pub mod psram; pub mod radio_clocks; +pub mod trng; pub mod ulp_core; diff --git a/examples/src/bin/rng.rs b/examples/src/bin/rng.rs index ee854799ad4..908ef4130d4 100644 --- a/examples/src/bin/rng.rs +++ b/examples/src/bin/rng.rs @@ -6,30 +6,32 @@ #![no_main] use esp_backtrace as _; -use esp_hal::{prelude::*, rng::Trng, - analog::adc::{AdcConfig, Attenuation, ADC}, +use esp_hal::{ + analog::adc::{Adc, AdcConfig, Attenuation}, clock::ClockControl, delay::Delay, - gpio::IO, - peripherals::{Peripherals, ADC1}}; - + gpio::Io, + peripherals::{Peripherals, ADC1}, + prelude::*, + rng::Trng, +}; use esp_println::println; #[entry] fn main() -> ! { let peripherals = Peripherals::take(); - let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); + let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); let analog_pin = io.pins.gpio3.into_analog(); let mut adc1_config = AdcConfig::new(); let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); - let mut adc1 = ADC::::new(peripherals.ADC1, adc1_config); + let mut adc1 = Adc::::new(peripherals.ADC1, adc1_config); let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); - + let mut trng = Trng::new(peripherals.RNG, &mut adc1); - + let (mut rng, adc1) = trng.downgrade(); - + // Fill a buffer with random bytes: let mut buf = [0u8; 16]; // trng.read(&mut buf); From 75d4f4f88e1e91a1785461acdfe70aa968f122c6 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Sun, 5 May 2024 15:26:07 +0200 Subject: [PATCH 07/16] Small fixes fmt --- esp-hal/src/rng.rs | 2 +- esp-hal/src/soc/esp32h2/trng.rs | 2 +- examples/src/bin/rng.rs | 31 ++++++------------------------- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index fdc5fff3ab6..e7cf0830f03 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -154,7 +154,7 @@ impl<'d> Trng<'d> { } #[cfg(feature = "embedded-hal-02")] -impl embedded_hal_02::blocking::rng::Read for Trng { +impl embedded_hal_02::blocking::rng::Read for Trng<'_> { type Error = core::convert::Infallible; fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> { diff --git a/esp-hal/src/soc/esp32h2/trng.rs b/esp-hal/src/soc/esp32h2/trng.rs index ba8ce366270..f51b34b5d04 100644 --- a/esp-hal/src/soc/esp32h2/trng.rs +++ b/esp-hal/src/soc/esp32h2/trng.rs @@ -283,7 +283,7 @@ pub(crate) fn revert_trng() { regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - I2C_SARADC_EN_TOUT_SAR1_BUS + I2C_SARADC_EN_TOUT_SAR1_BUS, I2C_SARADC_EN_TOUT_SAR1_BUS_MSB, I2C_SARADC_EN_TOUT_SAR1_BUS_LSB, 0, diff --git a/examples/src/bin/rng.rs b/examples/src/bin/rng.rs index 908ef4130d4..fc87b7d8fda 100644 --- a/examples/src/bin/rng.rs +++ b/examples/src/bin/rng.rs @@ -6,40 +6,21 @@ #![no_main] use esp_backtrace as _; -use esp_hal::{ - analog::adc::{Adc, AdcConfig, Attenuation}, - clock::ClockControl, - delay::Delay, - gpio::Io, - peripherals::{Peripherals, ADC1}, - prelude::*, - rng::Trng, -}; +use esp_hal::{peripherals::Peripherals, prelude::*, rng::Rng}; use esp_println::println; #[entry] fn main() -> ! { let peripherals = Peripherals::take(); - let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); + let mut rng = Rng::new(peripherals.RNG); - let analog_pin = io.pins.gpio3.into_analog(); - let mut adc1_config = AdcConfig::new(); - let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); - let mut adc1 = Adc::::new(peripherals.ADC1, adc1_config); - let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); - - let mut trng = Trng::new(peripherals.RNG, &mut adc1); - - let (mut rng, adc1) = trng.downgrade(); + // Generate a random word (u32): + println!("Random u32: {}", rng.random()); // Fill a buffer with random bytes: let mut buf = [0u8; 16]; - // trng.read(&mut buf); + rng.read(&mut buf); println!("Random bytes: {:?}", buf); - loop { - println!("Random u32: {}", rng.random()); - let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); - println!("ADC reading = {}", pin_value); - } + loop {} } From 9905b50220504b3061107578bcc8d0ed560f61a6 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Sun, 5 May 2024 15:45:06 +0200 Subject: [PATCH 08/16] Fmt + clippy + changelog --- esp-hal/CHANGELOG.md | 1 + esp-hal/src/rng.rs | 2 +- esp-hal/src/soc/esp32/trng.rs | 24 +++++++++++++++++------ esp-hal/src/soc/esp32c2/trng.rs | 28 +++++++++++++++++++++++---- esp-hal/src/soc/esp32c3/trng.rs | 34 ++++++++++++++++++++++++++------- esp-hal/src/soc/esp32h2/trng.rs | 4 ++-- esp-hal/src/soc/esp32s2/trng.rs | 19 ++++++++++-------- esp-hal/src/soc/esp32s3/trng.rs | 12 ++++++++---- 8 files changed, 92 insertions(+), 32 deletions(-) diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index bb9e5d051a2..8e65e778866 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -55,6 +55,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `embassy-usb` support (#1517) - SPI Slave support for ESP32-S2 (#1562) - Add new generic `OneShotTimer` and `PeriodicTimer` drivers, plus new `Timer` trait which is implemented for `TIMGx` and `SYSTIMER` (#1570) +- Feature: correct `TRNG` mechanism #1804 ### Fixed diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index e7cf0830f03..f7f4a547c03 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -135,7 +135,7 @@ impl<'d> Trng<'d> { ) -> Self { let gen = Rng::new(rng); crate::soc::trng::ensure_randomness(); - Self { rng: gen, adc: adc } + Self { rng: gen, adc } } pub fn random(&mut self) -> u32 { diff --git a/esp-hal/src/soc/esp32/trng.rs b/esp-hal/src/soc/esp32/trng.rs index d18825688e7..d41ea719314 100644 --- a/esp-hal/src/soc/esp32/trng.rs +++ b/esp-hal/src/soc/esp32/trng.rs @@ -138,8 +138,7 @@ pub fn ensure_randomness() { set_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_RX_START); } -pub fn revert_trng() -{ +pub fn revert_trng() { clear_peri_reg_mask(I2S_CONF_REG0, I2S_RX_START); set_peri_reg_mask(I2S_CONF_REG0, I2S_RX_RESET); clear_peri_reg_mask(I2S_CONF_REG0, I2S_RX_RESET); @@ -152,11 +151,24 @@ pub fn revert_trng() clear_peri_reg_mask(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE); clear_peri_reg_mask(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST); - clear_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX | SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S); + clear_peri_reg_mask( + SYSCON_SARADC_CTRL_REG, + SYSCON_SARADC_SAR2_MUX | SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S, + ); - set_peri_reg_bits(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S); + set_peri_reg_bits( + SENS_SAR_MEAS_WAIT2_REG, + SENS_FORCE_XPD_SAR, + 0, + SENS_FORCE_XPD_SAR_S, + ); - set_peri_reg_bits(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 8, SYSCON_SARADC_START_WAIT_S); + set_peri_reg_bits( + SYSCON_SARADC_FSM_REG, + SYSCON_SARADC_START_WAIT, + 8, + SYSCON_SARADC_START_WAIT_S, + ); } fn set_peri_reg_bits(reg: u32, bitmap: u32, value: u32, shift: u32) { @@ -183,4 +195,4 @@ fn write_peri_reg(reg: u32, val: u32) { unsafe { (reg as *mut u32).write_volatile(val); } -} \ No newline at end of file +} diff --git a/esp-hal/src/soc/esp32c2/trng.rs b/esp-hal/src/soc/esp32c2/trng.rs index 3a4a22fc49c..016dbc9d61e 100644 --- a/esp-hal/src/soc/esp32c2/trng.rs +++ b/esp-hal/src/soc/esp32c2/trng.rs @@ -173,11 +173,31 @@ pub(crate) fn revert_trng() { regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); clear_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); - reg_set_field(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1_V, APB_SARADC_SAR_PATT_TAB1_S, 0xffffff); - reg_set_field(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2_V, APB_SARADC_SAR_PATT_TAB2_S, 0xffffff); + reg_set_field( + APB_SARADC_SAR_PATT_TAB1_REG, + APB_SARADC_SAR_PATT_TAB1_V, + APB_SARADC_SAR_PATT_TAB1_S, + 0xffffff, + ); + reg_set_field( + APB_SARADC_SAR_PATT_TAB2_REG, + APB_SARADC_SAR_PATT_TAB2_V, + APB_SARADC_SAR_PATT_TAB2_S, + 0xffffff, + ); clear_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); - reg_set_field(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE_V, APB_SARADC_XPD_SAR_FORCE_S, 0); - reg_set_field(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR_V, RTC_CNTL_FORCE_XPD_SAR_S, 0); + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_XPD_SAR_FORCE_V, + APB_SARADC_XPD_SAR_FORCE_S, + 0, + ); + reg_set_field( + RTC_CNTL_SENSOR_CTRL_REG, + RTC_CNTL_FORCE_XPD_SAR_V, + RTC_CNTL_FORCE_XPD_SAR_S, + 0, + ); } fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { diff --git a/esp-hal/src/soc/esp32c3/trng.rs b/esp-hal/src/soc/esp32c3/trng.rs index 0401686c232..27afd6409b6 100644 --- a/esp-hal/src/soc/esp32c3/trng.rs +++ b/esp-hal/src/soc/esp32c3/trng.rs @@ -170,17 +170,37 @@ pub(crate) fn ensure_randomness() { } pub(crate) fn revert_trng() { - /* Restore internal I2C bus state */ + // Restore internal I2C bus state regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); - /* Restore SARADC to default mode */ + // Restore SARADC to default mode clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); clear_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); - reg_set_field(APB_SARADC_SAR_PATT_TAB1_REG, APB_SARADC_SAR_PATT_TAB1_V, APB_SARADC_SAR_PATT_TAB1_S, 0xffffff); - reg_set_field(APB_SARADC_SAR_PATT_TAB2_REG, APB_SARADC_SAR_PATT_TAB2_V, APB_SARADC_SAR_PATT_TAB2_S, 0xffffff); + reg_set_field( + APB_SARADC_SAR_PATT_TAB1_REG, + APB_SARADC_SAR_PATT_TAB1_V, + APB_SARADC_SAR_PATT_TAB1_S, + 0xffffff, + ); + reg_set_field( + APB_SARADC_SAR_PATT_TAB2_REG, + APB_SARADC_SAR_PATT_TAB2_V, + APB_SARADC_SAR_PATT_TAB2_S, + 0xffffff, + ); clear_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); - reg_set_field(APB_SARADC_CTRL_REG, APB_SARADC_XPD_SAR_FORCE_V, APB_SARADC_XPD_SAR_FORCE_S, 0); - reg_set_field(RTC_CNTL_SENSOR_CTRL_REG, RTC_CNTL_FORCE_XPD_SAR_V, RTC_CNTL_FORCE_XPD_SAR_S, 0); + reg_set_field( + APB_SARADC_CTRL_REG, + APB_SARADC_XPD_SAR_FORCE_V, + APB_SARADC_XPD_SAR_FORCE_S, + 0, + ); + reg_set_field( + RTC_CNTL_SENSOR_CTRL_REG, + RTC_CNTL_FORCE_XPD_SAR_V, + RTC_CNTL_FORCE_XPD_SAR_S, + 0, + ); } fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { @@ -202,4 +222,4 @@ fn clear_peri_reg_mask(reg: u32, mask: u32) { unsafe { (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); } -} \ No newline at end of file +} diff --git a/esp-hal/src/soc/esp32h2/trng.rs b/esp-hal/src/soc/esp32h2/trng.rs index f51b34b5d04..311d1cd8b8a 100644 --- a/esp-hal/src/soc/esp32h2/trng.rs +++ b/esp-hal/src/soc/esp32h2/trng.rs @@ -243,7 +243,7 @@ pub(crate) fn revert_trng() { I2C_SARADC_SAR2_INIT_CODE_LSB_LSB, 0, ); - + regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, @@ -291,7 +291,7 @@ pub(crate) fn revert_trng() { // disable ADC_CTRL_CLK (SAR ADC function clock) reg_write(PCR_SARADC_CLKM_CONF_REG, 0x00404000); - + // Set PCR_SARADC_CONF_REG to initial state reg_write(PCR_SARADC_CONF_REG, 0x5); } diff --git a/esp-hal/src/soc/esp32s2/trng.rs b/esp-hal/src/soc/esp32s2/trng.rs index d9458f259c1..2455e956f11 100644 --- a/esp-hal/src/soc/esp32s2/trng.rs +++ b/esp-hal/src/soc/esp32s2/trng.rs @@ -196,8 +196,7 @@ pub(crate) fn ensure_randomness() { set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); } -pub fn revert_trng() -{ +pub fn revert_trng() { // Restore internal I2C bus state regi2c_write_mask( I2C_SAR_ADC, @@ -205,7 +204,7 @@ pub fn revert_trng() ADC_SAR1_DREF_ADDR, ADC_SAR1_DREF_ADDR_MSB, ADC_SAR1_DREF_ADDR_LSB, - 0x1 + 0x1, ); regi2c_write_mask( @@ -214,7 +213,7 @@ pub fn revert_trng() ADC_SAR2_DREF_ADDR, ADC_SAR2_DREF_ADDR_MSB, ADC_SAR2_DREF_ADDR_LSB, - 0x1 + 0x1, ); regi2c_write_mask( @@ -247,7 +246,12 @@ pub fn revert_trng() // Restore SARADC to default mode clear_peri_reg_mask(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE); set_peri_reg_mask(DPORT_PERIP_CLK_EN0_REG, DPORT_APB_SARADC_CLK_EN); - set_peri_reg_bits(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S); + set_peri_reg_bits( + SENS_SAR_POWER_XPD_SAR_REG, + SENS_FORCE_XPD_SAR, + 0, + SENS_FORCE_XPD_SAR_S, + ); clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); } @@ -370,8 +374,7 @@ fn set_peri_reg_mask(reg: u32, mask: u32) { fn set_peri_reg_bits(reg: u32, bitmap: u32, value: u32, shift: u32) { unsafe { (reg as *mut u32).write_volatile( - ((reg as *mut u32).read_volatile() & !(bitmap << shift)) - | ((value & bitmap) << shift), + ((reg as *mut u32).read_volatile() & !(bitmap << shift)) | ((value & bitmap) << shift), ); } } @@ -386,4 +389,4 @@ fn write_peri_reg(reg: u32, val: u32) { unsafe { (reg as *mut u32).write_volatile(val); } -} \ No newline at end of file +} diff --git a/esp-hal/src/soc/esp32s3/trng.rs b/esp-hal/src/soc/esp32s3/trng.rs index d533d3d661c..5d39fbf0f6c 100644 --- a/esp-hal/src/soc/esp32s3/trng.rs +++ b/esp-hal/src/soc/esp32s3/trng.rs @@ -183,8 +183,7 @@ pub(crate) fn ensure_randomness() { regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 1); } -pub fn revert_trng() -{ +pub fn revert_trng() { regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 0); regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); @@ -193,7 +192,12 @@ pub fn revert_trng() regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); - reg_set_field(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR_V, SENS_FORCE_XPD_SAR_S, 0); + reg_set_field( + SENS_SAR_POWER_XPD_SAR_REG, + SENS_FORCE_XPD_SAR_V, + SENS_FORCE_XPD_SAR_S, + 0, + ); clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); @@ -233,4 +237,4 @@ fn write_peri_reg(reg: u32, val: u32) { unsafe { (reg as *mut u32).write_volatile(val); } -} \ No newline at end of file +} From 401fa75dc8290ea204dc01a87a61243c75b40067 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 13 May 2024 13:30:56 +0200 Subject: [PATCH 09/16] Comments, `RngCore` trait for `Trng` --- esp-hal/src/rng.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index f7f4a547c03..9f3f97636e0 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -120,15 +120,54 @@ impl rand_core::RngCore for Rng { } } +/// True Random Number Generator (TRNG) driver +/// +/// The `Trng` struct represents a true random number generator that combines +/// the randomness from the hardware RNG and an ADC. This struct provides methods +/// to generate random numbers and fill buffers with random bytes. +/// Due to pulling the entropy source from the ADC, it uses the associated regiters, +/// so to use TRNG we need to "occupy" the ADC peripheral. +/// +/// ```no_run +/// let analog_pin = io.pins.gpio3.into_analog(); +/// let mut adc1_config = AdcConfig::new(); +/// let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); +/// let mut adc1 = ADC::::new(peripherals.ADC1, adc1_config); +/// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); +/// +/// let mut trng = Trng::new(peripherals.RNG, &mut adc1); +/// +/// let (mut rng, adc1) = trng.downgrade(); +/// +/// // Fill a buffer with random bytes: +/// let mut buf = [0u8; 16]; +/// println!("Random bytes: {:?}", buf); +/// +/// println!("Random u32: {}", rng.random()); +/// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); +/// println!("ADC reading = {}", pin_value); +/// +/// ``` #[cfg(not(esp32p4))] pub struct Trng<'d> { + /// The hardware random number generator instance. pub rng: Rng, + /// A mutable reference to the ADC1 instance. adc: &'d mut Adc<'d, crate::peripherals::ADC1>, } #[cfg(not(esp32p4))] impl<'d> Trng<'d> { - /// Create a new True Random Number Generator instance + /// Creates a new True Random Number Generator (TRNG) instance. + /// + /// # Arguments + /// + /// * `rng` - A peripheral instance implementing the `RNG` trait. + /// * `adc` - A mutable reference to an `Adc` instance. + /// + /// # Returns + /// + /// Returns a new `Trng` instance. pub fn new( rng: impl Peripheral

, adc: &'d mut Adc<'d, crate::peripherals::ADC1>, @@ -138,15 +177,18 @@ impl<'d> Trng<'d> { Self { rng: gen, adc } } + /// Reads currently available `u32` integer from `TRNG` pub fn random(&mut self) -> u32 { self.rng.random() } + /// Fills the provided buffer with random bytes. pub fn read(&mut self, buffer: &mut [u8]) { self.rng.read(buffer) } - /// Downgrade Trng to Rng and release ADC1 + /// Downgrades the `Trng` instance to a `Rng` instance and releases the ADC1. + /// Returns a tuple containing the `Rng` instance and a mutable reference to the `Adc`. pub fn downgrade(&mut self) -> (Rng, &'d mut Adc<'_, crate::peripherals::ADC1>) { crate::soc::trng::revert_trng(); (self.rng, self.adc) @@ -156,12 +198,32 @@ impl<'d> Trng<'d> { #[cfg(feature = "embedded-hal-02")] impl embedded_hal_02::blocking::rng::Read for Trng<'_> { type Error = core::convert::Infallible; - + /// Fills the provided buffer with random bytes. fn read(&mut self, buffer: &mut [u8]) -> Result<(), Self::Error> { self.rng.read(buffer); Ok(()) } } +/// Implementing RngCore trait from rand_core for `Trng` structure +impl rand_core::RngCore for Trng<'_> { + fn next_u32(&mut self) -> u32 { + self.rng.next_u32() + } + + fn next_u64(&mut self) -> u64 { + self.rng.next_u64() + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.rng.fill_bytes(dest) + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { + self.rng.try_fill_bytes(dest) + } +} + +/// Implementing a CryptoRng marker trait that indicates that the generator is cryptographically secure. #[cfg(not(esp32p4))] impl rand_core::CryptoRng for Trng<'_> {} From 324168d630fe02c4bee43a8cf036687d932815e5 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 13 May 2024 14:28:11 +0200 Subject: [PATCH 10/16] fmt --- esp-hal/src/rng.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index 9f3f97636e0..c908db6627d 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -123,30 +123,29 @@ impl rand_core::RngCore for Rng { /// True Random Number Generator (TRNG) driver /// /// The `Trng` struct represents a true random number generator that combines -/// the randomness from the hardware RNG and an ADC. This struct provides methods -/// to generate random numbers and fill buffers with random bytes. -/// Due to pulling the entropy source from the ADC, it uses the associated regiters, -/// so to use TRNG we need to "occupy" the ADC peripheral. -/// +/// the randomness from the hardware RNG and an ADC. This struct provides +/// methods to generate random numbers and fill buffers with random bytes. +/// Due to pulling the entropy source from the ADC, it uses the associated +/// regiters, so to use TRNG we need to "occupy" the ADC peripheral. +/// /// ```no_run /// let analog_pin = io.pins.gpio3.into_analog(); /// let mut adc1_config = AdcConfig::new(); /// let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); /// let mut adc1 = ADC::::new(peripherals.ADC1, adc1_config); /// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); -/// +/// /// let mut trng = Trng::new(peripherals.RNG, &mut adc1); -/// +/// /// let (mut rng, adc1) = trng.downgrade(); -/// -/// // Fill a buffer with random bytes: +/// +/// // Fill a buffer with random bytes: /// let mut buf = [0u8; 16]; /// println!("Random bytes: {:?}", buf); -/// +/// /// println!("Random u32: {}", rng.random()); /// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); /// println!("ADC reading = {}", pin_value); -/// /// ``` #[cfg(not(esp32p4))] pub struct Trng<'d> { @@ -187,8 +186,9 @@ impl<'d> Trng<'d> { self.rng.read(buffer) } - /// Downgrades the `Trng` instance to a `Rng` instance and releases the ADC1. - /// Returns a tuple containing the `Rng` instance and a mutable reference to the `Adc`. + /// Downgrades the `Trng` instance to a `Rng` instance and releases the + /// ADC1. Returns a tuple containing the `Rng` instance and a mutable + /// reference to the `Adc`. pub fn downgrade(&mut self) -> (Rng, &'d mut Adc<'_, crate::peripherals::ADC1>) { crate::soc::trng::revert_trng(); (self.rng, self.adc) @@ -224,6 +224,7 @@ impl rand_core::RngCore for Trng<'_> { } } -/// Implementing a CryptoRng marker trait that indicates that the generator is cryptographically secure. +/// Implementing a CryptoRng marker trait that indicates that the generator is +/// cryptographically secure. #[cfg(not(esp32p4))] impl rand_core::CryptoRng for Trng<'_> {} From 1c707249b02d7dff934ccd55f892417d18898992 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Fri, 28 Jun 2024 13:43:58 +0200 Subject: [PATCH 11/16] Make ADC work correctly on TRNG drop, PAC functions instead of raw regs --- esp-hal/src/rng.rs | 45 +- esp-hal/src/soc/esp32/trng.rs | 329 +++++++-------- esp-hal/src/soc/esp32c2/trng.rs | 300 +++++--------- esp-hal/src/soc/esp32c3/trng.rs | 303 +++++--------- esp-hal/src/soc/esp32c6/trng.rs | 708 ++++++++++++++++---------------- esp-hal/src/soc/esp32h2/trng.rs | 557 ++++++++++++------------- esp-hal/src/soc/esp32s2/trng.rs | 387 ++++++++--------- esp-hal/src/soc/esp32s3/trng.rs | 305 +++++--------- 8 files changed, 1268 insertions(+), 1666 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index c908db6627d..346cd98bf2e 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -44,7 +44,10 @@ use core::marker::PhantomData; -use crate::{analog::adc::Adc, peripheral::Peripheral, peripherals::RNG}; +use crate::{ + peripheral::{Peripheral, PeripheralRef}, + peripherals::{ADC1, RNG}, +}; /// Random number generator driver #[derive(Clone, Copy)] @@ -135,27 +138,29 @@ impl rand_core::RngCore for Rng { /// let mut adc1 = ADC::::new(peripherals.ADC1, adc1_config); /// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); /// +/// let mut buf = [0u8; 16]; /// let mut trng = Trng::new(peripherals.RNG, &mut adc1); +/// trng.read(&mut buf); /// -/// let (mut rng, adc1) = trng.downgrade(); +/// println!("TRNG: Random bytes: {:?}", buf); +/// println!("TRNG: Random u32: {}", rng.random()); /// -/// // Fill a buffer with random bytes: -/// let mut buf = [0u8; 16]; +/// let mut rng = trng.downgrade(); +/// +/// rng.read(&mut buf); /// println!("Random bytes: {:?}", buf); /// /// println!("Random u32: {}", rng.random()); /// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); /// println!("ADC reading = {}", pin_value); /// ``` -#[cfg(not(esp32p4))] pub struct Trng<'d> { /// The hardware random number generator instance. pub rng: Rng, /// A mutable reference to the ADC1 instance. - adc: &'d mut Adc<'d, crate::peripherals::ADC1>, + _adc: PeripheralRef<'d, ADC1>, } -#[cfg(not(esp32p4))] impl<'d> Trng<'d> { /// Creates a new True Random Number Generator (TRNG) instance. /// @@ -167,13 +172,15 @@ impl<'d> Trng<'d> { /// # Returns /// /// Returns a new `Trng` instance. - pub fn new( - rng: impl Peripheral

, - adc: &'d mut Adc<'d, crate::peripherals::ADC1>, - ) -> Self { + pub fn new(rng: impl Peripheral

, adc: impl Peripheral

+ 'd) -> Self { + crate::into_ref!(adc); + let gen = Rng::new(rng); crate::soc::trng::ensure_randomness(); - Self { rng: gen, adc } + Self { + rng: gen, + _adc: adc, + } } /// Reads currently available `u32` integer from `TRNG` @@ -183,15 +190,18 @@ impl<'d> Trng<'d> { /// Fills the provided buffer with random bytes. pub fn read(&mut self, buffer: &mut [u8]) { - self.rng.read(buffer) + self.rng.read(buffer); } /// Downgrades the `Trng` instance to a `Rng` instance and releases the - /// ADC1. Returns a tuple containing the `Rng` instance and a mutable - /// reference to the `Adc`. - pub fn downgrade(&mut self) -> (Rng, &'d mut Adc<'_, crate::peripherals::ADC1>) { + /// ADC1. + pub fn downgrade(self) -> Rng { + self.rng + } +} +impl<'d> Drop for Trng<'d> { + fn drop(&mut self) { crate::soc::trng::revert_trng(); - (self.rng, self.adc) } } @@ -226,5 +236,4 @@ impl rand_core::RngCore for Trng<'_> { /// Implementing a CryptoRng marker trait that indicates that the generator is /// cryptographically secure. -#[cfg(not(esp32p4))] impl rand_core::CryptoRng for Trng<'_> {} diff --git a/esp-hal/src/soc/esp32/trng.rs b/esp-hal/src/soc/esp32/trng.rs index d41ea719314..f8bf24a4c83 100644 --- a/esp-hal/src/soc/esp32/trng.rs +++ b/esp-hal/src/soc/esp32/trng.rs @@ -1,198 +1,155 @@ -const DR_REG_RTCCNTL_BASE: u32 = 0x3ff48000; -const RTC_CNTL_TEST_MUX_REG: u32 = DR_REG_RTCCNTL_BASE + 0xa8; -const RTC_CNTL_DTEST_RTC: u32 = 0x00000003; -const RTC_CNTL_DTEST_RTC_S: u32 = 30; -const RTC_CNTL_ENT_RTC: u32 = 1 << 29; -const SENS_SAR_START_FORCE_REG: u32 = 0x3ff48800 + 0x002c; -const SENS_SAR2_EN_TEST: u32 = 1 << 4; -const DPORT_PERIP_CLK_EN_REG: u32 = 0x3ff00000 + 0x0c0; -const DPORT_I2C_EXT0_CLK_EN: u32 = 1 << 7; - -const DPORT_PERIP_RST_EN_REG: u32 = 0x3ff00000 + 0x0c4; -const DPORT_I2C_EXT0_RST: u32 = 1 << 7; - -const SENS_ULP_CP_FORCE_START_TOP: u32 = 1 << 8; -const SENS_ULP_CP_START_TOP: u32 = 1 << 9; - -const DR_REG_I2S_BASE: u32 = 0x3ff4f000; - -const DR_REG_SYSCON_BASE: u32 = 0x3ff66000; -const SYSCON_SARADC_CTRL_REG: u32 = DR_REG_SYSCON_BASE + 0x10; -const SYSCON_SARADC_FSM_REG: u32 = DR_REG_SYSCON_BASE + 0x18; -const SYSCON_SARADC_SAR2_PATT_TAB1_REG: u32 = DR_REG_SYSCON_BASE + 0x2c; -const SYSCON_SARADC_SAR2_PATT_TAB2_REG: u32 = DR_REG_SYSCON_BASE + 0x30; -const SYSCON_SARADC_SAR2_PATT_TAB3_REG: u32 = DR_REG_SYSCON_BASE + 0x34; -const SYSCON_SARADC_SAR2_PATT_TAB4_REG: u32 = DR_REG_SYSCON_BASE + 0x38; -const SYSCON_SARADC_SAR2_MUX: u32 = 1 << 2; -const SYSCON_SARADC_SAR_CLK_DIV: u32 = 0x000000FF; -const SYSCON_SARADC_SAR_CLK_DIV_S: u32 = 7; -const SYSCON_SARADC_RSTB_WAIT: u32 = 0x000000FF; -const SYSCON_SARADC_RSTB_WAIT_S: u32 = 0; -const SYSCON_SARADC_START_WAIT: u32 = 1 << 2; -const SYSCON_SARADC_START_WAIT_S: u32 = 1 << 2; -const SYSCON_SARADC_WORK_MODE: u32 = 0x00000003; -const SYSCON_SARADC_WORK_MODE_S: u32 = 3; -const SYSCON_SARADC_SAR_SEL: u32 = 1 << 5; -const I2S_RX_BCK_DIV_NUM: u32 = 0x0000003F; -const I2S_RX_BCK_DIV_NUM_S: u32 = 6; -const SYSCON_SARADC_DATA_TO_I2S: u32 = 1 << 16; -const SYSCON_SARADC_DATA_SAR_SEL: u32 = 1 << 25; - -const I2S_CAMERA_EN: u32 = 1 << 0; -const I2S_LCD_EN: u32 = 1 << 5; -const I2S_DATA_ENABLE: u32 = 1 << 4; -const I2S_DATA_ENABLE_TEST_EN: u32 = 1 << 3; -const I2S_RX_START: u32 = 1 << 5; -const I2S_RX_RESET: u32 = 1 << 1; - -const DR_REG_SENS_BASE: u32 = 0x3ff48800; -const SENS_SAR_MEAS_WAIT2_REG: u32 = DR_REG_SENS_BASE + 0x000c; -const SENS_SAR_READ_CTRL_REG: u32 = DR_REG_SENS_BASE; -const SENS_SAR_READ_CTRL2_REG: u32 = DR_REG_SENS_BASE + 0x0090; -const SENS_FORCE_XPD_SAR: u32 = 0x00000003; -const SENS_FORCE_XPD_SAR_S: u32 = 18; -const SENS_SAR1_DIG_FORCE: u32 = 1 << 27; -const SENS_SAR2_DIG_FORCE: u32 = 1 << 28; - -const I2S_CONF_REG0: u32 = DR_REG_I2S_BASE + 0x00a8; +//! Helper functions for TRNG functionality pub fn ensure_randomness() { - set_peri_reg_bits( - RTC_CNTL_TEST_MUX_REG, - RTC_CNTL_DTEST_RTC, - 2, - RTC_CNTL_DTEST_RTC_S, - ); - - set_peri_reg_mask(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC); - set_peri_reg_mask(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST); - - // periph_module_enable(PERIPH_I2S0_MODULE); - set_peri_reg_mask(DPORT_PERIP_CLK_EN_REG, DPORT_I2C_EXT0_CLK_EN); - clear_peri_reg_mask(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT0_RST); - - clear_peri_reg_mask(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP); - clear_peri_reg_mask(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_START_TOP); - - // Test pattern configuration byte 0xAD: - //--[7:4] channel_sel: 10-->en_test - //--[3:2] bit_width : 3-->12bit - //--[1:0] atten : 1-->3dB attenuation - write_peri_reg(SYSCON_SARADC_SAR2_PATT_TAB1_REG, 0xADADADAD); - write_peri_reg(SYSCON_SARADC_SAR2_PATT_TAB2_REG, 0xADADADAD); - write_peri_reg(SYSCON_SARADC_SAR2_PATT_TAB3_REG, 0xADADADAD); - write_peri_reg(SYSCON_SARADC_SAR2_PATT_TAB4_REG, 0xADADADAD); - - set_peri_reg_bits( - SENS_SAR_MEAS_WAIT2_REG, - SENS_FORCE_XPD_SAR, - 3, - SENS_FORCE_XPD_SAR_S, - ); - - set_peri_reg_mask(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE); - set_peri_reg_mask(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE); - - set_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX); - set_peri_reg_bits( - SYSCON_SARADC_CTRL_REG, - SYSCON_SARADC_SAR_CLK_DIV, - 4, - SYSCON_SARADC_SAR_CLK_DIV_S, - ); - set_peri_reg_bits( - SYSCON_SARADC_FSM_REG, - SYSCON_SARADC_RSTB_WAIT, - 8, - SYSCON_SARADC_RSTB_WAIT_S, - ); - set_peri_reg_bits( - SYSCON_SARADC_FSM_REG, - SYSCON_SARADC_START_WAIT, - 10, - SYSCON_SARADC_START_WAIT_S, - ); - set_peri_reg_bits( - SYSCON_SARADC_CTRL_REG, - SYSCON_SARADC_WORK_MODE, - 0, - SYSCON_SARADC_WORK_MODE_S, - ); - - set_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL); - clear_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_SAR_SEL); - - set_peri_reg_bits( - DR_REG_I2S_BASE + 0x00b0, - I2S_RX_BCK_DIV_NUM, - 20, - I2S_RX_BCK_DIV_NUM_S, - ); - - set_peri_reg_mask(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_TO_I2S); - - clear_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_CAMERA_EN); - set_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_LCD_EN); - set_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_DATA_ENABLE); - set_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_DATA_ENABLE_TEST_EN); - set_peri_reg_mask(DR_REG_I2S_BASE + 0x00a8, I2S_RX_START); -} + let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; + let sens = unsafe { &*crate::peripherals::SENS::ptr() }; + let dport = unsafe { &*crate::peripherals::DPORT::ptr() }; + let apb_ctrl = unsafe { &*crate::peripherals::APB_CTRL::ptr() }; + let i2s0 = unsafe { &*crate::peripherals::I2S0::ptr() }; -pub fn revert_trng() { - clear_peri_reg_mask(I2S_CONF_REG0, I2S_RX_START); - set_peri_reg_mask(I2S_CONF_REG0, I2S_RX_RESET); - clear_peri_reg_mask(I2S_CONF_REG0, I2S_RX_RESET); - clear_peri_reg_mask(I2S_CONF_REG0, I2S_CAMERA_EN); - clear_peri_reg_mask(I2S_CONF_REG0, I2S_LCD_EN); - clear_peri_reg_mask(I2S_CONF_REG0, I2S_DATA_ENABLE_TEST_EN); - clear_peri_reg_mask(I2S_CONF_REG0, I2S_DATA_ENABLE); - - clear_peri_reg_mask(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE); - clear_peri_reg_mask(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE); - - clear_peri_reg_mask(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST); - clear_peri_reg_mask( - SYSCON_SARADC_CTRL_REG, - SYSCON_SARADC_SAR2_MUX | SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S, - ); - - set_peri_reg_bits( - SENS_SAR_MEAS_WAIT2_REG, - SENS_FORCE_XPD_SAR, - 0, - SENS_FORCE_XPD_SAR_S, - ); - - set_peri_reg_bits( - SYSCON_SARADC_FSM_REG, - SYSCON_SARADC_START_WAIT, - 8, - SYSCON_SARADC_START_WAIT_S, - ); -} - -fn set_peri_reg_bits(reg: u32, bitmap: u32, value: u32, shift: u32) { unsafe { - (reg as *mut u32).write_volatile( - ((reg as *mut u32).read_volatile() & !(bitmap << shift)) | ((value & bitmap) << shift), - ); - } -} + rtc_cntl.test_mux().modify(|_, w| w.dtest_rtc().bits(2)); -fn set_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); - } -} + rtc_cntl.test_mux().modify(|_, w| w.ent_rtc().set_bit()); -fn clear_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + sens.sar_start_force() + .modify(|_, w| w.sar2_en_test().set_bit()); + + // periph_module_enable(PERIPH_I2S0_MODULE); + dport + .perip_clk_en() + .modify(|_, w| w.i2c0_ext0_clk_en().set_bit()); + + dport + .perip_rst_en() + .modify(|_, w| w.i2c0_ext0_rst().clear_bit()); + + sens.sar_start_force() + .modify(|_, w| w.ulp_cp_force_start_top().clear_bit()); + + sens.sar_start_force() + .modify(|_, w| w.ulp_cp_start_top().clear_bit()); + + // Test pattern configuration byte 0xAD: + //--[7:4] channel_sel: 10-->en_test + //--[3:2] bit_width : 3-->12bit + //--[1:0] atten : 1-->3dB attenuation + apb_ctrl + .apb_saradc_sar2_patt_tab1() + .write(|w| w.bits(0xADADADAD)); + apb_ctrl + .apb_saradc_sar2_patt_tab2() + .write(|w| w.bits(0xADADADAD)); + apb_ctrl + .apb_saradc_sar2_patt_tab3() + .write(|w| w.bits(0xADADADAD)); + apb_ctrl + .apb_saradc_sar2_patt_tab4() + .write(|w| w.bits(0xADADADAD)); + + sens.sar_meas_wait2() + .modify(|_, w| w.force_xpd_sar().bits(3)); + + sens.sar_read_ctrl() + .modify(|_, w| w.sar1_dig_force().set_bit()); + + sens.sar_read_ctrl2() + .modify(|_, w| w.sar2_dig_force().set_bit()); + + apb_ctrl + .apb_saradc_ctrl() + .modify(|_, w| w.saradc_sar2_mux().set_bit()); + + apb_ctrl + .apb_saradc_ctrl() + .modify(|_, w| w.saradc_sar_clk_div().bits(4)); + + apb_ctrl + .apb_saradc_fsm() + .modify(|_, w| w.saradc_rstb_wait().bits(8)); + + apb_ctrl + .apb_saradc_fsm() + .modify(|_, w| w.saradc_start_wait().bits(10)); + + apb_ctrl + .apb_saradc_ctrl() + .modify(|_, w| w.saradc_work_mode().bits(0)); + + apb_ctrl + .apb_saradc_ctrl() + .modify(|_, w| w.saradc_sar_sel().set_bit()); + + apb_ctrl + .apb_saradc_ctrl() + .modify(|_, w| w.saradc_data_sar_sel().clear_bit()); + + i2s0.sample_rate_conf() + .modify(|_, w| w.rx_bck_div_num().bits(20)); + + apb_ctrl + .apb_saradc_ctrl() + .modify(|_, w| w.saradc_data_to_i2s().set_bit()); + + i2s0.conf2().modify(|_, w| w.camera_en().set_bit()); + + i2s0.conf2().modify(|_, w| w.lcd_en().set_bit()); + + i2s0.conf2().modify(|_, w| w.data_enable().set_bit()); + + i2s0.conf2() + .modify(|_, w| w.data_enable_test_en().set_bit()); + + i2s0.conf().modify(|_, w| w.rx_start().set_bit()); } } -fn write_peri_reg(reg: u32, val: u32) { +pub fn revert_trng() { + let sens = unsafe { &*crate::peripherals::SENS::ptr() }; + let i2s0 = unsafe { &*crate::peripherals::I2S0::ptr() }; + let apb_ctrl = unsafe { &*crate::peripherals::APB_CTRL::ptr() }; + unsafe { - (reg as *mut u32).write_volatile(val); + i2s0.conf().modify(|_, w| w.rx_start().clear_bit()); + + i2s0.conf().modify(|_, w| w.rx_reset().set_bit()); + + i2s0.conf().modify(|_, w| w.rx_reset().clear_bit()); + + i2s0.conf2().modify(|_, w| { + w.camera_en() + .clear_bit() + .lcd_en() + .clear_bit() + .data_enable_test_en() + .clear_bit() + .data_enable() + .clear_bit() + }); + + sens.sar_read_ctrl() + .modify(|_, w| w.sar1_dig_force().clear_bit()); + + sens.sar_read_ctrl2() + .modify(|_, w| w.sar2_dig_force().clear_bit()); + + sens.sar_start_force() + .modify(|_, w| w.sar2_en_test().clear_bit()); + + apb_ctrl.apb_saradc_ctrl().modify(|_, w| { + w.saradc_sar2_mux() + .clear_bit() + .saradc_sar_sel() + .clear_bit() + .saradc_data_to_i2s() + .clear_bit() + }); + + sens.sar_meas_wait2() + .modify(|_, w| w.force_xpd_sar().bits(0)); + + apb_ctrl + .apb_saradc_fsm() + .modify(|_, w| w.saradc_start_wait().bits(8)); } } diff --git a/esp-hal/src/soc/esp32c2/trng.rs b/esp-hal/src/soc/esp32c2/trng.rs index 016dbc9d61e..88c5db4b23f 100644 --- a/esp-hal/src/soc/esp32c2/trng.rs +++ b/esp-hal/src/soc/esp32c2/trng.rs @@ -1,10 +1,3 @@ -const DR_REG_RTCCNTL_BASE: u32 = 0x60008000; -const RTC_CNTL_SENSOR_CTRL_REG: u32 = DR_REG_RTCCNTL_BASE + 0x108; -const RTC_CNTL_FORCE_XPD_SAR_V: u32 = 0x3; -const RTC_CNTL_FORCE_XPD_SAR_S: u32 = 30; -const RTC_CNTL_ANA_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x2c; -const RTC_CNTL_SAR_I2C_PU_M: u32 = 1 << 22; - const I2C_SAR_ADC: u8 = 0x69; const I2C_SAR_ADC_HOSTID: u8 = 0; const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7; @@ -20,203 +13,120 @@ const ADC_SARADC_ENT_TSENS_ADDR: u8 = 0x07; const ADC_SARADC_ENT_TSENS_ADDR_MSB: u8 = 2; const ADC_SARADC_ENT_TSENS_ADDR_LSB: u8 = 2; -const DR_REG_SYSTEM_BASE: u32 = 0x600c0000; -const SYSTEM_PERIP_CLK_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x10; -const SYSTEM_PERIP_RST_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x18; -const APB_SARADC_CLK_EN_M: u32 = 0x00000001 << 28; -const DR_REG_APB_SARADC_BASE: u32 = 0x60040000; -const APB_SARADC_APB_ADC_CLKM_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x54; -const APB_SARADC_REG_CLK_SEL_V: u32 = 0x00000003; -const APB_SARADC_REG_CLK_SEL_S: u32 = 21; -const APB_SARADC_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE; -const APB_SARADC_SAR_PATT_P_CLEAR_M: u32 = 0x00000001 << 23; -const APB_SARADC_SAR_PATT_LEN_V: u32 = 0x00000007; -const APB_SARADC_SAR_PATT_LEN_S: u32 = 15; -const APB_SARADC_SAR_CLK_GATED_M: u32 = 0x00000001 << 6; -const APB_SARADC_XPD_SAR_FORCE_V: u32 = 0x00000003; -const APB_SARADC_XPD_SAR_FORCE_S: u32 = 27; -const APB_SARADC_SAR_CLK_DIV_V: u32 = 0x000000FF; -const APB_SARADC_SAR_CLK_DIV_S: u32 = 7; -const APB_SARADC_SAR_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x18; -const APB_SARADC_SAR_PATT_TAB2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x1c; -const APB_SARADC_SAR_PATT_TAB1_V: u32 = 0x00FFFFFF; -const APB_SARADC_SAR_PATT_TAB1_S: u32 = 0; -const APB_SARADC_SAR_PATT_TAB2_V: u32 = 0x00FFFFFF; -const APB_SARADC_SAR_PATT_TAB2_S: u32 = 0; -const APB_SARADC_CTRL2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x4; -const APB_SARADC_TIMER_TARGET_V: u32 = 0x00000FFF; -const APB_SARADC_TIMER_TARGET_S: u32 = 12; -const APB_SARADC_REG_CLKM_DIV_NUM_V: u32 = 0x000000FF; -const APB_SARADC_REG_CLKM_DIV_NUM_S: u32 = 0; -const APB_SARADC_MEAS_NUM_LIMIT: u32 = 1 << 0; -const APB_SARADC_DMA_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x50; -const APB_SARADC_APB_ADC_TRANS_M: u32 = 0x00000001 << 31; -const APB_SARADC_TIMER_EN: u32 = 1 << 24; -const APB_SARADC_FSM_WAIT_REG: u32 = DR_REG_APB_SARADC_BASE + 0xc; -const APB_SARADC_RSTB_WAIT_V: u32 = 0x000000FF; -const APB_SARADC_RSTB_WAIT_S: u32 = 8; -const APB_SARADC_XPD_WAIT_V: u32 = 0x000000FF; -const APB_SARADC_XPD_WAIT_S: u32 = 0; -const APB_SARADC_STANDBY_WAIT_V: u32 = 0x000000FF; -const APB_SARADC_STANDBY_WAIT_S: u32 = 16; -const SYSTEM_APB_SARADC_RST_M: u32 = 0x00000001 << 28; -const SYSTEM_APB_SARADC_CLK_EN_M: u32 = 0x00000001 << 28; - use crate::regi2c_write_mask; pub(crate) fn ensure_randomness() { - // RNG module is always clock enabled - reg_set_field( - RTC_CNTL_SENSOR_CTRL_REG, - RTC_CNTL_FORCE_XPD_SAR_V, - RTC_CNTL_FORCE_XPD_SAR_S, - 0x3, - ); - - set_peri_reg_mask(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M); - - // Bridging sar2 internal reference voltage - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); - - // Enable SAR ADC2 internal channel to read adc2 ref voltage for additional - // entropy - set_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN_M); - clear_peri_reg_mask(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST_M); - reg_set_field( - APB_SARADC_APB_ADC_CLKM_CONF_REG, - APB_SARADC_REG_CLK_SEL_V, - APB_SARADC_REG_CLK_SEL_S, - 0x2, - ); - set_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); - set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED_M); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_XPD_SAR_FORCE_V, - APB_SARADC_XPD_SAR_FORCE_S, - 0x3, - ); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SAR_CLK_DIV_V, - APB_SARADC_SAR_CLK_DIV_S, - 1, - ); - - reg_set_field( - APB_SARADC_FSM_WAIT_REG, - APB_SARADC_RSTB_WAIT_V, - APB_SARADC_RSTB_WAIT_S, - 8, - ); - - reg_set_field( - APB_SARADC_FSM_WAIT_REG, - APB_SARADC_XPD_WAIT_V, - APB_SARADC_XPD_WAIT_S, - 5, - ); - - reg_set_field( - APB_SARADC_FSM_WAIT_REG, - APB_SARADC_STANDBY_WAIT_V, - APB_SARADC_STANDBY_WAIT_S, - 100, - ); - - set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); - clear_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SAR_PATT_LEN_V, - APB_SARADC_SAR_PATT_LEN_S, - 0, - ); - - reg_set_field( - APB_SARADC_SAR_PATT_TAB1_REG, - APB_SARADC_SAR_PATT_TAB1_V, - APB_SARADC_SAR_PATT_TAB1_S, - 0x9cffff, - ); - reg_set_field( - APB_SARADC_SAR_PATT_TAB2_REG, - APB_SARADC_SAR_PATT_TAB2_V, - APB_SARADC_SAR_PATT_TAB2_S, - 0x9cffff, - ); - - reg_set_field( - APB_SARADC_CTRL2_REG, - APB_SARADC_TIMER_TARGET_V, - APB_SARADC_TIMER_TARGET_S, - 100, - ); - reg_set_field( - APB_SARADC_APB_ADC_CLKM_CONF_REG, - APB_SARADC_REG_CLKM_DIV_NUM_V, - APB_SARADC_REG_CLKM_DIV_NUM_S, - 15, - ); - clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT); - set_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); - set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); -} - -pub(crate) fn revert_trng() { - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); - clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); - clear_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); - reg_set_field( - APB_SARADC_SAR_PATT_TAB1_REG, - APB_SARADC_SAR_PATT_TAB1_V, - APB_SARADC_SAR_PATT_TAB1_S, - 0xffffff, - ); - reg_set_field( - APB_SARADC_SAR_PATT_TAB2_REG, - APB_SARADC_SAR_PATT_TAB2_V, - APB_SARADC_SAR_PATT_TAB2_S, - 0xffffff, - ); - clear_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_XPD_SAR_FORCE_V, - APB_SARADC_XPD_SAR_FORCE_S, - 0, - ); - reg_set_field( - RTC_CNTL_SENSOR_CTRL_REG, - RTC_CNTL_FORCE_XPD_SAR_V, - RTC_CNTL_FORCE_XPD_SAR_S, - 0, - ); -} + let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; + let system = unsafe { &*crate::peripherals::SYSTEM::ptr() }; + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; -fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { unsafe { - (reg as *mut u32).write_volatile( - ((reg as *mut u32).read_volatile() & !(field_v << field_s)) - | ((value & field_v) << field_s), - ) - } -} + // RNG module is always clock enabled + rtc_cntl + .cntl_sensor_ctrl() + .modify(|_, w| w.force_xpd_sar().bits(3)); -fn set_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + rtc_cntl.ana_conf().modify(|_, w| w.sar_i2c_pu().set_bit()); + + // Bridging sar2 internal reference voltage + // Cannot replace with PAC-based functions + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); + + // Enable SAR ADC2 internal channel to read adc2 ref voltage for additional + // entropy + system + .perip_clk_en0() + .modify(|_, w| w.apb_saradc_clk_en().set_bit()); + + system + .perip_rst_en0() + .modify(|_, w| w.apb_saradc_rst().clear_bit()); + + apb_saradc.clkm_conf().modify(|_, w| w.clk_sel().bits(2)); + + apb_saradc.clkm_conf().modify(|_, w| w.clk_en().set_bit()); + + apb_saradc.ctrl().modify(|_, w| w.sar_clk_gated().set_bit()); + + apb_saradc.ctrl().modify(|_, w| w.xpd_sar_force().bits(3)); + + apb_saradc.ctrl().modify(|_, w| w.sar_clk_div().bits(1)); + + apb_saradc.fsm_wait().modify(|_, w| w.rstb_wait().bits(8)); + + apb_saradc.fsm_wait().modify(|_, w| w.xpd_wait().bits(5)); + + apb_saradc + .fsm_wait() + .modify(|_, w| w.standby_wait().bits(100)); + + apb_saradc + .ctrl() + .modify(|_, w| w.sar_patt_p_clear().set_bit()); + + apb_saradc + .ctrl() + .modify(|_, w| w.sar_patt_p_clear().clear_bit()); + + apb_saradc.ctrl().modify(|_, w| w.sar_patt_len().bits(0)); + + apb_saradc + .sar_patt_tab1() + .modify(|_, w| w.sar_patt_tab1().bits(0x9cffff)); + + apb_saradc + .sar_patt_tab2() + .modify(|_, w| w.sar_patt_tab2().bits(0x9cffff)); + + apb_saradc.ctrl2().modify(|_, w| w.timer_target().bits(100)); + + apb_saradc + .clkm_conf() + .modify(|_, w| w.clkm_div_num().bits(15)); + + apb_saradc + .ctrl2() + .modify(|_, w| w.meas_num_limit().clear_bit()); + + apb_saradc.dma_conf().modify(|_, w| w.adc_trans().set_bit()); + + apb_saradc.ctrl2().modify(|_, w| w.timer_en().set_bit()); } } -fn clear_peri_reg_mask(reg: u32, mask: u32) { +pub(crate) fn revert_trng() { + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; + let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; + unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); + + apb_saradc.ctrl2().modify(|_, w| w.timer_en().clear_bit()); + + apb_saradc + .dma_conf() + .modify(|_, w| w.adc_trans().clear_bit()); + + apb_saradc + .sar_patt_tab1() + .modify(|_, w| w.sar_patt_tab1().bits(0xffffff)); + + apb_saradc + .sar_patt_tab2() + .modify(|_, w| w.sar_patt_tab2().bits(0xffffff)); + + apb_saradc.clkm_conf().modify(|_, w| w.clk_en().clear_bit()); + + apb_saradc.ctrl().modify(|_, w| w.xpd_sar_force().bits(0)); + + rtc_cntl + .cntl_sensor_ctrl() + .modify(|_, w| w.force_xpd_sar().bits(0)); } } diff --git a/esp-hal/src/soc/esp32c3/trng.rs b/esp-hal/src/soc/esp32c3/trng.rs index 27afd6409b6..b78ed8d49a4 100644 --- a/esp-hal/src/soc/esp32c3/trng.rs +++ b/esp-hal/src/soc/esp32c3/trng.rs @@ -1,10 +1,3 @@ -const DR_REG_RTCCNTL_BASE: u32 = 0x60008000; -const RTC_CNTL_SENSOR_CTRL_REG: u32 = DR_REG_RTCCNTL_BASE + 0x011C; -const RTC_CNTL_FORCE_XPD_SAR_V: u32 = 0x3; -const RTC_CNTL_FORCE_XPD_SAR_S: u32 = 30; -const RTC_CNTL_ANA_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x0034; -const RTC_CNTL_SAR_I2C_PU_M: u32 = 1 << 22; - const I2C_SAR_ADC: u8 = 0x69; const I2C_SAR_ADC_HOSTID: u8 = 0; const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7; @@ -20,206 +13,120 @@ const ADC_SARADC_ENT_TSENS_ADDR: u8 = 0x07; const ADC_SARADC_ENT_TSENS_ADDR_MSB: u8 = 2; const ADC_SARADC_ENT_TSENS_ADDR_LSB: u8 = 2; -const DR_REG_SYSTEM_BASE: u32 = 0x600c0000; -const SYSTEM_PERIP_CLK_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x010; -const SYSTEM_PERIP_RST_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x018; -const APB_SARADC_CLK_EN_M: u32 = 0x00000001 << 20; -const DR_REG_APB_SARADC_BASE: u32 = 0x60040000; -const APB_SARADC_APB_ADC_CLKM_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x054; -const APB_SARADC_CLK_SEL_V: u32 = 0x00000003; -const APB_SARADC_CLK_SEL_S: u32 = 21; -const APB_SARADC_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE; -const APB_SARADC_SAR_PATT_P_CLEAR_M: u32 = 1 << 23; -const APB_SARADC_SAR_PATT_LEN_V: u32 = 7; -const APB_SARADC_SAR_PATT_LEN_S: u32 = 15; -const APB_SARADC_SAR_CLK_GATED_M: u32 = 1 << 6; -const APB_SARADC_XPD_SAR_FORCE_V: u32 = 0x3; -const APB_SARADC_XPD_SAR_FORCE_S: u32 = 27; -const APB_SARADC_SAR_CLK_DIV_V: u32 = 0xFF; -const APB_SARADC_SAR_CLK_DIV_S: u32 = 7; -const APB_SARADC_SAR_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x018; -const APB_SARADC_SAR_PATT_TAB2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x01c; -const APB_SARADC_SAR_PATT_TAB1_V: u32 = 0xFFFFFF; -const APB_SARADC_SAR_PATT_TAB1_S: u32 = 0; -const APB_SARADC_SAR_PATT_TAB2_V: u32 = 0xFFFFFF; -const APB_SARADC_SAR_PATT_TAB2_S: u32 = 0; -const APB_SARADC_CTRL2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x004; -const APB_SARADC_TIMER_TARGET_V: u32 = 0xFFF; -const APB_SARADC_TIMER_TARGET_S: u32 = 12; -const APB_SARADC_CLKM_DIV_NUM_V: u32 = 0xFF; -const APB_SARADC_CLKM_DIV_NUM_S: u32 = 0; -const APB_SARADC_MEAS_NUM_LIMIT: u32 = 1 << 0; -const APB_SARADC_DMA_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x050; -const APB_SARADC_APB_ADC_TRANS_M: u32 = 1 << 31; -const APB_SARADC_TIMER_EN: u32 = 1 << 24; -const APB_SARADC_FSM_WAIT_REG: u32 = DR_REG_APB_SARADC_BASE + 0x00c; -const APB_SARADC_RSTB_WAIT_V: u32 = 0xFF; -const APB_SARADC_RSTB_WAIT_S: u32 = 8; -const APB_SARADC_XPD_WAIT_V: u32 = 0xFF; -const APB_SARADC_XPD_WAIT_S: u32 = 0; -const APB_SARADC_STANDBY_WAIT_V: u32 = 0xFF; -const APB_SARADC_STANDBY_WAIT_S: u32 = 16; -const SYSTEM_APB_SARADC_RST_M: u32 = 1 << 28; -const SYSTEM_APB_SARADC_CLK_EN_M: u32 = 1 << 28; - use crate::regi2c_write_mask; pub(crate) fn ensure_randomness() { - // RNG module is always clock enabled - reg_set_field( - RTC_CNTL_SENSOR_CTRL_REG, - RTC_CNTL_FORCE_XPD_SAR_V, - RTC_CNTL_FORCE_XPD_SAR_S, - 0x3, - ); - - set_peri_reg_mask(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_PU_M); - - // Bridging sar2 internal reference voltage - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); - - // Enable SAR ADC2 internal channel to read adc2 ref voltage for additional - // entropy - set_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN_M); - clear_peri_reg_mask(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST_M); - reg_set_field( - APB_SARADC_APB_ADC_CLKM_CONF_REG, - APB_SARADC_CLK_SEL_V, - APB_SARADC_CLK_SEL_S, - 0x2, - ); - set_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); - set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED_M); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_XPD_SAR_FORCE_V, - APB_SARADC_XPD_SAR_FORCE_S, - 0x3, - ); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SAR_CLK_DIV_V, - APB_SARADC_SAR_CLK_DIV_S, - 1, - ); - - reg_set_field( - APB_SARADC_FSM_WAIT_REG, - APB_SARADC_RSTB_WAIT_V, - APB_SARADC_RSTB_WAIT_S, - 8, - ); - - reg_set_field( - APB_SARADC_FSM_WAIT_REG, - APB_SARADC_XPD_WAIT_V, - APB_SARADC_XPD_WAIT_S, - 5, - ); - - reg_set_field( - APB_SARADC_FSM_WAIT_REG, - APB_SARADC_STANDBY_WAIT_V, - APB_SARADC_STANDBY_WAIT_S, - 100, - ); - - set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); - clear_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_PATT_P_CLEAR_M); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SAR_PATT_LEN_V, - APB_SARADC_SAR_PATT_LEN_S, - 0, - ); - - reg_set_field( - APB_SARADC_SAR_PATT_TAB1_REG, - APB_SARADC_SAR_PATT_TAB1_V, - APB_SARADC_SAR_PATT_TAB1_S, - 0x9cffff, - ); - reg_set_field( - APB_SARADC_SAR_PATT_TAB2_REG, - APB_SARADC_SAR_PATT_TAB2_V, - APB_SARADC_SAR_PATT_TAB2_S, - 0x9cffff, - ); - - reg_set_field( - APB_SARADC_CTRL2_REG, - APB_SARADC_TIMER_TARGET_V, - APB_SARADC_TIMER_TARGET_S, - 100, - ); - reg_set_field( - APB_SARADC_APB_ADC_CLKM_CONF_REG, - APB_SARADC_CLKM_DIV_NUM_V, - APB_SARADC_CLKM_DIV_NUM_S, - 15, - ); - clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT); - set_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); - set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); -} - -pub(crate) fn revert_trng() { - // Restore internal I2C bus state - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); - - // Restore SARADC to default mode - clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); - clear_peri_reg_mask(APB_SARADC_DMA_CONF_REG, APB_SARADC_APB_ADC_TRANS_M); - reg_set_field( - APB_SARADC_SAR_PATT_TAB1_REG, - APB_SARADC_SAR_PATT_TAB1_V, - APB_SARADC_SAR_PATT_TAB1_S, - 0xffffff, - ); - reg_set_field( - APB_SARADC_SAR_PATT_TAB2_REG, - APB_SARADC_SAR_PATT_TAB2_V, - APB_SARADC_SAR_PATT_TAB2_S, - 0xffffff, - ); - clear_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN_M); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_XPD_SAR_FORCE_V, - APB_SARADC_XPD_SAR_FORCE_S, - 0, - ); - reg_set_field( - RTC_CNTL_SENSOR_CTRL_REG, - RTC_CNTL_FORCE_XPD_SAR_V, - RTC_CNTL_FORCE_XPD_SAR_S, - 0, - ); -} + let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; + let system = unsafe { &*crate::peripherals::SYSTEM::ptr() }; + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; -fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { unsafe { - (reg as *mut u32).write_volatile( - ((reg as *mut u32).read_volatile() & !(field_v << field_s)) - | ((value & field_v) << field_s), - ) - } -} + // RNG module is always clock enabled + rtc_cntl + .sensor_ctrl() + .modify(|_, w| w.force_xpd_sar().bits(3)); -fn set_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + rtc_cntl.ana_conf().modify(|_, w| w.sar_i2c_pu().set_bit()); + + // Bridging sar2 internal reference voltage + // Cannot replace with PAC-based functions + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); + + // Enable SAR ADC2 internal channel to read adc2 ref voltage for additional + // entropy + system + .perip_clk_en0() + .modify(|_, w| w.apb_saradc_clk_en().set_bit()); + + system + .perip_rst_en0() + .modify(|_, w| w.apb_saradc_rst().clear_bit()); + + apb_saradc.clkm_conf().modify(|_, w| w.clk_sel().bits(2)); + + apb_saradc.clkm_conf().modify(|_, w| w.clk_en().set_bit()); + + apb_saradc.ctrl().modify(|_, w| w.sar_clk_gated().set_bit()); + + apb_saradc.ctrl().modify(|_, w| w.xpd_sar_force().bits(3)); + + apb_saradc.ctrl().modify(|_, w| w.sar_clk_div().bits(1)); + + apb_saradc.fsm_wait().modify(|_, w| w.rstb_wait().bits(8)); + + apb_saradc.fsm_wait().modify(|_, w| w.xpd_wait().bits(5)); + + apb_saradc + .fsm_wait() + .modify(|_, w| w.standby_wait().bits(100)); + + apb_saradc + .ctrl() + .modify(|_, w| w.sar_patt_p_clear().set_bit()); + + apb_saradc + .ctrl() + .modify(|_, w| w.sar_patt_p_clear().clear_bit()); + + apb_saradc.ctrl().modify(|_, w| w.sar_patt_len().bits(0)); + + apb_saradc + .sar_patt_tab1() + .modify(|_, w| w.sar_patt_tab1().bits(0x9cffff)); + + apb_saradc + .sar_patt_tab2() + .modify(|_, w| w.sar_patt_tab2().bits(0x9cffff)); + + apb_saradc.ctrl2().modify(|_, w| w.timer_target().bits(100)); + + apb_saradc + .clkm_conf() + .modify(|_, w| w.clkm_div_num().bits(15)); + + apb_saradc + .ctrl2() + .modify(|_, w| w.meas_num_limit().clear_bit()); + + apb_saradc.dma_conf().modify(|_, w| w.adc_trans().set_bit()); + + apb_saradc.ctrl2().modify(|_, w| w.timer_en().set_bit()); } } -fn clear_peri_reg_mask(reg: u32, mask: u32) { +pub(crate) fn revert_trng() { + let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; + unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC2_ENCAL_REF_ADDR, 0); + + apb_saradc.ctrl2().modify(|_, w| w.timer_en().clear_bit()); + + apb_saradc + .dma_conf() + .modify(|_, w| w.adc_trans().clear_bit()); + + apb_saradc + .sar_patt_tab1() + .modify(|_, w| w.sar_patt_tab1().bits(0xffffff)); + + apb_saradc + .sar_patt_tab2() + .modify(|_, w| w.sar_patt_tab2().bits(0xffffff)); + + apb_saradc.clkm_conf().modify(|_, w| w.clk_en().clear_bit()); + + apb_saradc.ctrl().modify(|_, w| w.xpd_sar_force().bits(0)); + + rtc_cntl + .sensor_ctrl() + .modify(|_, w| w.force_xpd_sar().bits(0)); } } diff --git a/esp-hal/src/soc/esp32c6/trng.rs b/esp-hal/src/soc/esp32c6/trng.rs index 803ec7fcd85..53747e80e5c 100644 --- a/esp-hal/src/soc/esp32c6/trng.rs +++ b/esp-hal/src/soc/esp32c6/trng.rs @@ -1,25 +1,10 @@ -const PCR_SARADC_CONF_REG: u32 = 0x60096000 + 0x80; -const PCR_SARADC_RST_EN: u32 = 1 << 1; -const PCR_SARADC_REG_CLK_EN: u32 = 1 << 2; -const PCR_SARADC_CLKM_CONF_REG: u32 = 0x60096000 + 0x84; -const PCR_SARADC_CLKM_EN: u32 = 1 << 22; -const PMU_RF_PWC_REG: u32 = 0x600B0000 + 0x154; const I2C_SAR_ADC: u8 = 0x69; const I2C_SAR_ADC_HOSTID: u8 = 0; + const SAR2_CHANNEL: u32 = 9; const SAR2_ATTEN: u32 = 1; const SAR1_ATTEN: u32 = 1; const PATTERN_BIT_WIDTH: u32 = 6; -const APB_SARADC_SAR_PATT_TAB1_REG: u32 = 0x60040000 + 0x18; -const APB_SARADC_CTRL_REG: u32 = 0x60040000; -const APB_SARADC_CTRL2_REG: u32 = 0x60040000 + 0x4; - -const DR_REG_MODEM_LPCON_BASE: u32 = 0x600AF000; -const MODEM_LPCON_CLK_CONF_REG: u32 = DR_REG_MODEM_LPCON_BASE + 0x18; -const MODEM_LPCON_CLK_I2C_MST_EN: u32 = 1 << 2; -const DR_REG_LP_I2C_ANA_MST_BASE: u32 = 0x600B2400; -const LP_I2C_ANA_MST_DATE_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x3fc; -const LP_I2C_ANA_MST_I2C_MAT_CLK_EN: u32 = 1 << 28; const REGI2C_BBPLL: u8 = 0x66; const REGI2C_BIAS: u8 = 0x6a; @@ -27,7 +12,6 @@ const REGI2C_DIG_REG: u8 = 0x6d; const REGI2C_ULP_CAL: u8 = 0x61; const REGI2C_SAR_I2C: u8 = 0x69; -const LP_I2C_ANA_MST_DEVICE_EN_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x14; const REGI2C_BBPLL_DEVICE_EN: u32 = 1 << 5; const REGI2C_BIAS_DEVICE_EN: u32 = 1 << 4; const REGI2C_DIG_REG_DEVICE_EN: u32 = 1 << 8; @@ -42,22 +26,6 @@ const REGI2C_RTC_WR_CNTL_S: u8 = 24; const REGI2C_RTC_DATA_V: u8 = 0xFF; const REGI2C_RTC_DATA_S: u8 = 16; -const LP_I2C_ANA_MST_I2C0_CTRL_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE; -const LP_I2C_ANA_MST_I2C0_BUSY: u32 = 1 << 25; - -const LP_I2C_ANA_MST_I2C0_DATA_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x8; -const LP_I2C_ANA_MST_I2C0_RDATA_V: u32 = 0x000000FF; -const LP_I2C_ANA_MST_I2C0_RDATA_S: u32 = 0; - -const PCR_SARADC_CLKM_SEL_V: u32 = 0x00000003; -const PCR_SARADC_CLKM_SEL_S: u32 = 20; - -const PCR_SARADC_CLKM_DIV_NUM_V: u32 = 0x000000FF; -const PCR_SARADC_CLKM_DIV_NUM_S: u32 = 12; - -const PMU_PERIF_I2C_RSTB: u32 = 1 << 26; -const PMU_XPD_PERIF_I2C: u32 = 1 << 27; - const ADC_SAR2_INITIAL_CODE_HIGH_ADDR: u8 = 0x4; const ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB: u8 = 0x3; const ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB: u8 = 0x0; @@ -90,351 +58,385 @@ const ADC_SARADC2_ENCAL_REF_ADDR: u8 = 0x7; const ADC_SARADC2_ENCAL_REF_ADDR_MSB: u8 = 6; const ADC_SARADC2_ENCAL_REF_ADDR_LSB: u8 = 6; -const APB_SARADC_SARADC_SAR_PATT_LEN_V: u32 = 0x00000007; -const APB_SARADC_SARADC_SAR_PATT_LEN_S: u32 = 15; -const APB_SARADC_SARADC_SAR_CLK_DIV_V: u32 = 0x000000FF; -const APB_SARADC_SARADC_SAR_CLK_DIV_S: u32 = 7; -const APB_SARADC_SARADC_TIMER_TARGET_V: u32 = 0x00000FFF; -const APB_SARADC_SARADC_TIMER_TARGET_S: u32 = 12; -const APB_SARADC_SARADC_TIMER_EN: u32 = 1 << 24; - pub(crate) fn ensure_randomness() { - // Pull SAR ADC out of reset - reg_set_bit(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); - reg_clr_bit(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); - - // Enable SAR ADC APB clock - reg_set_bit(PCR_SARADC_CONF_REG, PCR_SARADC_REG_CLK_EN); - - // Enable ADC_CTRL_CLK (SAR ADC function clock) - reg_set_bit(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_EN); - - // Select XTAL clock (40 MHz) source for ADC_CTRL_CLK - reg_set_field( - PCR_SARADC_CLKM_CONF_REG, - PCR_SARADC_CLKM_SEL_V, - PCR_SARADC_CLKM_SEL_S, - 0, - ); - - // Set the clock divider for ADC_CTRL_CLK to default value (in case it has been - // changed) - reg_set_field( - PCR_SARADC_CLKM_CONF_REG, - PCR_SARADC_CLKM_DIV_NUM_V, - PCR_SARADC_CLKM_DIV_NUM_S, - 0, - ); - - // some ADC sensor registers are in power group PERIF_I2C and need to be enabled - // via PMU - set_peri_reg_mask(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); - set_peri_reg_mask(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); - - // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal - // voltage as sampling source - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_DTEST_RTC_ADDR, - ADC_SARADC_DTEST_RTC_ADDR_MSB, - ADC_SARADC_DTEST_RTC_ADDR_LSB, - 2, - ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_ENT_RTC_ADDR, - ADC_SARADC_ENT_RTC_ADDR_MSB, - ADC_SARADC_ENT_RTC_ADDR_LSB, - 1, - ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC1_ENCAL_REF_ADDR, - ADC_SARADC1_ENCAL_REF_ADDR_MSB, - ADC_SARADC1_ENCAL_REF_ADDR_LSB, - 1, - ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC1_ENCAL_REF_ADDR, - ADC_SARADC1_ENCAL_REF_ADDR_MSB, - ADC_SARADC1_ENCAL_REF_ADDR_LSB, - 1, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR2_INITIAL_CODE_HIGH_ADDR, - ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB, - ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB, - 0x60, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR2_INITIAL_CODE_LOW_ADDR, - ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB, - ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB, - 0x66, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR1_INITIAL_CODE_HIGH_ADDR, - ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB, - ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB, - 0x08, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR1_INITIAL_CODE_LOW_ADDR, - ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB, - ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB, - 0x66, - ); - - // create patterns and set them in pattern table - let pattern_one: u32 = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation - let pattern_two: u32 = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here - let pattern_table: u32 = - (pattern_two << (3 * PATTERN_BIT_WIDTH)) | (pattern_one << (2 * PATTERN_BIT_WIDTH)); - - reg_write(APB_SARADC_SAR_PATT_TAB1_REG, pattern_table); - - // set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0) - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SARADC_SAR_PATT_LEN_V, - APB_SARADC_SARADC_SAR_PATT_LEN_S, - 1, - ); - - // Same as in C3 - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SARADC_SAR_CLK_DIV_V, - APB_SARADC_SARADC_SAR_CLK_DIV_S, - 15, - ); - - // set timer expiry (timer is ADC_CTRL_CLK) - reg_set_field( - APB_SARADC_CTRL2_REG, - APB_SARADC_SARADC_TIMER_TARGET_V, - APB_SARADC_SARADC_TIMER_TARGET_S, - 200, - ); - - // enable timer - reg_set_bit(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); -} - -pub(crate) fn revert_trng() { - reg_clr_bit(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); - reg_write(APB_SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR2_INITIAL_CODE_HIGH_ADDR, - ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB, - ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB, - 0x60, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR2_INITIAL_CODE_LOW_ADDR, - ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB, - ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB, - 0, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR1_INITIAL_CODE_HIGH_ADDR, - ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB, - ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB, - 0x60, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR1_INITIAL_CODE_LOW_ADDR, - ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB, - ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB, - 0, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_DTEST_RTC_ADDR, - ADC_SARADC_DTEST_RTC_ADDR_MSB, - ADC_SARADC_DTEST_RTC_ADDR_LSB, - 0, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_ENT_RTC_ADDR, - ADC_SARADC_ENT_RTC_ADDR_MSB, - ADC_SARADC_ENT_RTC_ADDR_LSB, - 0, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC1_ENCAL_REF_ADDR, - ADC_SARADC1_ENCAL_REF_ADDR_MSB, - ADC_SARADC1_ENCAL_REF_ADDR_LSB, - 0, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC2_ENCAL_REF_ADDR, - ADC_SARADC2_ENCAL_REF_ADDR_MSB, - ADC_SARADC2_ENCAL_REF_ADDR_LSB, - 0, - ); - - clear_peri_reg_mask(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); - reg_write(PCR_SARADC_CLKM_CONF_REG, 0x00404000); - reg_write(PCR_SARADC_CONF_REG, 0x5); -} + let pcr = unsafe { &*crate::peripherals::PCR::ptr() }; + let pmu = unsafe { &*crate::peripherals::PMU::ptr() }; + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; -fn reg_set_bit(reg: u32, bit: u32) { unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); + // Pull SAR ADC out of reset + pcr.saradc_conf().modify(|_, w| w.saradc_rst_en().set_bit()); + + pcr.saradc_conf() + .modify(|_, w| w.saradc_rst_en().clear_bit()); + + // Enable SAR ADC APB clock + pcr.saradc_conf() + .modify(|_, w| w.saradc_reg_clk_en().set_bit()); + + // Enable ADC_CTRL_CLK (SAR ADC function clock) + pcr.saradc_clkm_conf() + .modify(|_, w| w.saradc_clkm_en().set_bit()); + + // Select XTAL clock (40 MHz) source for ADC_CTRL_CLK + pcr.saradc_clkm_conf() + .modify(|_, w| w.saradc_clkm_sel().bits(0)); + + // Set the clock divider for ADC_CTRL_CLK to default value (in case it has been + // changed) + pcr.saradc_clkm_conf() + .modify(|_, w| w.saradc_clkm_div_num().bits(0)); + + // some ADC sensor registers are in power group PERIF_I2C and need to be enabled + // via PMU + pmu.rf_pwc().modify(|_, w| w.perif_i2c_rstb().set_bit()); + + pmu.rf_pwc().modify(|_, w| w.xpd_perif_i2c().set_bit()); + + // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal + // voltage as sampling source + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_DTEST_RTC_ADDR, + ADC_SARADC_DTEST_RTC_ADDR_MSB, + ADC_SARADC_DTEST_RTC_ADDR_LSB, + 2, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_RTC_ADDR, + ADC_SARADC_ENT_RTC_ADDR_MSB, + ADC_SARADC_ENT_RTC_ADDR_LSB, + 1, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC1_ENCAL_REF_ADDR, + ADC_SARADC1_ENCAL_REF_ADDR_MSB, + ADC_SARADC1_ENCAL_REF_ADDR_LSB, + 1, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC1_ENCAL_REF_ADDR, + ADC_SARADC1_ENCAL_REF_ADDR_MSB, + ADC_SARADC1_ENCAL_REF_ADDR_LSB, + 1, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB, + 0x60, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_INITIAL_CODE_LOW_ADDR, + ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB, + ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB, + 0x66, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB, + 0x08, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_INITIAL_CODE_LOW_ADDR, + ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB, + ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB, + 0x66, + ); + + // create patterns and set them in pattern table + let pattern_one: u32 = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation + let pattern_two: u32 = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here + let pattern_table: u32 = + (pattern_two << (3 * PATTERN_BIT_WIDTH)) | (pattern_one << (2 * PATTERN_BIT_WIDTH)); + + apb_saradc + .sar_patt_tab1() + .modify(|_, w| w.bits(pattern_table)); + + // set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0) + apb_saradc.ctrl().modify(|_, w| w.sar_patt_len().bits(1)); + + // Same as in C3 + apb_saradc.ctrl().modify(|_, w| w.sar_clk_div().bits(15)); + + // set timer expiry (timer is ADC_CTRL_CLK) + apb_saradc.ctrl2().modify(|_, w| w.timer_target().bits(200)); + + // enable timer + apb_saradc.ctrl2().modify(|_, w| w.timer_en().set_bit()); } } -fn reg_clr_bit(reg: u32, bit: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !bit); - } -} +pub(crate) fn revert_trng() { + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; + let pmu = unsafe { &*crate::peripherals::PMU::ptr() }; + let pcr = unsafe { &*crate::peripherals::PCR::ptr() }; -fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { unsafe { - (reg as *mut u32).write_volatile( - ((reg as *mut u32).read_volatile() & !(field_v << field_s)) - | ((value & field_v) << field_s), - ) + apb_saradc.ctrl2().modify(|_, w| w.timer_en().clear_bit()); + + apb_saradc.sar_patt_tab1().modify(|_, w| w.bits(0xFFFFFF)); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB, + ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB, + 0x60, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_INITIAL_CODE_LOW_ADDR, + ADC_SAR2_INITIAL_CODE_LOW_ADDR_MSB, + ADC_SAR2_INITIAL_CODE_LOW_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR_MSB, + ADC_SAR1_INITIAL_CODE_HIGH_ADDR_LSB, + 0x60, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_INITIAL_CODE_LOW_ADDR, + ADC_SAR1_INITIAL_CODE_LOW_ADDR_MSB, + ADC_SAR1_INITIAL_CODE_LOW_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_DTEST_RTC_ADDR, + ADC_SARADC_DTEST_RTC_ADDR_MSB, + ADC_SARADC_DTEST_RTC_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_RTC_ADDR, + ADC_SARADC_ENT_RTC_ADDR_MSB, + ADC_SARADC_ENT_RTC_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC1_ENCAL_REF_ADDR, + ADC_SARADC1_ENCAL_REF_ADDR_MSB, + ADC_SARADC1_ENCAL_REF_ADDR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC2_ENCAL_REF_ADDR, + ADC_SARADC2_ENCAL_REF_ADDR_MSB, + ADC_SARADC2_ENCAL_REF_ADDR_LSB, + 0, + ); + + pmu.rf_pwc().modify(|_, w| w.perif_i2c_rstb().clear_bit()); + + pcr.saradc_clkm_conf().modify(|_, w| w.bits(0x00404000)); + + pcr.saradc_conf().modify(|_, w| w.bits(0x5)); } } -fn set_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); - } -} -fn reg_write(reg: u32, v: u32) { - unsafe { - (reg as *mut u32).write_volatile(v); - } -} - -fn reg_get_bit(reg: u32, b: u32) -> u32 { - unsafe { (reg as *mut u32).read_volatile() & b } -} - -fn reg_get_field(reg: u32, s: u32, v: u32) -> u32 { - unsafe { ((reg as *mut u32).read_volatile() >> s) & v } -} - fn regi2c_enable_block(block: u8) { - reg_set_bit(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); - reg_set_bit(LP_I2C_ANA_MST_DATE_REG, LP_I2C_ANA_MST_I2C_MAT_CLK_EN); + let modem_lpcon = unsafe { &*crate::peripherals::MODEM_LPCON::ptr() }; + let lp_i2c_ana = unsafe { &*crate::peripherals::LP_I2C_ANA_MST::ptr() }; - // Before config I2C register, enable corresponding slave. - match block { - v if v == REGI2C_BBPLL => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); - } - v if v == REGI2C_BIAS => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); - } - v if v == REGI2C_DIG_REG => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); - } - v if v == REGI2C_ULP_CAL => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); - } - v if v == REGI2C_SAR_I2C => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); + unsafe { + modem_lpcon + .clk_conf() + .modify(|_, w| w.clk_i2c_mst_en().set_bit()); + + lp_i2c_ana + .date() + .modify(|_, w| w.lp_i2c_ana_mast_i2c_mat_clk_en().set_bit()); + + match block { + REGI2C_BBPLL => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_BBPLL_DEVICE_EN) + as u16, + ) + }); + } + REGI2C_BIAS => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_BIAS_DEVICE_EN) + as u16, + ) + }); + } + REGI2C_DIG_REG => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_DIG_REG_DEVICE_EN) + as u16, + ) + }); + } + REGI2C_ULP_CAL => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_ULP_CAL_DEVICE_EN) + as u16, + ) + }); + } + REGI2C_SAR_I2C => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_SAR_I2C_DEVICE_EN) + as u16, + ) + }); + } + _ => (), } - _ => (), } } fn regi2c_disable_block(block: u8) { - match block { - v if v == REGI2C_BBPLL => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); - } - v if v == REGI2C_BIAS => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); - } - v if v == REGI2C_DIG_REG => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); - } - v if v == REGI2C_ULP_CAL => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); - } - v if v == REGI2C_SAR_I2C => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); + let lp_i2c_ana = unsafe { &*crate::peripherals::LP_I2C_ANA_MST::ptr() }; + + unsafe { + match block { + REGI2C_BBPLL => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 & !REGI2C_BBPLL_DEVICE_EN) + as u16, + ) + }); + } + REGI2C_BIAS => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 & !REGI2C_BIAS_DEVICE_EN) + as u16, + ) + }); + } + REGI2C_DIG_REG => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 + & !REGI2C_DIG_REG_DEVICE_EN) as u16, + ) + }); + } + REGI2C_ULP_CAL => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 + & !REGI2C_ULP_CAL_DEVICE_EN) as u16, + ) + }); + } + REGI2C_SAR_I2C => { + lp_i2c_ana.device_en().modify(|r, w| { + w.lp_i2c_ana_mast_i2c_device_en().bits( + (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 + & !REGI2C_SAR_I2C_DEVICE_EN) as u16, + ) + }); + } + _ => (), } - _ => (), } } pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, lsb: u8, data: u8) { assert!(msb - lsb < 8); - regi2c_enable_block(block); - - // Read the i2c bus register - let mut temp: u32 = ((block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) - << REGI2C_RTC_SLAVE_ID_S as u32) - | (reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32; - reg_write(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); - while reg_get_bit(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY) != 0 {} - temp = reg_get_field( - LP_I2C_ANA_MST_I2C0_DATA_REG, - LP_I2C_ANA_MST_I2C0_RDATA_S, - LP_I2C_ANA_MST_I2C0_RDATA_V, - ); - // Write the i2c bus register - temp &= (!(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)); - temp |= (data as u32 & (!(0xFFFFFFFF << (msb as u32 - lsb as u32 + 1)))) << (lsb as u32); - temp = ((block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) << REGI2C_RTC_SLAVE_ID_S as u32) - | ((reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32) - | ((0x1 & REGI2C_RTC_WR_CNTL_V as u32) << REGI2C_RTC_WR_CNTL_S as u32) - | ((temp & REGI2C_RTC_DATA_V as u32) << REGI2C_RTC_DATA_S as u32); - reg_write(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); - while reg_get_bit(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY) != 0 {} - - regi2c_disable_block(block); -} + let lp_i2c_ana = unsafe { &*crate::peripherals::LP_I2C_ANA_MST::ptr() }; -fn clear_peri_reg_mask(reg: u32, mask: u32) { unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + regi2c_enable_block(block); + + // Read the i2c bus register + let mut temp: u32 = ((block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) + << REGI2C_RTC_SLAVE_ID_S as u32) + | (reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32; + + lp_i2c_ana + .i2c0_ctrl() + .modify(|_, w| w.lp_i2c_ana_mast_i2c0_ctrl().bits(temp)); + + while lp_i2c_ana + .i2c0_ctrl() + .read() + .lp_i2c_ana_mast_i2c0_busy() + .bit() + != false + {} + + temp = lp_i2c_ana + .i2c0_data() + .read() + .lp_i2c_ana_mast_i2c0_rdata() + .bits() as u32; + + // Write the i2c bus register + temp &= (!(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)); + temp |= (data as u32 & (!(0xFFFFFFFF << (msb as u32 - lsb as u32 + 1)))) << (lsb as u32); + temp = ((block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) << REGI2C_RTC_SLAVE_ID_S as u32) + | ((reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32) + | ((0x1 & REGI2C_RTC_WR_CNTL_V as u32) << REGI2C_RTC_WR_CNTL_S as u32) + | ((temp & REGI2C_RTC_DATA_V as u32) << REGI2C_RTC_DATA_S as u32); + + lp_i2c_ana + .i2c0_ctrl() + .modify(|_, w| w.lp_i2c_ana_mast_i2c0_ctrl().bits(temp)); + + while lp_i2c_ana + .i2c0_ctrl() + .read() + .lp_i2c_ana_mast_i2c0_busy() + .bit() + != false + {} + + regi2c_disable_block(block); } } diff --git a/esp-hal/src/soc/esp32h2/trng.rs b/esp-hal/src/soc/esp32h2/trng.rs index 311d1cd8b8a..0b1e25e1188 100644 --- a/esp-hal/src/soc/esp32h2/trng.rs +++ b/esp-hal/src/soc/esp32h2/trng.rs @@ -1,14 +1,3 @@ -const PCR_SARADC_CONF_REG: u32 = 0x60096000 + 0x80; -const PCR_SARADC_RST_EN: u32 = 1 << 1; -const PCR_SARADC_REG_CLK_EN: u32 = 1 << 2; -const PCR_SARADC_CLKM_CONF_REG: u32 = 0x60096000 + 0x84; -const PCR_SARADC_CLKM_EN: u32 = 1 << 22; -const PCR_SARADC_CLKM_SEL_V: u32 = 0x00000003; -const PCR_SARADC_CLKM_SEL_S: u32 = 20; -const PCR_SARADC_CLKM_DIV_NUM_V: u32 = 0x000000FF; -const PCR_SARADC_CLKM_DIV_NUM_S: u32 = 12; -const PMU_RF_PWC_REG: u32 = 0x600B0000 + 0x154; -const PMU_XPD_PERIF_I2C: u32 = 1 << 27; const I2C_SAR_ADC: u8 = 0x69; const I2C_SAR_ADC_HOSTID: u8 = 0; @@ -40,37 +29,24 @@ const SAR2_CHANNEL: u32 = 9; const SAR2_ATTEN: u32 = 1; const SAR1_ATTEN: u32 = 1; const PATTERN_BIT_WIDTH: u32 = 6; -const APB_SARADC_SAR_PATT_TAB1_REG: u32 = 0x60040000 + 0x18; -const APB_SARADC_CTRL_REG: u32 = 0x60040000; -const APB_SARADC_CTRL2_REG: u32 = 0x60040000 + 0x4; - -const APB_SARADC_SARADC_SAR_PATT_LEN_V: u32 = 0x00000007; -const APB_SARADC_SARADC_SAR_PATT_LEN_S: u32 = 15; -const APB_SARADC_SARADC_SAR_CLK_DIV_V: u32 = 0x000000FF; -const APB_SARADC_SARADC_SAR_CLK_DIV_S: u32 = 7; -const APB_SARADC_SARADC_TIMER_TARGET_V: u32 = 0x00000FFF; -const APB_SARADC_SARADC_TIMER_TARGET_S: u32 = 12; -const APB_SARADC_SARADC_TIMER_EN: u32 = 1 << 24; - -const DR_REG_MODEM_LPCON_BASE: u32 = 0x600AF000; -const MODEM_LPCON_CLK_CONF_REG: u32 = DR_REG_MODEM_LPCON_BASE + 0x18; -const MODEM_LPCON_CLK_I2C_MST_EN: u32 = 1 << 2; -const DR_REG_LP_I2C_ANA_MST_BASE: u32 = 0x600B2400; -const LP_I2C_ANA_MST_DATE_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x3fc; -const LP_I2C_ANA_MST_I2C_MAT_CLK_EN: u32 = 1 << 28; const REGI2C_BBPLL: u8 = 0x66; const REGI2C_BIAS: u8 = 0x6a; -const REGI2C_DIG_REG: u8 = 0x6d; +const REGI2C_PMU: u8 = 0x6d; const REGI2C_ULP_CAL: u8 = 0x61; const REGI2C_SAR_I2C: u8 = 0x69; -const LP_I2C_ANA_MST_DEVICE_EN_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x14; -const REGI2C_BBPLL_DEVICE_EN: u32 = 1 << 5; -const REGI2C_BIAS_DEVICE_EN: u32 = 1 << 4; -const REGI2C_DIG_REG_DEVICE_EN: u32 = 1 << 8; -const REGI2C_ULP_CAL_DEVICE_EN: u32 = 1 << 6; -const REGI2C_SAR_I2C_DEVICE_EN: u32 = 1 << 7; +const I2C_MST_ANA_CONF1_M: u32 = 0x00FFFFFF; +const I2C_MST_I2C0_CTRL_REG: u32 = 0x600AD800; +const I2C_MST_ANA_CONF1_REG: u32 = I2C_MST_I2C0_CTRL_REG + 0x1c; + +const REGI2C_BBPLL_RD_MASK: u32 = !(1 << 7) & I2C_MST_ANA_CONF1_M; +const REGI2C_BIAS_RD_MASK: u32 = !(1 << 6) & I2C_MST_ANA_CONF1_M; +const REGI2C_DIG_REG_RD_MASK: u32 = !(1 << 10) & I2C_MST_ANA_CONF1_M; +const REGI2C_ULP_CAL_RD_MASK: u32 = !(1 << 8) & I2C_MST_ANA_CONF1_M; +const REGI2C_SAR_I2C_RD_MASK: u32 = !(1 << 9) & I2C_MST_ANA_CONF1_M; +const REGI2C_RTC_BUSY: u32 = 1 << 25; + const REGI2C_RTC_SLAVE_ID_V: u8 = 0xFF; const REGI2C_RTC_SLAVE_ID_S: u8 = 0; const REGI2C_RTC_ADDR_V: u8 = 0xFF; @@ -80,282 +56,231 @@ const REGI2C_RTC_WR_CNTL_S: u8 = 24; const REGI2C_RTC_DATA_V: u8 = 0xFF; const REGI2C_RTC_DATA_S: u8 = 16; -const LP_I2C_ANA_MST_I2C0_CTRL_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE; -const LP_I2C_ANA_MST_I2C0_BUSY: u32 = 1 << 25; - -const LP_I2C_ANA_MST_I2C0_DATA_REG: u32 = DR_REG_LP_I2C_ANA_MST_BASE + 0x8; -const LP_I2C_ANA_MST_I2C0_RDATA_V: u32 = 0x000000FF; -const LP_I2C_ANA_MST_I2C0_RDATA_S: u32 = 0; - pub(crate) fn ensure_randomness() { - // Pull SAR ADC out of reset - reg_set_bit(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); - reg_clr_bit(PCR_SARADC_CONF_REG, PCR_SARADC_RST_EN); - - // Enable SAR ADC APB clock - reg_set_bit(PCR_SARADC_CONF_REG, PCR_SARADC_REG_CLK_EN); - - // Enable ADC_CTRL_CLK (SAR ADC function clock) - reg_set_bit(PCR_SARADC_CLKM_CONF_REG, PCR_SARADC_CLKM_EN); - - // Select XTAL clock (40 MHz) source for ADC_CTRL_CLK - reg_set_field( - PCR_SARADC_CLKM_CONF_REG, - PCR_SARADC_CLKM_SEL_V, - PCR_SARADC_CLKM_SEL_S, - 0, - ); - - // Set the clock divider for ADC_CTRL_CLK to default value (in case it has been - // changed) - reg_set_field( - PCR_SARADC_CLKM_CONF_REG, - PCR_SARADC_CLKM_DIV_NUM_V, - PCR_SARADC_CLKM_DIV_NUM_S, - 0, - ); - - // some ADC sensor registers are in power group PERIF_I2C and need to be enabled - // via PMU - set_peri_reg_mask(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); - - // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal - // voltage as sampling source - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_DTEST, - I2C_SARADC_DTEST_MSB, - I2C_SARADC_DTEST_LSB, - 2, - ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_ENT_SAR, - I2C_SARADC_ENT_SAR_MSB, - I2C_SARADC_ENT_SAR_LSB, - 1, - ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_EN_TOUT_SAR1_BUS, - I2C_SARADC_EN_TOUT_SAR1_BUS_MSB, - I2C_SARADC_EN_TOUT_SAR1_BUS_LSB, - 1, - ); - - // SAR2 High ADDR - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_SAR2_INIT_CODE_MSB, - I2C_SARADC_SAR2_INIT_CODE_MSB_MSB, - I2C_SARADC_SAR2_INIT_CODE_MSB_LSB, - 0x08, - ); - // SAR2 Low ADDR - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_SAR2_INIT_CODE_LSB, - I2C_SARADC_SAR2_INIT_CODE_LSB_MSB, - I2C_SARADC_SAR2_INIT_CODE_LSB_LSB, - 0x66, - ); - // SAR1 High ADDR - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_SAR1_INIT_CODE_MSB, - I2C_SARADC_SAR1_INIT_CODE_MSB_MSB, - I2C_SARADC_SAR1_INIT_CODE_MSB_LSB, - 0x08, - ); - // SAR1 Low ADDR - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_SAR1_INIT_CODE_LSB, - I2C_SARADC_SAR1_INIT_CODE_LSB_MSB, - I2C_SARADC_SAR1_INIT_CODE_LSB_LSB, - 0x66, - ); - - // create patterns and set them in pattern table - let pattern_one: u32 = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation - let pattern_two: u32 = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here - let pattern_table: u32 = - (pattern_two << (3 * PATTERN_BIT_WIDTH)) | (pattern_one << (2 * PATTERN_BIT_WIDTH)); - reg_write(APB_SARADC_SAR_PATT_TAB1_REG, pattern_table); - - // set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0) - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SARADC_SAR_PATT_LEN_V, - APB_SARADC_SARADC_SAR_PATT_LEN_S, - 0, - ); - - // Same as in C3 - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SARADC_SAR_CLK_DIV_V, - APB_SARADC_SARADC_SAR_CLK_DIV_S, - 15, - ); - - // set timer expiry (timer is ADC_CTRL_CLK) - reg_set_field( - APB_SARADC_CTRL2_REG, - APB_SARADC_SARADC_TIMER_TARGET_V, - APB_SARADC_SARADC_TIMER_TARGET_S, - 200, - ); - - // enable timer - reg_set_bit(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); -} + let pcr = unsafe { &*crate::peripherals::PCR::ptr() }; + let pmu = unsafe { &*crate::peripherals::PMU::ptr() }; + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; -pub(crate) fn revert_trng() { - // Disable timer - reg_clr_bit(APB_SARADC_CTRL2_REG, APB_SARADC_SARADC_TIMER_EN); - - // Write reset value - reg_write(APB_SARADC_SAR_PATT_TAB1_REG, 0xFFFFFF); - - // Revert ADC I2C configuration and initial voltage source setting - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_SAR2_INIT_CODE_MSB, - I2C_SARADC_SAR2_INIT_CODE_MSB_MSB, - I2C_SARADC_SAR2_INIT_CODE_MSB_LSB, - 0x60, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_SAR2_INIT_CODE_LSB, - I2C_SARADC_SAR2_INIT_CODE_LSB_MSB, - I2C_SARADC_SAR2_INIT_CODE_LSB_LSB, - 0, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_SAR1_INIT_CODE_MSB, - I2C_SARADC_SAR1_INIT_CODE_MSB_MSB, - I2C_SARADC_SAR1_INIT_CODE_MSB_LSB, - 0x60, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_SAR1_INIT_CODE_LSB, - I2C_SARADC_SAR1_INIT_CODE_LSB_MSB, - I2C_SARADC_SAR1_INIT_CODE_LSB_LSB, - 0, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_DTEST, - I2C_SARADC_DTEST_MSB, - I2C_SARADC_DTEST_LSB, - 0, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_ENT_SAR, - I2C_SARADC_ENT_SAR_MSB, - I2C_SARADC_ENT_SAR_LSB, - 0, - ); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - I2C_SARADC_EN_TOUT_SAR1_BUS, - I2C_SARADC_EN_TOUT_SAR1_BUS_MSB, - I2C_SARADC_EN_TOUT_SAR1_BUS_LSB, - 0, - ); - - // disable ADC_CTRL_CLK (SAR ADC function clock) - reg_write(PCR_SARADC_CLKM_CONF_REG, 0x00404000); - - // Set PCR_SARADC_CONF_REG to initial state - reg_write(PCR_SARADC_CONF_REG, 0x5); -} - -fn reg_set_bit(reg: u32, bit: u32) { unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); + // Pull SAR ADC out of reset + pcr.saradc_conf().modify(|_, w| w.saradc_rst_en().set_bit()); + + pcr.saradc_conf() + .modify(|_, w| w.saradc_rst_en().clear_bit()); + + // Enable SAR ADC APB clock + pcr.saradc_conf() + .modify(|_, w| w.saradc_reg_clk_en().set_bit()); + + // Enable ADC_CTRL_CLK (SAR ADC function clock) + pcr.saradc_clkm_conf() + .modify(|_, w| w.saradc_clkm_en().set_bit()); + + // Select XTAL clock (40 MHz) source for ADC_CTRL_CLK + pcr.saradc_clkm_conf() + .modify(|_, w| w.saradc_clkm_sel().bits(0)); + + // Set the clock divider for ADC_CTRL_CLK to default value (in case it has been + // changed) + pcr.saradc_clkm_conf() + .modify(|_, w| w.saradc_clkm_div_num().bits(0)); + + // some ADC sensor registers are in power group PERIF_I2C and need to be enabled + // via PMU + pmu.rf_pwc().modify(|_, w| w.xpd_perif_i2c().set_bit()); + + // Config ADC circuit (Analog part) with I2C(HOST ID 0x69) and chose internal + // voltage as sampling source + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_DTEST, + I2C_SARADC_DTEST_MSB, + I2C_SARADC_DTEST_LSB, + 2, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_ENT_SAR, + I2C_SARADC_ENT_SAR_MSB, + I2C_SARADC_ENT_SAR_LSB, + 1, + ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_EN_TOUT_SAR1_BUS, + I2C_SARADC_EN_TOUT_SAR1_BUS_MSB, + I2C_SARADC_EN_TOUT_SAR1_BUS_LSB, + 1, + ); + + // SAR2 High ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR2_INIT_CODE_MSB, + I2C_SARADC_SAR2_INIT_CODE_MSB_MSB, + I2C_SARADC_SAR2_INIT_CODE_MSB_LSB, + 0x08, + ); + // SAR2 Low ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR2_INIT_CODE_LSB, + I2C_SARADC_SAR2_INIT_CODE_LSB_MSB, + I2C_SARADC_SAR2_INIT_CODE_LSB_LSB, + 0x66, + ); + // SAR1 High ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR1_INIT_CODE_MSB, + I2C_SARADC_SAR1_INIT_CODE_MSB_MSB, + I2C_SARADC_SAR1_INIT_CODE_MSB_LSB, + 0x08, + ); + // SAR1 Low ADDR + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR1_INIT_CODE_LSB, + I2C_SARADC_SAR1_INIT_CODE_LSB_MSB, + I2C_SARADC_SAR1_INIT_CODE_LSB_LSB, + 0x66, + ); + + // create patterns and set them in pattern table + let pattern_one: u32 = (SAR2_CHANNEL << 2) | SAR2_ATTEN; // we want channel 9 with max attenuation + let pattern_two: u32 = SAR1_ATTEN; // we want channel 0 with max attenuation, channel doesn't really matter here + let pattern_table: u32 = + (pattern_two << (3 * PATTERN_BIT_WIDTH)) | (pattern_one << (2 * PATTERN_BIT_WIDTH)); + + apb_saradc + .sar_patt_tab1() + .modify(|_, w| w.bits(pattern_table)); + + // set pattern length to 2 (APB_SARADC_SAR_PATT_LEN counts from 0) + apb_saradc.ctrl().modify(|_, w| w.sar_patt_len().bits(0)); + + // Same as in C3 + apb_saradc.ctrl().modify(|_, w| w.sar_clk_div().bits(15)); + + // set timer expiry (timer is ADC_CTRL_CLK) + apb_saradc.ctrl2().modify(|_, w| w.timer_target().bits(200)); + + // enable timer + apb_saradc.ctrl2().modify(|_, w| w.timer_en().set_bit()); } } -fn reg_clr_bit(reg: u32, bit: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !bit); - } -} - -fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { - unsafe { - (reg as *mut u32).write_volatile( - ((reg as *mut u32).read_volatile() & !(field_v << field_s)) - | ((value & field_v) << field_s), - ) - } -} +pub(crate) fn revert_trng() { + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; + let pcr = unsafe { &*crate::peripherals::PCR::ptr() }; -fn set_peri_reg_mask(reg: u32, mask: u32) { unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + apb_saradc.ctrl2().modify(|_, w| w.timer_en().clear_bit()); + + apb_saradc.sar_patt_tab1().modify(|_, w| w.bits(0xFFFFFF)); + + // Revert ADC I2C configuration and initial voltage source setting + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR2_INIT_CODE_MSB, + I2C_SARADC_SAR2_INIT_CODE_MSB_MSB, + I2C_SARADC_SAR2_INIT_CODE_MSB_LSB, + 0x60, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR2_INIT_CODE_LSB, + I2C_SARADC_SAR2_INIT_CODE_LSB_MSB, + I2C_SARADC_SAR2_INIT_CODE_LSB_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR1_INIT_CODE_MSB, + I2C_SARADC_SAR1_INIT_CODE_MSB_MSB, + I2C_SARADC_SAR1_INIT_CODE_MSB_LSB, + 0x60, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_SAR1_INIT_CODE_LSB, + I2C_SARADC_SAR1_INIT_CODE_LSB_MSB, + I2C_SARADC_SAR1_INIT_CODE_LSB_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_DTEST, + I2C_SARADC_DTEST_MSB, + I2C_SARADC_DTEST_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_ENT_SAR, + I2C_SARADC_ENT_SAR_MSB, + I2C_SARADC_ENT_SAR_LSB, + 0, + ); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + I2C_SARADC_EN_TOUT_SAR1_BUS, + I2C_SARADC_EN_TOUT_SAR1_BUS_MSB, + I2C_SARADC_EN_TOUT_SAR1_BUS_LSB, + 0, + ); + + // disable ADC_CTRL_CLK (SAR ADC function clock) + pcr.saradc_clkm_conf().modify(|_, w| w.bits(0x00404000)); + + // Set PCR_SARADC_CONF_REG to initial state + pcr.saradc_conf().modify(|_, w| w.bits(0x5)); } } -fn reg_write(reg: u32, v: u32) { - unsafe { - (reg as *mut u32).write_volatile(v); - } -} - -fn reg_get_bit(reg: u32, b: u32) -> u32 { - unsafe { (reg as *mut u32).read_volatile() & b } -} - -fn reg_get_field(reg: u32, s: u32, v: u32) -> u32 { - unsafe { ((reg as *mut u32).read_volatile() >> s) & v } -} fn regi2c_enable_block(block: u8) { - reg_set_bit(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); - reg_set_bit(LP_I2C_ANA_MST_DATE_REG, LP_I2C_ANA_MST_I2C_MAT_CLK_EN); + let modem_lpcon = unsafe { &*crate::peripherals::MODEM_LPCON::ptr() }; + + modem_lpcon + .clk_conf() + .modify(|_, w| w.clk_i2c_mst_en().set_bit()); // Before config I2C register, enable corresponding slave. match block { v if v == REGI2C_BBPLL => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); + reg_set_bit(I2C_MST_ANA_CONF1_REG, REGI2C_BBPLL_RD_MASK); } v if v == REGI2C_BIAS => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); + reg_set_bit(I2C_MST_ANA_CONF1_REG, REGI2C_BIAS_RD_MASK); } - v if v == REGI2C_DIG_REG => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); + v if v == REGI2C_PMU => { + reg_set_bit(I2C_MST_ANA_CONF1_REG, REGI2C_DIG_REG_RD_MASK); } v if v == REGI2C_ULP_CAL => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); + reg_set_bit(I2C_MST_ANA_CONF1_REG, REGI2C_ULP_CAL_RD_MASK); } v if v == REGI2C_SAR_I2C => { - reg_set_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); + reg_set_bit(I2C_MST_ANA_CONF1_REG, REGI2C_SAR_I2C_RD_MASK); } _ => (), } @@ -364,38 +289,66 @@ fn regi2c_enable_block(block: u8) { fn regi2c_disable_block(block: u8) { match block { v if v == REGI2C_BBPLL => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BBPLL_DEVICE_EN); + reg_clr_bit(I2C_MST_ANA_CONF1_REG, REGI2C_BBPLL_RD_MASK); } v if v == REGI2C_BIAS => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_BIAS_DEVICE_EN); + reg_clr_bit(I2C_MST_ANA_CONF1_REG, REGI2C_BIAS_RD_MASK); } - v if v == REGI2C_DIG_REG => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_DIG_REG_DEVICE_EN); + v if v == REGI2C_PMU => { + reg_clr_bit(I2C_MST_ANA_CONF1_REG, REGI2C_DIG_REG_RD_MASK); } v if v == REGI2C_ULP_CAL => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_ULP_CAL_DEVICE_EN); + reg_clr_bit(I2C_MST_ANA_CONF1_REG, REGI2C_ULP_CAL_RD_MASK); } v if v == REGI2C_SAR_I2C => { - reg_clr_bit(LP_I2C_ANA_MST_DEVICE_EN_REG, REGI2C_SAR_I2C_DEVICE_EN); + reg_clr_bit(I2C_MST_ANA_CONF1_REG, REGI2C_SAR_I2C_RD_MASK); } _ => (), } } +fn reg_write(reg: u32, v: u32) { + unsafe { + (reg as *mut u32).write_volatile(v); + } +} + +fn reg_get_bit(reg: u32, b: u32) -> u32 { + unsafe { (reg as *mut u32).read_volatile() & b } +} + +fn reg_set_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); + } +} + +fn reg_clr_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !bit); + } +} + +fn reg_get_field(reg: u32, s: u32, v: u32) -> u32 { + unsafe { ((reg as *mut u32).read_volatile() >> s) & v } +} + pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, lsb: u8, data: u8) { assert!(msb - lsb < 8); regi2c_enable_block(block); // Read the i2c bus register + while reg_get_bit(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY) != 0 {} + let mut temp: u32 = ((block as u32 & REGI2C_RTC_SLAVE_ID_V as u32) << REGI2C_RTC_SLAVE_ID_S as u32) | (reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32; - reg_write(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); - while reg_get_bit(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY) != 0 {} + reg_write(I2C_MST_I2C0_CTRL_REG, temp); + while reg_get_bit(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY) != 0 {} temp = reg_get_field( - LP_I2C_ANA_MST_I2C0_DATA_REG, - LP_I2C_ANA_MST_I2C0_RDATA_S, - LP_I2C_ANA_MST_I2C0_RDATA_V, + I2C_MST_I2C0_CTRL_REG, + REGI2C_RTC_DATA_S as u32, + REGI2C_RTC_DATA_V as u32, ); // Write the i2c bus register temp &= (!(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1)); @@ -404,8 +357,8 @@ pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, l | ((reg_add as u32 & REGI2C_RTC_ADDR_V as u32) << REGI2C_RTC_ADDR_S as u32) | ((0x1 & REGI2C_RTC_WR_CNTL_V as u32) << REGI2C_RTC_WR_CNTL_S as u32) | ((temp & REGI2C_RTC_DATA_V as u32) << REGI2C_RTC_DATA_S as u32); - reg_write(LP_I2C_ANA_MST_I2C0_CTRL_REG, temp); - while reg_get_bit(LP_I2C_ANA_MST_I2C0_CTRL_REG, LP_I2C_ANA_MST_I2C0_BUSY) != 0 {} + reg_write(I2C_MST_I2C0_CTRL_REG, temp); + while reg_get_bit(I2C_MST_I2C0_CTRL_REG, REGI2C_RTC_BUSY) != 0 {} regi2c_disable_block(block); } diff --git a/esp-hal/src/soc/esp32s2/trng.rs b/esp-hal/src/soc/esp32s2/trng.rs index 2455e956f11..2999ac1d339 100644 --- a/esp-hal/src/soc/esp32s2/trng.rs +++ b/esp-hal/src/soc/esp32s2/trng.rs @@ -1,17 +1,3 @@ -const DR_REG_RTCCNTL_BASE: u32 = 0x3f408000; -const DR_REG_SYSTEM_BASE: u32 = 0x3f4c0000; -const DR_REG_SENS_BASE: u32 = 0x3f408800; -const DR_REG_APB_SARADC_BASE: u32 = 0x3f440000; -const DPORT_APB_SARADC_CLK_EN: u32 = 1 << 28; -const RTC_CNTL_CLK_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x0074; -const RTC_CNTL_DIG_CLK8M_EN: u32 = 1 << 10; -const DPORT_PERIP_CLK_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x040; -const APB_SARADC_APB_ADC_CLKM_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x05c; -const APB_SARADC_CLK_SEL_V: u32 = 0x3; -const APB_SARADC_CLK_SEL_S: u32 = 21; -const RTC_CNTL_ANA_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x0034; -const RTC_CNTL_SAR_I2C_FORCE_PD_M: u32 = 1 << 21; -const RTC_CNTL_SAR_I2C_FORCE_PU_M: u32 = 1 << 22; const ANA_CONFIG_REG: u32 = 0x6000E044; const ANA_CONFIG2_REG: u32 = 0x6000E048; const I2C_SAR_ADC: u8 = 0x69; @@ -31,29 +17,6 @@ const ADC_SARADC_ENT_TSENS_ADDR_LSB: u8 = 2; const ADC_SARADC_ENT_RTC_ADDR: u8 = 0x7; const ADC_SARADC_ENT_RTC_ADDR_MSB: u8 = 3; const ADC_SARADC_ENT_RTC_ADDR_LSB: u8 = 3; -const APB_SARADC_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE; -const APB_SARADC_SAR1_PATT_LEN_V: u32 = 0xF; -const APB_SARADC_SAR1_PATT_LEN_S: u32 = 15; -const APB_SARADC_SAR1_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x018; -const APB_SARADC_SAR2_PATT_LEN_V: u32 = 0xF; -const APB_SARADC_SAR2_PATT_LEN_S: u32 = 19; -const APB_SARADC_SAR2_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x028; -const SENS_SAR_MEAS1_MUX_REG: u32 = DR_REG_SENS_BASE + 0x0010; -const SENS_SAR1_DIG_FORCE: u32 = 1 << 31; -const APB_SARADC_WORK_MODE_V: u32 = 0x3; -const APB_SARADC_WORK_MODE_S: u32 = 3; - -const APB_SARADC_CTRL2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x004; -const APB_SARADC_MEAS_NUM_LIMIT: u32 = 1 << 0; -const SENS_SAR_POWER_XPD_SAR_REG: u32 = DR_REG_SENS_BASE + 0x003c; -const SENS_FORCE_XPD_SAR: u32 = 0x00000003; -const SENS_FORCE_XPD_SAR_V: u32 = 0x3; -const SENS_FORCE_XPD_SAR_S: u32 = 29; -const APB_SARADC_TIMER_SEL: u32 = 1 << 11; -const APB_SARADC_TIMER_TARGET_V: u32 = 0xFFF; -const APB_SARADC_TIMER_TARGET_S: u32 = 12; -const APB_SARADC_START_FORCE: u32 = 1 << 0; -const APB_SARADC_TIMER_EN: u32 = 1 << 24; const I2C_RTC_SLAVE_ID_V: u8 = 0xFF; const I2C_RTC_SLAVE_ID_S: u8 = 0; @@ -83,204 +46,184 @@ const I2C_RTC_SAR_MASK: u32 = 1 << 18; const I2C_RTC_BOD_MASK: u32 = 1 << 22; pub(crate) fn ensure_randomness() { - // Enable 8M clock source for RNG (this is actually enough to produce strong - // random results, but enabling the SAR ADC as well adds some insurance.) - reg_set_bit(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN); + let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; + let dport = unsafe { &*crate::peripherals::SYSTEM::ptr() }; + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; + let sens = unsafe { &*crate::peripherals::SENS::ptr() }; - // Enable SAR ADC to read a disconnected input for additional entropy - set_peri_reg_mask(DPORT_PERIP_CLK_EN0_REG, DPORT_APB_SARADC_CLK_EN); - - reg_set_field( - APB_SARADC_APB_ADC_CLKM_CONF_REG, - APB_SARADC_CLK_SEL_V, - APB_SARADC_CLK_SEL_S, - 2, - ); + unsafe { + // Enable 8M clock source for RNG (this is actually enough to produce strong + // random results, but enabling the SAR ADC as well adds some insurance.) + rtc_cntl + .clk_conf() + .modify(|_, w| w.dig_clk8m_en().set_bit()); + + // Enable SAR ADC to read a disconnected input for additional entropy + dport + .perip_clk_en0() + .modify(|_, w| w.apb_saradc_clk_en().set_bit()); + + apb_saradc.clkm_conf().modify(|_, w| w.clk_sel().bits(2)); + + rtc_cntl + .ana_conf() + .modify(|_, w| w.sar_i2c_force_pd().clear_bit()); + + rtc_cntl + .ana_conf() + .modify(|_, w| w.sar_i2c_force_pu().set_bit()); + + // Temporarily not in PACs + // esp-idf/components/soc/esp32s2/include/soc/regi2c_defs.h + clear_peri_reg_mask(ANA_CONFIG_REG, 1 << 18); + set_peri_reg_mask(ANA_CONFIG2_REG, 1 << 16); + + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_DREF_ADDR, + ADC_SAR1_DREF_ADDR_MSB, + ADC_SAR1_DREF_ADDR_LSB, + 0x4, + ); - clear_peri_reg_mask(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PD_M); - set_peri_reg_mask(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_SAR_I2C_FORCE_PU_M); - clear_peri_reg_mask(ANA_CONFIG_REG, 1 << 18); - set_peri_reg_mask(ANA_CONFIG2_REG, 1 << 16); - - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR1_DREF_ADDR, - ADC_SAR1_DREF_ADDR_MSB, - ADC_SAR1_DREF_ADDR_LSB, - 0x4, - ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_DREF_ADDR, + ADC_SAR2_DREF_ADDR_MSB, + ADC_SAR2_DREF_ADDR_LSB, + 0x4, + ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR2_DREF_ADDR, - ADC_SAR2_DREF_ADDR_MSB, - ADC_SAR2_DREF_ADDR_LSB, - 0x4, - ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENCAL_REF_ADDR, + ADC_SARADC_ENCAL_REF_ADDR_MSB, + ADC_SARADC_ENCAL_REF_ADDR_LSB, + 1, + ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_ENCAL_REF_ADDR, - ADC_SARADC_ENCAL_REF_ADDR_MSB, - ADC_SARADC_ENCAL_REF_ADDR_LSB, - 1, - ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_TSENS_ADDR, + ADC_SARADC_ENT_TSENS_ADDR_MSB, + ADC_SARADC_ENT_TSENS_ADDR_LSB, + 1, + ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_ENT_TSENS_ADDR, - ADC_SARADC_ENT_TSENS_ADDR_MSB, - ADC_SARADC_ENT_TSENS_ADDR_LSB, - 1, - ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_RTC_ADDR, + ADC_SARADC_ENT_RTC_ADDR_MSB, + ADC_SARADC_ENT_RTC_ADDR_LSB, + 0, + ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_ENT_RTC_ADDR, - ADC_SARADC_ENT_RTC_ADDR_MSB, - ADC_SARADC_ENT_RTC_ADDR_LSB, - 0, - ); + apb_saradc.ctrl().modify(|_, w| w.sar1_patt_len().bits(0)); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SAR1_PATT_LEN_V, - APB_SARADC_SAR1_PATT_LEN_S, - 0, - ); + apb_saradc + .sar1_patt_tab1() + .modify(|_, w| w.bits(0xafffffff)); - write_peri_reg(APB_SARADC_SAR1_PATT_TAB1_REG, 0xafffffff); + apb_saradc.ctrl().modify(|_, w| w.sar2_patt_len().bits(0)); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SAR2_PATT_LEN_V, - APB_SARADC_SAR2_PATT_LEN_S, - 0, - ); + apb_saradc + .sar2_patt_tab1() + .modify(|_, w| w.bits(0xafffffff)); - write_peri_reg(APB_SARADC_SAR2_PATT_TAB1_REG, 0xafffffff); + sens.sar_meas1_mux() + .modify(|_, w| w.sar1_dig_force().set_bit()); - set_peri_reg_mask(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE); + apb_saradc.ctrl().modify(|_, w| w.work_mode().bits(1)); - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_WORK_MODE_V, - APB_SARADC_WORK_MODE_S, - 1, - ); + apb_saradc + .ctrl2() + .modify(|_, w| w.meas_num_limit().clear_bit()); - clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT); + sens.sar_power_xpd_sar() + .modify(|_, w| w.force_xpd_sar().bits(3)); - reg_set_field( - SENS_SAR_POWER_XPD_SAR_REG, - SENS_FORCE_XPD_SAR_V, - SENS_FORCE_XPD_SAR_S, - 3, - ); + apb_saradc.ctrl2().modify(|_, w| w.timer_sel().set_bit()); - set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_SEL); + apb_saradc.ctrl2().modify(|_, w| w.timer_target().bits(100)); - reg_set_field( - APB_SARADC_CTRL2_REG, - APB_SARADC_TIMER_TARGET_V, - APB_SARADC_TIMER_TARGET_S, - 100, - ); + apb_saradc.ctrl().modify(|_, w| w.start_force().clear_bit()); - clear_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_START_FORCE); - set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); + apb_saradc.ctrl2().modify(|_, w| w.timer_en().set_bit()); + } } pub fn revert_trng() { - // Restore internal I2C bus state - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR1_DREF_ADDR, - ADC_SAR1_DREF_ADDR_MSB, - ADC_SAR1_DREF_ADDR_LSB, - 0x1, - ); + let dport = unsafe { &*crate::peripherals::SYSTEM::ptr() }; + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; + let sens = unsafe { &*crate::peripherals::SENS::ptr() }; - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SAR2_DREF_ADDR, - ADC_SAR2_DREF_ADDR_MSB, - ADC_SAR2_DREF_ADDR_LSB, - 0x1, - ); + unsafe { + // Restore internal I2C bus state + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR1_DREF_ADDR, + ADC_SAR1_DREF_ADDR_MSB, + ADC_SAR1_DREF_ADDR_LSB, + 0x1, + ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_ENCAL_REF_ADDR, - ADC_SARADC_ENCAL_REF_ADDR_MSB, - ADC_SARADC_ENCAL_REF_ADDR_LSB, - 0, - ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SAR2_DREF_ADDR, + ADC_SAR2_DREF_ADDR_MSB, + ADC_SAR2_DREF_ADDR_LSB, + 0x1, + ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_ENT_TSENS_ADDR, - ADC_SARADC_ENT_TSENS_ADDR_MSB, - ADC_SARADC_ENT_TSENS_ADDR_LSB, - 0, - ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENCAL_REF_ADDR, + ADC_SARADC_ENCAL_REF_ADDR_MSB, + ADC_SARADC_ENCAL_REF_ADDR_LSB, + 0, + ); - regi2c_write_mask( - I2C_SAR_ADC, - I2C_SAR_ADC_HOSTID, - ADC_SARADC_ENT_RTC_ADDR, - ADC_SARADC_ENT_RTC_ADDR_MSB, - ADC_SARADC_ENT_RTC_ADDR_LSB, - 0, - ); + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_TSENS_ADDR, + ADC_SARADC_ENT_TSENS_ADDR_MSB, + ADC_SARADC_ENT_TSENS_ADDR_LSB, + 0, + ); - // Restore SARADC to default mode - clear_peri_reg_mask(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE); - set_peri_reg_mask(DPORT_PERIP_CLK_EN0_REG, DPORT_APB_SARADC_CLK_EN); - set_peri_reg_bits( - SENS_SAR_POWER_XPD_SAR_REG, - SENS_FORCE_XPD_SAR, - 0, - SENS_FORCE_XPD_SAR_S, - ); - clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); -} + regi2c_write_mask( + I2C_SAR_ADC, + I2C_SAR_ADC_HOSTID, + ADC_SARADC_ENT_RTC_ADDR, + ADC_SARADC_ENT_RTC_ADDR_MSB, + ADC_SARADC_ENT_RTC_ADDR_LSB, + 0, + ); -fn reg_set_bit(reg: u32, bit: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); - } -} + // Restore SARADC to default mode + sens.sar_meas1_mux() + .modify(|_, w| w.sar1_dig_force().clear_bit()); -fn reg_write(reg: u32, v: u32) { - unsafe { - (reg as *mut u32).write_volatile(v); - } -} - -fn reg_get_bit(reg: u32, b: u32) -> u32 { - unsafe { (reg as *mut u32).read_volatile() & b } -} + dport + .perip_clk_en0() + .modify(|_, w| w.apb_saradc_clk_en().set_bit()); -fn reg_get_field(reg: u32, s: u32, v: u32) -> u32 { - unsafe { ((reg as *mut u32).read_volatile() >> s) & v } -} + sens.sar_power_xpd_sar() + .modify(|_, w| w.force_xpd_sar().bits(0)); -fn reg_clr_bit(reg: u32, bit: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !bit); + apb_saradc.ctrl2().modify(|_, w| w.timer_en().clear_bit()); } } - +// Temporarily not in PACs fn regi2c_enable_block(block: u8) { reg_set_field( I2C_RTC_CONFIG0, @@ -356,6 +299,26 @@ pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, l regi2c_disable_block(block); } +fn reg_write(reg: u32, v: u32) { + unsafe { + (reg as *mut u32).write_volatile(v); + } +} + +fn reg_get_bit(reg: u32, b: u32) -> u32 { + unsafe { (reg as *mut u32).read_volatile() & b } +} + +fn reg_get_field(reg: u32, s: u32, v: u32) -> u32 { + unsafe { ((reg as *mut u32).read_volatile() >> s) & v } +} + +fn reg_clr_bit(reg: u32, bit: u32) { + unsafe { + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !bit); + } +} + fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { unsafe { (reg as *mut u32).write_volatile( @@ -365,17 +328,15 @@ fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { } } -fn set_peri_reg_mask(reg: u32, mask: u32) { +fn reg_set_bit(reg: u32, bit: u32) { unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); } } -fn set_peri_reg_bits(reg: u32, bitmap: u32, value: u32, shift: u32) { +fn set_peri_reg_mask(reg: u32, mask: u32) { unsafe { - (reg as *mut u32).write_volatile( - ((reg as *mut u32).read_volatile() & !(bitmap << shift)) | ((value & bitmap) << shift), - ); + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); } } @@ -384,9 +345,3 @@ fn clear_peri_reg_mask(reg: u32, mask: u32) { (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); } } - -fn write_peri_reg(reg: u32, val: u32) { - unsafe { - (reg as *mut u32).write_volatile(val); - } -} diff --git a/esp-hal/src/soc/esp32s3/trng.rs b/esp-hal/src/soc/esp32s3/trng.rs index 5d39fbf0f6c..2b194225ba3 100644 --- a/esp-hal/src/soc/esp32s3/trng.rs +++ b/esp-hal/src/soc/esp32s3/trng.rs @@ -1,54 +1,7 @@ const DR_REG_SYSCON_BASE: u32 = 0x60026000; -const DR_REG_RTCCNTL_BASE: u32 = 0x60008000; -const DR_REG_SYSTEM_BASE: u32 = 0x600C0000; -const DR_REG_APB_SARADC_BASE: u32 = 0x60040000; -const DR_REG_SENS_BASE: u32 = 0x60008800; const SYSTEM_WIFI_CLK_EN_REG: u32 = DR_REG_SYSCON_BASE + 0x14; const SYSTEM_WIFI_CLK_RNG_EN: u32 = 1 << 15; -const RTC_CNTL_CLK_CONF_REG: u32 = DR_REG_RTCCNTL_BASE + 0x74; -const RTC_CNTL_DIG_CLK8M_EN: u32 = 1 << 10; -const SYSTEM_PERIP_CLK_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x18; -const SYSTEM_APB_SARADC_CLK_EN: u32 = 1 << 28; -const APB_SARADC_APB_ADC_CLKM_CONF_REG: u32 = DR_REG_APB_SARADC_BASE + 0x70; -const APB_SARADC_CLK_SEL_V: u32 = 0x3; -const APB_SARADC_CLK_SEL_S: u32 = 21; -const APB_SARADC_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE; -const APB_SARADC_CTRL2_REG: u32 = DR_REG_APB_SARADC_BASE + 0x4; -const APB_SARADC_SAR_CLK_GATED: u32 = 1 << 6; -const APB_SARADC_CLK_EN: u32 = 1 << 20; -const APB_SARADC_CLKM_DIV_NUM_V: u32 = 0xFF; -const APB_SARADC_CLKM_DIV_NUM_S: u32 = 0; -const APB_SARADC_SAR_CLK_DIV_V: u32 = 0xFF; -const APB_SARADC_SAR_CLK_DIV_S: u32 = 7; -const APB_SARADC_TIMER_TARGET_V: u32 = 0xFFF; -const APB_SARADC_TIMER_TARGET_S: u32 = 0x12; -const APB_SARADC_START_FORCE: u32 = 1 << 0; -const SENS_SAR_POWER_XPD_SAR_REG: u32 = DR_REG_SENS_BASE + 0x3C; -const SENS_FORCE_XPD_SAR_V: u32 = 0x3; -const SENS_FORCE_XPD_SAR_S: u32 = 29; -const APB_SARADC_MEAS_NUM_LIMIT: u32 = 1 << 0; -const APB_SARADC_WORK_MODE_V: u32 = 0x3; -const APB_SARADC_WORK_MODE_S: u32 = 0x3; -const APB_SARADC_SAR2_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x28; -const APB_SARADC_SAR2_PATT_LEN_V: u32 = 0xF; -const APB_SARADC_SAR2_PATT_LEN_S: u32 = 19; -const APB_SARADC_SAR1_PATT_LEN_V: u32 = 0xF; -const APB_SARADC_SAR1_PATT_LEN_S: u32 = 15; -const APB_SARADC_SAR1_PATT_TAB1_REG: u32 = DR_REG_APB_SARADC_BASE + 0x18; -const SENS_SAR_MEAS1_MUX_REG: u32 = DR_REG_SENS_BASE + 0x10; -const SENS_SAR1_DIG_FORCE: u32 = 1 << 31; -const SENS_SAR_MEAS2_MUX_REG: u32 = DR_REG_SENS_BASE + 0x34; -const SENS_SAR2_RTC_FORCE: u32 = 1 << 31; -const APB_SARADC_APB_ADC_ARB_CTRL_REG: u32 = DR_REG_APB_SARADC_BASE + 0x38; -const APB_SARADC_ADC_ARB_GRANT_FORCE: u32 = 1 << 5; -const APB_SARADC_ADC_ARB_FIX_PRIORITY: u32 = 1 << 12; -const APB_SARADC_FILTER_CTRL0_REG: u32 = DR_REG_APB_SARADC_BASE + 0x3C; -const APB_SARADC_FILTER_CHANNEL0_V: u32 = 0x1F; -const APB_SARADC_FILTER_CHANNEL0_S: u32 = 19; -const APB_SARADC_FILTER_CHANNEL1_V: u32 = 0x1F; -const APB_SARADC_FILTER_CHANNEL1_S: u32 = 14; -const APB_SARADC_TIMER_SEL: u32 = 1 << 11; -const APB_SARADC_TIMER_EN: u32 = 1 << 24; + const I2C_SAR_ADC: u8 = 0x69; const I2C_SAR_ADC_HOSTID: u8 = 1; const ADC_SARADC_ENCAL_REF_ADDR: u8 = 0x7; @@ -63,178 +16,134 @@ const ADC_SARADC_ENT_RTC_ADDR_LSB: u32 = 3; const ADC_SARADC_DTEST_RTC_ADDR: u32 = 0x7; const ADC_SARADC_DTEST_RTC_ADDR_MSB: u32 = 1; const ADC_SARADC_DTEST_RTC_ADDR_LSB: u32 = 0; -const SYSTEM_PERIP_RST_EN0_REG: u32 = DR_REG_SYSTEM_BASE + 0x20; -const SYSTEM_APB_SARADC_RST: u32 = 1 << 28; use crate::regi2c_write_mask; pub(crate) fn ensure_randomness() { - set_peri_reg_mask(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_RNG_EN); - - // Enable 8M clock source for RNG (this is actually enough to produce strong - // random results, but enabling the SAR ADC as well adds some insurance.) - reg_set_bit(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_EN); - - // Enable SAR ADC to read a disconnected input for additional entropy - set_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN); - clear_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, SYSTEM_APB_SARADC_CLK_EN); - - reg_set_field( - APB_SARADC_APB_ADC_CLKM_CONF_REG, - APB_SARADC_CLK_SEL_V, - APB_SARADC_CLK_SEL_S, - 2, - ); - - set_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_SAR_CLK_GATED); - set_peri_reg_mask(APB_SARADC_APB_ADC_CLKM_CONF_REG, APB_SARADC_CLK_EN); - - reg_set_field( - APB_SARADC_APB_ADC_CLKM_CONF_REG, - APB_SARADC_CLKM_DIV_NUM_V, - APB_SARADC_CLKM_DIV_NUM_S, - 3, - ); - - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SAR_CLK_DIV_V, - APB_SARADC_SAR_CLK_DIV_S, - 3, - ); - - reg_set_field( - APB_SARADC_CTRL2_REG, - APB_SARADC_TIMER_TARGET_V, - APB_SARADC_TIMER_TARGET_S, - 70, - ); - - clear_peri_reg_mask(APB_SARADC_CTRL_REG, APB_SARADC_START_FORCE); - reg_set_field( - SENS_SAR_POWER_XPD_SAR_REG, - SENS_FORCE_XPD_SAR_V, - SENS_FORCE_XPD_SAR_S, - 3, - ); - clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_MEAS_NUM_LIMIT); - - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_WORK_MODE_V, - APB_SARADC_WORK_MODE_S, - 1, - ); - - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SAR2_PATT_LEN_V, - APB_SARADC_SAR2_PATT_LEN_S, - 0, - ); - - write_peri_reg(APB_SARADC_SAR2_PATT_TAB1_REG, 0xafffff); - - reg_set_field( - APB_SARADC_CTRL_REG, - APB_SARADC_SAR1_PATT_LEN_V, - APB_SARADC_SAR1_PATT_LEN_S, - 0, - ); - - write_peri_reg(APB_SARADC_SAR1_PATT_TAB1_REG, 0xafffff); - - set_peri_reg_mask(SENS_SAR_MEAS1_MUX_REG, SENS_SAR1_DIG_FORCE); - - clear_peri_reg_mask(SENS_SAR_MEAS2_MUX_REG, SENS_SAR2_RTC_FORCE); - - clear_peri_reg_mask( - APB_SARADC_APB_ADC_ARB_CTRL_REG, - APB_SARADC_ADC_ARB_GRANT_FORCE, - ); - clear_peri_reg_mask( - APB_SARADC_APB_ADC_ARB_CTRL_REG, - APB_SARADC_ADC_ARB_FIX_PRIORITY, - ); - - reg_set_field( - APB_SARADC_FILTER_CTRL0_REG, - APB_SARADC_FILTER_CHANNEL0_V, - APB_SARADC_FILTER_CHANNEL0_S, - 0xD, - ); - - reg_set_field( - APB_SARADC_FILTER_CTRL0_REG, - APB_SARADC_FILTER_CHANNEL1_V, - APB_SARADC_FILTER_CHANNEL1_S, - 0xD, - ); - - set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_SEL); - set_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 1); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 1); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 1); - - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 1); -} + let rtc_cntl = unsafe { &*crate::peripherals::RTC_CNTL::ptr() }; + let system = unsafe { &*crate::peripherals::SYSTEM::ptr() }; + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; + let sens = unsafe { &*crate::peripherals::SENS::ptr() }; -pub fn revert_trng() { - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 0); + unsafe { + // Temporarily `WIFI_CLK_RNG_EN` is not in PACs + set_peri_reg_mask(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_RNG_EN); - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); + // Enable 8M clock source for RNG (this is actually enough to produce strong + // random results, but enabling the SAR ADC as well adds some insurance.) + rtc_cntl + .clk_conf() + .modify(|_, w| w.dig_clk8m_en().set_bit()); - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); + // Enable SAR ADC to read a disconnected input for additional entropy + // Reset ADC clock + system + .perip_clk_en0() + .modify(|_, w| w.apb_saradc_clk_en().set_bit()); - regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + system + .perip_clk_en0() + .modify(|_, w| w.apb_saradc_clk_en().clear_bit()); - reg_set_field( - SENS_SAR_POWER_XPD_SAR_REG, - SENS_FORCE_XPD_SAR_V, - SENS_FORCE_XPD_SAR_S, - 0, - ); + apb_saradc.clkm_conf().modify(|_, w| w.clk_sel().bits(2)); - clear_peri_reg_mask(APB_SARADC_CTRL2_REG, APB_SARADC_TIMER_EN); + apb_saradc.ctrl().modify(|_, w| w.sar_clk_gated().set_bit()); + apb_saradc.clkm_conf().modify(|_, w| w.clk_en().set_bit()); - clear_peri_reg_mask(SYSTEM_PERIP_CLK_EN0_REG, APB_SARADC_CLK_EN); + apb_saradc + .clkm_conf() + .modify(|_, w| w.clkm_div_num().bits(3)); - set_peri_reg_mask(SYSTEM_PERIP_RST_EN0_REG, SYSTEM_APB_SARADC_RST); -} + apb_saradc.ctrl().modify(|_, w| w.sar_clk_div().bits(3)); -fn reg_set_bit(reg: u32, bit: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | bit); - } -} + apb_saradc.ctrl2().modify(|_, w| w.timer_target().bits(3)); -fn reg_set_field(reg: u32, field_v: u32, field_s: u32, value: u32) { - unsafe { - (reg as *mut u32).write_volatile( - ((reg as *mut u32).read_volatile() & !(field_v << field_s)) - | ((value & field_v) << field_s), - ) - } -} + apb_saradc.ctrl().modify(|_, w| w.sar_clk_div().bits(3)); -fn set_peri_reg_mask(reg: u32, mask: u32) { - unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); + sens.sar_power_xpd_sar() + .modify(|_, w| w.force_xpd_sar().bits(3)); + + apb_saradc + .ctrl2() + .modify(|_, w| w.meas_num_limit().clear_bit()); + + apb_saradc.ctrl().modify(|_, w| w.work_mode().bits(1)); + + apb_saradc.ctrl().modify(|_, w| w.sar2_patt_len().bits(0)); + + apb_saradc.sar2_patt_tab1().modify(|_, w| w.bits(0xafffff)); + + apb_saradc.ctrl().modify(|_, w| w.sar1_patt_len().bits(0)); + + apb_saradc.sar1_patt_tab1().modify(|_, w| w.bits(0xafffff)); + + sens.sar_meas1_mux() + .modify(|_, w| w.sar1_dig_force().set_bit()); + + sens.sar_meas2_mux() + .modify(|_, w| w.sar2_rtc_force().clear_bit()); + + apb_saradc + .arb_ctrl() + .modify(|_, w| w.grant_force().clear_bit()); + + apb_saradc + .arb_ctrl() + .modify(|_, w| w.fix_priority().clear_bit()); + + apb_saradc + .filter_ctrl0() + .modify(|_, w| w.filter_channel0().bits(0xD)); + + apb_saradc + .filter_ctrl0() + .modify(|_, w| w.filter_channel1().bits(0xD)); + + apb_saradc.ctrl2().modify(|_, w| w.timer_sel().set_bit()); + + apb_saradc.ctrl2().modify(|_, w| w.timer_en().set_bit()); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 1); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 1); } } -fn clear_peri_reg_mask(reg: u32, mask: u32) { +pub fn revert_trng() { + let system = unsafe { &*crate::peripherals::SYSTEM::ptr() }; + let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; + let sens = unsafe { &*crate::peripherals::SENS::ptr() }; + unsafe { - (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() & !mask); + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENCAL_REF_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_TSENS_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_ENT_RTC_ADDR, 0); + + regi2c_write_mask!(I2C_SAR_ADC, ADC_SARADC_DTEST_RTC_ADDR, 0); + + sens.sar_power_xpd_sar() + .modify(|_, w| w.force_xpd_sar().bits(0)); + + apb_saradc.ctrl2().modify(|_, w| w.timer_en().clear_bit()); + + system + .perip_clk_en0() + .modify(|_, w| w.apb_saradc_clk_en().clear_bit()); + + system + .perip_rst_en0() + .modify(|_, w| w.apb_saradc_rst().set_bit()); } } -fn write_peri_reg(reg: u32, val: u32) { +fn set_peri_reg_mask(reg: u32, mask: u32) { unsafe { - (reg as *mut u32).write_volatile(val); + (reg as *mut u32).write_volatile((reg as *mut u32).read_volatile() | mask); } } From e66773feacc9f7824acf41967e38080164f3afaa Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Fri, 28 Jun 2024 14:17:12 +0200 Subject: [PATCH 12/16] Get docs buildable rustfmt --- esp-hal/src/rng.rs | 22 +++++++++++----------- esp-hal/src/soc/esp32c6/trng.rs | 2 -- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index 346cd98bf2e..fba85585b21 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -131,29 +131,29 @@ impl rand_core::RngCore for Rng { /// Due to pulling the entropy source from the ADC, it uses the associated /// regiters, so to use TRNG we need to "occupy" the ADC peripheral. /// -/// ```no_run -/// let analog_pin = io.pins.gpio3.into_analog(); -/// let mut adc1_config = AdcConfig::new(); -/// let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); -/// let mut adc1 = ADC::::new(peripherals.ADC1, adc1_config); -/// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); -/// +/// ```rust, ignore /// let mut buf = [0u8; 16]; -/// let mut trng = Trng::new(peripherals.RNG, &mut adc1); +/// let mut trng = Trng::new(peripherals.RNG, &mut peripherals.ADC1); /// trng.read(&mut buf); /// /// println!("TRNG: Random bytes: {:?}", buf); -/// println!("TRNG: Random u32: {}", rng.random()); +/// println!("TRNG: Random u32: {}", rng.random()); /// /// let mut rng = trng.downgrade(); /// +/// let analog_pin = io.pins.gpio3; +/// let mut adc1_config = AdcConfig::new(); +/// let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); +/// let mut adc1 = Adc::::new(peripherals.ADC1, adc1_config); +/// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); +/// /// rng.read(&mut buf); /// println!("Random bytes: {:?}", buf); -/// -/// println!("Random u32: {}", rng.random()); +/// println!("Random u32: {}", rng.random()); /// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); /// println!("ADC reading = {}", pin_value); /// ``` + pub struct Trng<'d> { /// The hardware random number generator instance. pub rng: Rng, diff --git a/esp-hal/src/soc/esp32c6/trng.rs b/esp-hal/src/soc/esp32c6/trng.rs index 53747e80e5c..1bd462fcac4 100644 --- a/esp-hal/src/soc/esp32c6/trng.rs +++ b/esp-hal/src/soc/esp32c6/trng.rs @@ -408,7 +408,6 @@ pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, l .read() .lp_i2c_ana_mast_i2c0_busy() .bit() - != false {} temp = lp_i2c_ana @@ -434,7 +433,6 @@ pub(crate) fn regi2c_write_mask(block: u8, _host_id: u8, reg_add: u8, msb: u8, l .read() .lp_i2c_ana_mast_i2c0_busy() .bit() - != false {} regi2c_disable_block(block); From 870b0e5ce13abda345bdf8e34eedbbed10865aa5 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 1 Jul 2024 15:11:47 +0200 Subject: [PATCH 13/16] Doc comments fix fmt --- esp-hal/src/rng.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index fba85585b21..f43f8a6d60f 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -131,27 +131,37 @@ impl rand_core::RngCore for Rng { /// Due to pulling the entropy source from the ADC, it uses the associated /// regiters, so to use TRNG we need to "occupy" the ADC peripheral. /// -/// ```rust, ignore +/// ```rust, no_run +#[doc = crate::before_snippet!()] +/// # use esp_hal::rng::Trng; +/// # use esp_hal::peripherals::Peripherals; +/// # use esp_hal::peripherals::ADC1; +/// # use esp_hal::analog::adc::{AdcConfig, Attenuation, Adc}; +/// # use esp_hal::gpio::Io; +/// +/// let mut peripherals = Peripherals::take(); +/// let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); /// let mut buf = [0u8; 16]; +/// +/// // ADC is not available from now /// let mut trng = Trng::new(peripherals.RNG, &mut peripherals.ADC1); /// trng.read(&mut buf); -/// -/// println!("TRNG: Random bytes: {:?}", buf); -/// println!("TRNG: Random u32: {}", rng.random()); +/// let mut true_rand = trng.random(); /// /// let mut rng = trng.downgrade(); /// +/// // ADC is available now /// let analog_pin = io.pins.gpio3; /// let mut adc1_config = AdcConfig::new(); -/// let mut adc1_pin = adc1_config.enable_pin(analog_pin, Attenuation::Attenuation11dB); -/// let mut adc1 = Adc::::new(peripherals.ADC1, adc1_config); -/// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); +/// let mut adc1_pin = adc1_config.enable_pin(analog_pin, +/// Attenuation::Attenuation11dB); let mut adc1 = +/// Adc::::new(peripherals.ADC1, adc1_config); let pin_value: u16 = +/// nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); /// /// rng.read(&mut buf); -/// println!("Random bytes: {:?}", buf); -/// println!("Random u32: {}", rng.random()); +/// true_rand = rng.random(); /// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); -/// println!("ADC reading = {}", pin_value); +/// # } /// ``` pub struct Trng<'d> { From 5aa2c33208a82d8881e990e0f44f333713a9ef06 Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Mon, 1 Jul 2024 15:55:30 +0200 Subject: [PATCH 14/16] Fix docs for esp32 --- esp-hal/src/rng.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index f43f8a6d60f..111748ababd 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -151,7 +151,8 @@ impl rand_core::RngCore for Rng { /// let mut rng = trng.downgrade(); /// /// // ADC is available now -/// let analog_pin = io.pins.gpio3; +#[cfg_attr(esp32, doc = "let analog_pin = io.pins.gpio32;")] +#[cfg_attr(not(esp32), doc = "let analog_pin = io.pins.gpio3;")] /// let mut adc1_config = AdcConfig::new(); /// let mut adc1_pin = adc1_config.enable_pin(analog_pin, /// Attenuation::Attenuation11dB); let mut adc1 = From 7a91b2d4c400fc42d1ced6c68a21dff2cb2a9afa Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Tue, 2 Jul 2024 15:54:29 +0200 Subject: [PATCH 15/16] Small fixes + exclude `downgrade` and `drop` for `esp32c6` Downgrade for `esp32c6` is not implemented so far --- esp-hal/src/rng.rs | 14 +++-- esp-hal/src/soc/esp32c6/trng.rs | 105 ++++++++++++++------------------ 2 files changed, 54 insertions(+), 65 deletions(-) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index 111748ababd..7b37ccc1cd1 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -147,9 +147,7 @@ impl rand_core::RngCore for Rng { /// let mut trng = Trng::new(peripherals.RNG, &mut peripherals.ADC1); /// trng.read(&mut buf); /// let mut true_rand = trng.random(); -/// -/// let mut rng = trng.downgrade(); -/// +#[cfg_attr(not(esp32c6), doc = "let mut rng = trng.downgrade();")] /// // ADC is available now #[cfg_attr(esp32, doc = "let analog_pin = io.pins.gpio32;")] #[cfg_attr(not(esp32), doc = "let analog_pin = io.pins.gpio3;")] @@ -158,9 +156,8 @@ impl rand_core::RngCore for Rng { /// Attenuation::Attenuation11dB); let mut adc1 = /// Adc::::new(peripherals.ADC1, adc1_config); let pin_value: u16 = /// nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); -/// -/// rng.read(&mut buf); -/// true_rand = rng.random(); +#[cfg_attr(not(esp32c6), doc = "rng.read(&mut buf);")] +#[cfg_attr(not(esp32c6), doc = "true_rand = rng.random();")] /// let pin_value: u16 = nb::block!(adc1.read_oneshot(&mut adc1_pin)).unwrap(); /// # } /// ``` @@ -206,10 +203,15 @@ impl<'d> Trng<'d> { /// Downgrades the `Trng` instance to a `Rng` instance and releases the /// ADC1. + /// For esp32c6 - blocked on https://github.com/espressif/esp-idf/issues/14124 + #[cfg(not(esp32c6))] pub fn downgrade(self) -> Rng { self.rng } } + +/// For esp32c6 - blocked on https://github.com/espressif/esp-idf/issues/14124 +#[cfg(not(esp32c6))] impl<'d> Drop for Trng<'d> { fn drop(&mut self) { crate::soc::trng::revert_trng(); diff --git a/esp-hal/src/soc/esp32c6/trng.rs b/esp-hal/src/soc/esp32c6/trng.rs index 1bd462fcac4..c08b363e2fd 100644 --- a/esp-hal/src/soc/esp32c6/trng.rs +++ b/esp-hal/src/soc/esp32c6/trng.rs @@ -12,11 +12,13 @@ const REGI2C_DIG_REG: u8 = 0x6d; const REGI2C_ULP_CAL: u8 = 0x61; const REGI2C_SAR_I2C: u8 = 0x69; -const REGI2C_BBPLL_DEVICE_EN: u32 = 1 << 5; -const REGI2C_BIAS_DEVICE_EN: u32 = 1 << 4; -const REGI2C_DIG_REG_DEVICE_EN: u32 = 1 << 8; -const REGI2C_ULP_CAL_DEVICE_EN: u32 = 1 << 6; -const REGI2C_SAR_I2C_DEVICE_EN: u32 = 1 << 7; +const I2C_MST_ANA_CONF1_M: u32 = 0x00FFFFFF; +const REGI2C_BBPLL_RD_MASK: u32 = !(1 << 7) & I2C_MST_ANA_CONF1_M; +const REGI2C_BIAS_RD_MASK: u32 = !(1 << 6) & I2C_MST_ANA_CONF1_M; +const REGI2C_DIG_REG_RD_MASK: u32 = !(1 << 10) & I2C_MST_ANA_CONF1_M; +const REGI2C_ULP_CAL_RD_MASK: u32 = !(1 << 8) & I2C_MST_ANA_CONF1_M; +const REGI2C_SAR_I2C_RD_MASK: u32 = !(1 << 9) & I2C_MST_ANA_CONF1_M; + const REGI2C_RTC_SLAVE_ID_V: u8 = 0xFF; const REGI2C_RTC_SLAVE_ID_S: u8 = 0; const REGI2C_RTC_ADDR_V: u8 = 0xFF; @@ -122,9 +124,9 @@ pub(crate) fn ensure_randomness() { regi2c_write_mask( I2C_SAR_ADC, I2C_SAR_ADC_HOSTID, - ADC_SARADC1_ENCAL_REF_ADDR, - ADC_SARADC1_ENCAL_REF_ADDR_MSB, - ADC_SARADC1_ENCAL_REF_ADDR_LSB, + ADC_SARADC2_ENCAL_REF_ADDR, + ADC_SARADC2_ENCAL_REF_ADDR_MSB, + ADC_SARADC2_ENCAL_REF_ADDR_LSB, 1, ); @@ -134,7 +136,7 @@ pub(crate) fn ensure_randomness() { ADC_SAR2_INITIAL_CODE_HIGH_ADDR, ADC_SAR2_INITIAL_CODE_HIGH_ADDR_MSB, ADC_SAR2_INITIAL_CODE_HIGH_ADDR_LSB, - 0x60, + 0x08, ); regi2c_write_mask( @@ -188,6 +190,7 @@ pub(crate) fn ensure_randomness() { } } +#[allow(unused)] pub(crate) fn revert_trng() { let apb_saradc = unsafe { &*crate::peripherals::APB_SARADC::ptr() }; let pmu = unsafe { &*crate::peripherals::PMU::ptr() }; @@ -287,49 +290,43 @@ fn regi2c_enable_block(block: u8) { .clk_conf() .modify(|_, w| w.clk_i2c_mst_en().set_bit()); + modem_lpcon + .i2c_mst_clk_conf() + .modify(|_, w| w.clk_i2c_mst_sel_160m().set_bit()); + lp_i2c_ana .date() .modify(|_, w| w.lp_i2c_ana_mast_i2c_mat_clk_en().set_bit()); match block { REGI2C_BBPLL => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_BBPLL_DEVICE_EN) - as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() | REGI2C_BBPLL_RD_MASK) }); } REGI2C_BIAS => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_BIAS_DEVICE_EN) - as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() | REGI2C_BIAS_RD_MASK) }); } REGI2C_DIG_REG => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_DIG_REG_DEVICE_EN) - as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() | REGI2C_DIG_REG_RD_MASK) }); } REGI2C_ULP_CAL => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_ULP_CAL_DEVICE_EN) - as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() | REGI2C_ULP_CAL_RD_MASK) }); } REGI2C_SAR_I2C => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 | REGI2C_SAR_I2C_DEVICE_EN) - as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() | REGI2C_SAR_I2C_RD_MASK) }); } _ => (), @@ -343,43 +340,33 @@ fn regi2c_disable_block(block: u8) { unsafe { match block { REGI2C_BBPLL => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 & !REGI2C_BBPLL_DEVICE_EN) - as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() & !REGI2C_BBPLL_RD_MASK) }); } REGI2C_BIAS => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 & !REGI2C_BIAS_DEVICE_EN) - as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() & !REGI2C_BIAS_RD_MASK) }); } REGI2C_DIG_REG => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 - & !REGI2C_DIG_REG_DEVICE_EN) as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() & !REGI2C_DIG_REG_RD_MASK) }); } REGI2C_ULP_CAL => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 - & !REGI2C_ULP_CAL_DEVICE_EN) as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() & !REGI2C_ULP_CAL_RD_MASK) }); } REGI2C_SAR_I2C => { - lp_i2c_ana.device_en().modify(|r, w| { - w.lp_i2c_ana_mast_i2c_device_en().bits( - (r.lp_i2c_ana_mast_i2c_device_en().bits() as u32 - & !REGI2C_SAR_I2C_DEVICE_EN) as u16, - ) + lp_i2c_ana.ana_conf1().modify(|r, w| { + w.lp_i2c_ana_mast_ana_conf1() + .bits(r.lp_i2c_ana_mast_ana_conf1().bits() & !REGI2C_SAR_I2C_RD_MASK) }); } _ => (), From c56db37864b38218b80b692700e1893f1516d6fb Mon Sep 17 00:00:00 2001 From: Kirill Mikhailov Date: Thu, 4 Jul 2024 10:46:51 +0200 Subject: [PATCH 16/16] TRNG/ADC on `esp32c6` warning comment --- esp-hal/src/rng.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/esp-hal/src/rng.rs b/esp-hal/src/rng.rs index 7b37ccc1cd1..3014a15366c 100644 --- a/esp-hal/src/rng.rs +++ b/esp-hal/src/rng.rs @@ -131,6 +131,9 @@ impl rand_core::RngCore for Rng { /// Due to pulling the entropy source from the ADC, it uses the associated /// regiters, so to use TRNG we need to "occupy" the ADC peripheral. /// +/// For now, even after calling `core::mem::drop()` on `TRNG` ADC1 will not be +/// usable (details in esp-hal/#1750) +/// /// ```rust, no_run #[doc = crate::before_snippet!()] /// # use esp_hal::rng::Trng;