diff --git a/Cargo.toml b/Cargo.toml index ae012067c..0ab3323db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "esp-idf-hal" -version = "0.16.2" +version = "0.17.0" authors = ["sapir ", "Ivan Markov "] edition = "2018" categories = ["embedded", "hardware-support"] @@ -19,11 +19,11 @@ default = ["std", "esp-idf-sys"] std = ["esp-idf-sys/std"] -ulp = [] # Early experiment, not working yet +ulp = [] [dependencies] cfg-if = "1" nb = "0.1.2" mutex-trait = "0.2" embedded-hal = { version = "0.2", features = ["unproven"] } -esp-idf-sys = { version = "0.16", optional = true, default-features = false } +esp-idf-sys = { version = "0.16.3", optional = true, default-features = false } diff --git a/src/gpio.rs b/src/gpio.rs index 2f8f71060..f22893ef5 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -10,10 +10,7 @@ //! The advantage of using the dedicated traits in peripherals is that the configuration of the //! IO can be done inside the peripheral instead of having to be done upfront. -use { - core::marker::PhantomData, - embedded_hal::digital::v2::{OutputPin as _, StatefulOutputPin as _}, -}; +use core::marker::PhantomData; #[cfg(not(feature = "ulp"))] use esp_idf_sys::*; @@ -21,6 +18,8 @@ use esp_idf_sys::*; #[cfg(feature = "ulp")] use crate::ulp::sys::*; +pub use chip::*; + /// Extension trait to split a GPIO peripheral into independent pins and registers pub trait GpioExt { /// The type to split the GPIO into @@ -164,7 +163,7 @@ macro_rules! impl_hal_input_pin { type Error = EspError; fn is_high(&self) -> Result { - Ok(unsafe { gpio_get_level($pxi::<$mode>::pin()) } != 0) + Ok(unsafe { gpio_get_level($pxi::<$mode>::runtime_pin()) } != 0) } fn is_low(&self) -> Result { @@ -180,17 +179,23 @@ macro_rules! impl_hal_output_pin { type Error = EspError; fn set_high(&mut self) -> Result<(), Self::Error> { - esp_result!(unsafe { gpio_set_level($pxi::<$mode>::pin(), 1) }, ()) + esp_result!( + unsafe { gpio_set_level($pxi::<$mode>::runtime_pin(), 1) }, + () + ) } fn set_low(&mut self) -> Result<(), Self::Error> { - esp_result!(unsafe { gpio_set_level($pxi::<$mode>::pin(), 0) }, ()) + esp_result!( + unsafe { gpio_set_level($pxi::<$mode>::runtime_pin(), 0) }, + () + ) } } impl embedded_hal::digital::v2::StatefulOutputPin for $pxi<$mode> { fn is_set_high(&self) -> Result { - Ok(unsafe { gpio_get_level($pxi::<$mode>::pin()) } != 0) + Ok(unsafe { gpio_get_level($pxi::<$mode>::runtime_pin()) } != 0) } fn is_set_low(&self) -> Result { @@ -220,7 +225,10 @@ macro_rules! impl_pull { fn set_pull_up(&mut self) -> Result<&mut Self, Self::Error> { esp_result!( unsafe { - gpio_set_pull_mode($pxi::<$mode>::pin(), gpio_pull_mode_t_GPIO_PULLUP_ONLY) + gpio_set_pull_mode( + $pxi::<$mode>::runtime_pin(), + gpio_pull_mode_t_GPIO_PULLUP_ONLY, + ) }, self ) @@ -230,7 +238,7 @@ macro_rules! impl_pull { esp_result!( unsafe { gpio_set_pull_mode( - $pxi::<$mode>::pin(), + $pxi::<$mode>::runtime_pin(), gpio_pull_mode_t_GPIO_PULLDOWN_ONLY, ) }, @@ -242,7 +250,7 @@ macro_rules! impl_pull { esp_result!( unsafe { gpio_set_pull_mode( - $pxi::<$mode>::pin(), + $pxi::<$mode>::runtime_pin(), gpio_pull_mode_t_GPIO_PULLUP_PULLDOWN, ) }, @@ -253,7 +261,10 @@ macro_rules! impl_pull { fn set_floating(&mut self) -> Result<&mut Self, Self::Error> { esp_result!( unsafe { - gpio_set_pull_mode($pxi::<$mode>::pin(), gpio_pull_mode_t_GPIO_FLOATING) + gpio_set_pull_mode( + $pxi::<$mode>::runtime_pin(), + gpio_pull_mode_t_GPIO_FLOATING, + ) }, self ) @@ -268,6 +279,14 @@ macro_rules! impl_input_base { _mode: PhantomData, } + #[cfg(not(feature = "ulp"))] + impl $pxi { + #[inline(always)] + fn runtime_pin() -> i32 { + $pin + } + } + impl Pin for $pxi { type Error = EspError; @@ -287,6 +306,7 @@ macro_rules! impl_input_base { }; } +#[allow(unused)] macro_rules! impl_input_only { ($pxi:ident: $pin:expr) => { impl_input_base!($pxi: $pin); @@ -299,7 +319,10 @@ macro_rules! impl_input_only { pub fn into_disabled(self) -> Result<$pxi, EspError> { esp_result!( unsafe { - gpio_set_direction($pxi::::pin(), gpio_mode_t_GPIO_MODE_DISABLE) + gpio_set_direction( + $pxi::::runtime_pin(), + gpio_mode_t_GPIO_MODE_DISABLE, + ) }, $pxi { _mode: PhantomData } ) @@ -307,7 +330,9 @@ macro_rules! impl_input_only { pub fn into_input(self) -> Result<$pxi, EspError> { esp_result!( - unsafe { gpio_set_direction($pxi::::pin(), gpio_mode_t_GPIO_MODE_INPUT) }, + unsafe { + gpio_set_direction($pxi::::runtime_pin(), gpio_mode_t_GPIO_MODE_INPUT) + }, $pxi { _mode: PhantomData } ) } @@ -335,7 +360,10 @@ macro_rules! impl_input_output { pub fn into_disabled(self) -> Result<$pxi, EspError> { esp_result!( unsafe { - gpio_set_direction($pxi::::pin(), gpio_mode_t_GPIO_MODE_DISABLE) + gpio_set_direction( + $pxi::::runtime_pin(), + gpio_mode_t_GPIO_MODE_DISABLE, + ) }, $pxi { _mode: PhantomData } ) @@ -343,7 +371,9 @@ macro_rules! impl_input_output { pub fn into_input(self) -> Result<$pxi, EspError> { esp_result!( - unsafe { gpio_set_direction($pxi::::pin(), gpio_mode_t_GPIO_MODE_INPUT) }, + unsafe { + gpio_set_direction($pxi::::runtime_pin(), gpio_mode_t_GPIO_MODE_INPUT) + }, $pxi { _mode: PhantomData } ) } @@ -351,7 +381,10 @@ macro_rules! impl_input_output { pub fn into_input_output(self) -> Result<$pxi, EspError> { esp_result!( unsafe { - gpio_set_direction($pxi::::pin(), gpio_mode_t_GPIO_MODE_INPUT_OUTPUT) + gpio_set_direction( + $pxi::::runtime_pin(), + gpio_mode_t_GPIO_MODE_INPUT_OUTPUT, + ) }, $pxi { _mode: PhantomData } ) @@ -361,7 +394,7 @@ macro_rules! impl_input_output { esp_result!( unsafe { gpio_set_direction( - $pxi::::pin(), + $pxi::::runtime_pin(), gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD, ) }, @@ -372,7 +405,10 @@ macro_rules! impl_input_output { pub fn into_output(self) -> Result<$pxi, EspError> { esp_result!( unsafe { - gpio_set_direction($pxi::::pin(), gpio_mode_t_GPIO_MODE_OUTPUT) + gpio_set_direction( + $pxi::::runtime_pin(), + gpio_mode_t_GPIO_MODE_OUTPUT, + ) }, $pxi { _mode: PhantomData } ) @@ -381,7 +417,10 @@ macro_rules! impl_input_output { pub fn into_output_od(self) -> Result<$pxi, EspError> { esp_result!( unsafe { - gpio_set_direction($pxi::::pin(), gpio_mode_t_GPIO_MODE_OUTPUT_OD) + gpio_set_direction( + $pxi::::runtime_pin(), + gpio_mode_t_GPIO_MODE_OUTPUT_OD, + ) }, $pxi { _mode: PhantomData } ) @@ -391,7 +430,15 @@ macro_rules! impl_input_output { } macro_rules! impl_rtc { - ($pxi:ident: $pin:expr, RTC:$rtc:expr) => { + ($pxi:ident: $pin:expr, RTC: $rtc:expr) => { + #[cfg(feature = "ulp")] + impl $pxi { + #[inline(always)] + fn runtime_pin() -> i32 { + $rtc + } + } + impl RTCPin for $pxi { fn rtc_pin() -> i32 { $rtc @@ -399,11 +446,11 @@ macro_rules! impl_rtc { } }; - ($pxi:ident: $pin:expr, NORTC:$rtc:expr) => {}; + ($pxi:ident: $pin:expr, NORTC: $rtc:expr) => {}; } macro_rules! impl_adc { - ($pxi:ident: $pin:expr, ADC1:$adc:expr) => { + ($pxi:ident: $pin:expr, ADC1: $adc:expr) => { impl ADCPin for $pxi { fn adc_unit() -> adc_unit_t { adc_unit_t_ADC_UNIT_1 @@ -415,7 +462,7 @@ macro_rules! impl_adc { } }; - ($pxi:ident: $pin:expr, ADC2:$adc:expr) => { + ($pxi:ident: $pin:expr, ADC2: $adc:expr) => { impl ADCPin for $pxi { fn adc_unit() -> adc_unit_t { adc_unit_t_ADC_UNIT_2 @@ -427,11 +474,11 @@ macro_rules! impl_adc { } }; - ($pxi:ident: $pin:expr, NOADC:$adc:expr) => {}; + ($pxi:ident: $pin:expr, NOADC: $adc:expr) => {}; } macro_rules! impl_dac { - ($pxi:ident: $pin:expr, DAC:$dac:expr) => { + ($pxi:ident: $pin:expr, DAC: $dac:expr) => { #[cfg(not(esp32c3))] impl DACPin for $pxi { fn dac_channel() -> dac_channel_t { @@ -440,11 +487,11 @@ macro_rules! impl_dac { } }; - ($pxi:ident: $pin:expr, NODAC:$dac:expr) => {}; + ($pxi:ident: $pin:expr, NODAC: $dac:expr) => {}; } macro_rules! impl_touch { - ($pxi:ident: $pin:expr, TOUCH:$touch:expr) => { + ($pxi:ident: $pin:expr, TOUCH: $touch:expr) => { #[cfg(not(esp32c3))] impl TouchPin for $pxi { fn touch_channel() -> touch_pad_t { @@ -453,11 +500,11 @@ macro_rules! impl_touch { } }; - ($pxi:ident: $pin:expr, NOTOUCH:$touch:expr) => {}; + ($pxi:ident: $pin:expr, NOTOUCH: $touch:expr) => {}; } macro_rules! pin { - ($pxi:ident: $pin:expr, Input, $rtc:ident:$rtcno:expr, $adc:ident:$adcno:expr, $dac:ident:$dacno:expr, $touch:ident:$touchno:expr) => { + ($pxi:ident: $pin:expr, Input, $rtc:ident: $rtcno:expr, $adc:ident: $adcno:expr, $dac:ident: $dacno:expr, $touch:ident: $touchno:expr) => { impl_input_only!($pxi: $pin); impl_rtc!($pxi: $pin, $rtc: $rtcno); impl_adc!($pxi: $pin, $adc: $adcno); @@ -465,7 +512,7 @@ macro_rules! pin { impl_touch!($pxi: $pin, $touch: $touchno); }; - ($pxi:ident: $pin:expr, IO, $rtc:ident:$rtcno:expr, $adc:ident:$adcno:expr, $dac:ident:$dacno:expr, $touch:ident:$touchno:expr) => { + ($pxi:ident: $pin:expr, IO, $rtc:ident: $rtcno:expr, $adc:ident: $adcno:expr, $dac:ident: $dacno:expr, $touch:ident: $touchno:expr) => { impl_input_output!($pxi: $pin); impl_rtc!($pxi: $pin, $rtc: $rtcno); impl_adc!($pxi: $pin, $adc: $adcno); @@ -474,112 +521,429 @@ macro_rules! pin { }; } -// TODO: Separate pin layout for esp32s2, esp32s3 and esp32c3 -pin!(Gpio0:0, IO, RTC:11, ADC2:1, NODAC:0, TOUCH:1); -pin!(Gpio1:1, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio2:2, IO, RTC:12, ADC2:2, NODAC:0, TOUCH:2); -pin!(Gpio3:3, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio4:4, IO, RTC:10, ADC2:0, NODAC:0, TOUCH:0); -pin!(Gpio5:5, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio6:6, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio7:7, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio8:8, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio9:9, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio10:10, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio11:11, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio12:12, IO, RTC:15, ADC2:5, NODAC:0, TOUCH:5); -pin!(Gpio13:13, IO, RTC:14, ADC2:4, NODAC:0, TOUCH:4); -pin!(Gpio14:14, IO, RTC:16, ADC2:6, NODAC:0, TOUCH:6); -pin!(Gpio15:15, IO, RTC:13, ADC2:3, NODAC:0, TOUCH:3); -pin!(Gpio16:16, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio17:17, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio18:18, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio19:19, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio21:21, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio22:22, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio23:23, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); -pin!(Gpio25:25, IO, RTC:6, ADC2:8, DAC:1, NOTOUCH:0); -pin!(Gpio26:26, IO, RTC:7, ADC2:9, DAC:2, NOTOUCH:0); -pin!(Gpio27:27, IO, RTC:17, ADC2:7, NODAC:0, TOUCH:7); -pin!(Gpio32:32, IO, RTC:9, ADC1:4, NODAC:0, TOUCH:9); -pin!(Gpio33:33, IO, RTC:8, ADC1:5, NODAC:0, TOUCH:8); -pin!(Gpio34:34, Input, RTC:4, ADC1:6, NODAC:0, NOTOUCH:0); -pin!(Gpio35:35, Input, RTC:5, ADC1:7, NODAC:0, NOTOUCH:0); -pin!(Gpio36:36, Input, RTC:0, ADC1:0, NODAC:0, NOTOUCH:0); -pin!(Gpio39:39, Input, RTC:3, ADC1:3, NODAC:0, NOTOUCH:0); +#[cfg(esp32)] +mod chip { + use { + core::marker::PhantomData, + embedded_hal::digital::v2::{OutputPin as _, StatefulOutputPin as _}, + }; -// Not mapped: 20, 24, 28, 29, 30, 31, 37, 38 + #[cfg(not(feature = "ulp"))] + use esp_idf_sys::*; -pub struct Pins { - pub gpio0: Gpio0, - pub gpio1: Gpio1, - pub gpio2: Gpio2, - pub gpio3: Gpio3, - pub gpio4: Gpio4, - pub gpio5: Gpio5, - pub gpio6: Gpio6, - pub gpio7: Gpio7, - pub gpio8: Gpio8, - pub gpio9: Gpio9, - pub gpio10: Gpio10, - pub gpio11: Gpio11, - pub gpio12: Gpio12, - pub gpio13: Gpio13, - pub gpio14: Gpio14, - pub gpio15: Gpio15, - pub gpio16: Gpio16, - pub gpio17: Gpio17, - pub gpio18: Gpio18, - pub gpio19: Gpio19, - pub gpio21: Gpio21, - pub gpio22: Gpio22, - pub gpio23: Gpio23, - pub gpio25: Gpio25, - pub gpio26: Gpio26, - pub gpio27: Gpio27, - pub gpio32: Gpio32, - pub gpio33: Gpio33, - pub gpio34: Gpio34, - pub gpio35: Gpio35, - pub gpio36: Gpio36, - pub gpio39: Gpio39, -} + #[cfg(feature = "ulp")] + use crate::ulp::sys::*; -impl Pins { - pub unsafe fn new() -> Self { - Self { - gpio0: Gpio0::::new(), - gpio1: Gpio1::::new(), - gpio2: Gpio2::::new(), - gpio3: Gpio3::::new(), - gpio4: Gpio4::::new(), - gpio5: Gpio5::::new(), - gpio6: Gpio6::::new(), - gpio7: Gpio7::::new(), - gpio8: Gpio8::::new(), - gpio9: Gpio9::::new(), - gpio10: Gpio10::::new(), - gpio11: Gpio11::::new(), - gpio12: Gpio12::::new(), - gpio13: Gpio13::::new(), - gpio14: Gpio14::::new(), - gpio15: Gpio15::::new(), - gpio16: Gpio16::::new(), - gpio17: Gpio17::::new(), - gpio18: Gpio18::::new(), - gpio19: Gpio19::::new(), - gpio21: Gpio21::::new(), - gpio22: Gpio22::::new(), - gpio23: Gpio23::::new(), - gpio25: Gpio25::::new(), - gpio26: Gpio26::::new(), - gpio27: Gpio27::::new(), - gpio32: Gpio32::::new(), - gpio33: Gpio33::::new(), - gpio34: Gpio34::::new(), - gpio35: Gpio35::::new(), - gpio36: Gpio36::::new(), - gpio39: Gpio39::::new(), + use super::*; + + // Not mapped: 20, 24, 28, 29, 30, 31, 37, 38 + pin!(Gpio0:0, IO, RTC:11, ADC2:1, NODAC:0, TOUCH:1); + #[cfg(not(feature = "ulp"))] + pin!(Gpio1:1, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio2:2, IO, RTC:12, ADC2:2, NODAC:0, TOUCH:2); + #[cfg(not(feature = "ulp"))] + pin!(Gpio3:3, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio4:4, IO, RTC:10, ADC2:0, NODAC:0, TOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio5:5, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio6:6, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio7:7, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio8:8, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio9:9, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio10:10, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio11:11, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio12:12, IO, RTC:15, ADC2:5, NODAC:0, TOUCH:5); + pin!(Gpio13:13, IO, RTC:14, ADC2:4, NODAC:0, TOUCH:4); + pin!(Gpio14:14, IO, RTC:16, ADC2:6, NODAC:0, TOUCH:6); + pin!(Gpio15:15, IO, RTC:13, ADC2:3, NODAC:0, TOUCH:3); + #[cfg(not(feature = "ulp"))] + pin!(Gpio16:16, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio17:17, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio18:18, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio19:19, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio21:21, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio22:22, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio23:23, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio25:25, IO, RTC:6, ADC2:8, DAC:1, NOTOUCH:0); + pin!(Gpio26:26, IO, RTC:7, ADC2:9, DAC:2, NOTOUCH:0); + pin!(Gpio27:27, IO, RTC:17, ADC2:7, NODAC:0, TOUCH:7); + pin!(Gpio32:32, IO, RTC:9, ADC1:4, NODAC:0, TOUCH:9); + pin!(Gpio33:33, IO, RTC:8, ADC1:5, NODAC:0, TOUCH:8); + pin!(Gpio34:34, Input, RTC:4, ADC1:6, NODAC:0, NOTOUCH:0); + pin!(Gpio35:35, Input, RTC:5, ADC1:7, NODAC:0, NOTOUCH:0); + pin!(Gpio36:36, Input, RTC:0, ADC1:0, NODAC:0, NOTOUCH:0); + pin!(Gpio39:39, Input, RTC:3, ADC1:3, NODAC:0, NOTOUCH:0); + + pub struct Pins { + pub gpio0: Gpio0, + #[cfg(not(feature = "ulp"))] + pub gpio1: Gpio1, + pub gpio2: Gpio2, + #[cfg(not(feature = "ulp"))] + pub gpio3: Gpio3, + pub gpio4: Gpio4, + #[cfg(not(feature = "ulp"))] + pub gpio5: Gpio5, + #[cfg(not(feature = "ulp"))] + pub gpio6: Gpio6, + #[cfg(not(feature = "ulp"))] + pub gpio7: Gpio7, + #[cfg(not(feature = "ulp"))] + pub gpio8: Gpio8, + #[cfg(not(feature = "ulp"))] + pub gpio9: Gpio9, + #[cfg(not(feature = "ulp"))] + pub gpio10: Gpio10, + #[cfg(not(feature = "ulp"))] + pub gpio11: Gpio11, + pub gpio12: Gpio12, + pub gpio13: Gpio13, + pub gpio14: Gpio14, + pub gpio15: Gpio15, + #[cfg(not(feature = "ulp"))] + pub gpio16: Gpio16, + #[cfg(not(feature = "ulp"))] + pub gpio17: Gpio17, + #[cfg(not(feature = "ulp"))] + pub gpio18: Gpio18, + #[cfg(not(feature = "ulp"))] + pub gpio19: Gpio19, + #[cfg(not(feature = "ulp"))] + pub gpio21: Gpio21, + #[cfg(not(feature = "ulp"))] + pub gpio22: Gpio22, + #[cfg(not(feature = "ulp"))] + pub gpio23: Gpio23, + pub gpio25: Gpio25, + pub gpio26: Gpio26, + pub gpio27: Gpio27, + pub gpio32: Gpio32, + pub gpio33: Gpio33, + pub gpio34: Gpio34, + pub gpio35: Gpio35, + pub gpio36: Gpio36, + pub gpio39: Gpio39, + } + + impl Pins { + pub unsafe fn new() -> Self { + Self { + gpio0: Gpio0::::new(), + #[cfg(not(feature = "ulp"))] + gpio1: Gpio1::::new(), + gpio2: Gpio2::::new(), + #[cfg(not(feature = "ulp"))] + gpio3: Gpio3::::new(), + gpio4: Gpio4::::new(), + #[cfg(not(feature = "ulp"))] + gpio5: Gpio5::::new(), + #[cfg(not(feature = "ulp"))] + gpio6: Gpio6::::new(), + #[cfg(not(feature = "ulp"))] + gpio7: Gpio7::::new(), + #[cfg(not(feature = "ulp"))] + gpio8: Gpio8::::new(), + #[cfg(not(feature = "ulp"))] + gpio9: Gpio9::::new(), + #[cfg(not(feature = "ulp"))] + gpio10: Gpio10::::new(), + #[cfg(not(feature = "ulp"))] + gpio11: Gpio11::::new(), + gpio12: Gpio12::::new(), + gpio13: Gpio13::::new(), + gpio14: Gpio14::::new(), + gpio15: Gpio15::::new(), + #[cfg(not(feature = "ulp"))] + gpio16: Gpio16::::new(), + #[cfg(not(feature = "ulp"))] + gpio17: Gpio17::::new(), + #[cfg(not(feature = "ulp"))] + gpio18: Gpio18::::new(), + #[cfg(not(feature = "ulp"))] + gpio19: Gpio19::::new(), + #[cfg(not(feature = "ulp"))] + gpio21: Gpio21::::new(), + #[cfg(not(feature = "ulp"))] + gpio22: Gpio22::::new(), + #[cfg(not(feature = "ulp"))] + gpio23: Gpio23::::new(), + gpio25: Gpio25::::new(), + gpio26: Gpio26::::new(), + gpio27: Gpio27::::new(), + gpio32: Gpio32::::new(), + gpio33: Gpio33::::new(), + gpio34: Gpio34::::new(), + gpio35: Gpio35::::new(), + gpio36: Gpio36::::new(), + gpio39: Gpio39::::new(), + } + } + } +} + +#[cfg(any(esp32s2, esp32s3))] +mod chip { + use { + core::marker::PhantomData, + embedded_hal::digital::v2::{OutputPin as _, StatefulOutputPin as _}, + }; + + #[cfg(not(feature = "ulp"))] + use esp_idf_sys::*; + + #[cfg(feature = "ulp")] + use crate::ulp::sys::*; + + use super::*; + + // Not mapped: 22 - 25, 27 - 32 + pin!(Gpio0:0, IO, RTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio1:1, IO, RTC:1, ADC1:0, NODAC:0, TOUCH:1); + pin!(Gpio2:2, IO, RTC:2, ADC1:1, NODAC:0, TOUCH:2); + pin!(Gpio3:3, IO, RTC:3, ADC1:2, NODAC:0, TOUCH:3); + pin!(Gpio4:4, IO, RTC:4, ADC1:3, NODAC:0, TOUCH:4); + pin!(Gpio5:5, IO, RTC:5, ADC1:4, NODAC:0, TOUCH:5); + pin!(Gpio6:6, IO, RTC:6, ADC1:5, NODAC:0, TOUCH:6); + pin!(Gpio7:7, IO, RTC:7, ADC1:6, NODAC:0, TOUCH:7); + pin!(Gpio8:8, IO, RTC:8, ADC1:7, NODAC:0, TOUCH:8); + pin!(Gpio9:9, IO, RTC:9, ADC1:8, NODAC:0, TOUCH:9); + pin!(Gpio10:10, IO, RTC:10, ADC1:9, NODAC:0, TOUCH:10); + pin!(Gpio11:11, IO, RTC:11, ADC2:0, NODAC:0, TOUCH:11); + pin!(Gpio12:12, IO, RTC:12, ADC2:1, NODAC:0, TOUCH:12); + pin!(Gpio13:13, IO, RTC:13, ADC2:2, NODAC:0, TOUCH:13); + pin!(Gpio14:14, IO, RTC:14, ADC2:3, NODAC:0, TOUCH:14); + pin!(Gpio15:15, IO, RTC:15, ADC2:4, NODAC:0, TOUCH:15); + pin!(Gpio16:16, IO, RTC:16, ADC2:5, NODAC:0, NOTOUCH:0); + pin!(Gpio17:17, IO, RTC:17, ADC2:6, NODAC:0, NOTOUCH:0); + pin!(Gpio18:18, IO, RTC:18, ADC2:7, NODAC:0, NOTOUCH:0); + pin!(Gpio19:19, IO, RTC:19, ADC2:8, NODAC:0, NOTOUCH:0); + pin!(Gpio20:20, IO, RTC:20, ADC2:9, NODAC:0, NOTOUCH:0); + pin!(Gpio21:21, IO, RTC:21, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio26:26, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio33:33, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio34:34, Input, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio35:35, Input, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio36:36, Input, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio37:37, Input, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio38:38, Input, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio39:39, Input, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio40:40, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio41:41, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio42:42, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio43:43, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio44:44, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio45:45, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + #[cfg(not(feature = "ulp"))] + pin!(Gpio46:46, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + + pub struct Pins { + pub gpio0: Gpio0, + pub gpio1: Gpio1, + pub gpio2: Gpio2, + pub gpio3: Gpio3, + pub gpio4: Gpio4, + pub gpio5: Gpio5, + pub gpio6: Gpio6, + pub gpio7: Gpio7, + pub gpio8: Gpio8, + pub gpio9: Gpio9, + pub gpio10: Gpio10, + pub gpio11: Gpio11, + pub gpio12: Gpio12, + pub gpio13: Gpio13, + pub gpio14: Gpio14, + pub gpio15: Gpio15, + pub gpio16: Gpio16, + pub gpio17: Gpio17, + pub gpio18: Gpio18, + pub gpio19: Gpio19, + pub gpio20: Gpio20, + pub gpio21: Gpio21, + #[cfg(not(feature = "ulp"))] + pub gpio26: Gpio26, + #[cfg(not(feature = "ulp"))] + pub gpio33: Gpio33, + #[cfg(not(feature = "ulp"))] + pub gpio34: Gpio34, + #[cfg(not(feature = "ulp"))] + pub gpio35: Gpio35, + #[cfg(not(feature = "ulp"))] + pub gpio36: Gpio36, + #[cfg(not(feature = "ulp"))] + pub gpio37: Gpio37, + #[cfg(not(feature = "ulp"))] + pub gpio38: Gpio38, + #[cfg(not(feature = "ulp"))] + pub gpio39: Gpio39, + #[cfg(not(feature = "ulp"))] + pub gpio40: Gpio40, + #[cfg(not(feature = "ulp"))] + pub gpio41: Gpio41, + #[cfg(not(feature = "ulp"))] + pub gpio42: Gpio42, + #[cfg(not(feature = "ulp"))] + pub gpio43: Gpio43, + #[cfg(not(feature = "ulp"))] + pub gpio44: Gpio44, + #[cfg(not(feature = "ulp"))] + pub gpio45: Gpio45, + #[cfg(not(feature = "ulp"))] + pub gpio46: Gpio46, + } + + impl Pins { + pub unsafe fn new() -> Self { + Self { + gpio0: Gpio0::::new(), + gpio1: Gpio1::::new(), + gpio2: Gpio2::::new(), + gpio3: Gpio3::::new(), + gpio4: Gpio4::::new(), + gpio5: Gpio5::::new(), + gpio6: Gpio6::::new(), + gpio7: Gpio7::::new(), + gpio8: Gpio8::::new(), + gpio9: Gpio9::::new(), + gpio10: Gpio10::::new(), + gpio11: Gpio11::::new(), + gpio12: Gpio12::::new(), + gpio13: Gpio13::::new(), + gpio14: Gpio14::::new(), + gpio15: Gpio15::::new(), + gpio16: Gpio16::::new(), + gpio17: Gpio17::::new(), + gpio18: Gpio18::::new(), + gpio19: Gpio19::::new(), + gpio20: Gpio20::::new(), + gpio21: Gpio21::::new(), + #[cfg(not(feature = "ulp"))] + gpio26: Gpio26::::new(), + #[cfg(not(feature = "ulp"))] + gpio33: Gpio33::::new(), + #[cfg(not(feature = "ulp"))] + gpio34: Gpio34::::new(), + #[cfg(not(feature = "ulp"))] + gpio35: Gpio35::::new(), + #[cfg(not(feature = "ulp"))] + gpio36: Gpio36::::new(), + #[cfg(not(feature = "ulp"))] + gpio37: Gpio37::::new(), + #[cfg(not(feature = "ulp"))] + gpio38: Gpio38::::new(), + #[cfg(not(feature = "ulp"))] + gpio39: Gpio39::::new(), + #[cfg(not(feature = "ulp"))] + gpio40: Gpio40::::new(), + #[cfg(not(feature = "ulp"))] + gpio41: Gpio41::::new(), + #[cfg(not(feature = "ulp"))] + gpio42: Gpio42::::new(), + #[cfg(not(feature = "ulp"))] + gpio43: Gpio43::::new(), + #[cfg(not(feature = "ulp"))] + gpio44: Gpio44::::new(), + #[cfg(not(feature = "ulp"))] + gpio45: Gpio45::::new(), + #[cfg(not(feature = "ulp"))] + gpio46: Gpio46::::new(), + } + } + } +} + +#[cfg(esp32c3)] +#[cfg(not(feature = "ulp"))] +mod chip { + use { + core::marker::PhantomData, + embedded_hal::digital::v2::{OutputPin as _, StatefulOutputPin as _}, + }; + + #[cfg(not(feature = "ulp"))] + use esp_idf_sys::*; + + use super::*; + + // Not mapped: 11 - 17 + pin!(Gpio0:0, IO, RTC:0, ADC1:0, NODAC:0, TOUCH:0); + pin!(Gpio1:1, IO, RTC:1, ADC1:1, NODAC:0, TOUCH:1); + pin!(Gpio2:2, IO, RTC:2, ADC1:2, NODAC:0, TOUCH:2); + pin!(Gpio3:3, IO, RTC:3, ADC1:3, NODAC:0, TOUCH:3); + pin!(Gpio4:4, IO, RTC:4, ADC1:4, NODAC:0, TOUCH:4); + pin!(Gpio5:5, IO, RTC:5, ADC2:0, NODAC:0, TOUCH:5); + pin!(Gpio6:6, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio7:7, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio8:8, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio9:9, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio10:10, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio18:18, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio19:19, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio20:20, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + pin!(Gpio21:21, IO, NORTC:0, NOADC:0, NODAC:0, NOTOUCH:0); + + pub struct Pins { + pub gpio0: Gpio0, + pub gpio1: Gpio1, + pub gpio2: Gpio2, + pub gpio3: Gpio3, + pub gpio4: Gpio4, + pub gpio5: Gpio5, + pub gpio6: Gpio6, + pub gpio7: Gpio7, + pub gpio8: Gpio8, + pub gpio9: Gpio9, + pub gpio10: Gpio10, + pub gpio18: Gpio18, + pub gpio19: Gpio19, + pub gpio20: Gpio20, + pub gpio21: Gpio21, + } + + impl Pins { + pub unsafe fn new() -> Self { + Self { + gpio0: Gpio0::::new(), + gpio1: Gpio1::::new(), + gpio2: Gpio2::::new(), + gpio3: Gpio3::::new(), + gpio4: Gpio4::::new(), + gpio5: Gpio5::::new(), + gpio6: Gpio6::::new(), + gpio7: Gpio7::::new(), + gpio8: Gpio8::::new(), + gpio9: Gpio9::::new(), + gpio10: Gpio10::::new(), + gpio18: Gpio18::::new(), + gpio19: Gpio19::::new(), + gpio20: Gpio20::::new(), + gpio21: Gpio21::::new(), + } } } } diff --git a/src/lib.rs b/src/lib.rs index 58f05eecb..658a4bee4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,4 @@ #![feature(llvm_asm)] - #![cfg_attr(not(feature = "std"), no_std)] cfg_if::cfg_if! { @@ -8,7 +7,6 @@ cfg_if::cfg_if! { } } -#[cfg(feature = "ulp")] #[macro_use] pub mod ulp; #[cfg(not(feature = "ulp"))] diff --git a/src/peripherals.rs b/src/peripherals.rs index 9189ae4c5..5430efd9c 100644 --- a/src/peripherals.rs +++ b/src/peripherals.rs @@ -6,6 +6,7 @@ use esp_idf_sys::EspMutex; #[cfg(feature = "ulp")] use crate::ulp::sys::EspMutex; +#[cfg(any(not(esp32c3), not(feature = "ulp")))] use crate::gpio; #[cfg(not(feature = "ulp"))] use crate::i2c; @@ -15,12 +16,13 @@ use crate::serial; use crate::spi; pub struct Peripherals { + #[cfg(any(not(esp32c3), not(feature = "ulp")))] pub pins: gpio::Pins, #[cfg(not(feature = "ulp"))] pub uart0: serial::UART0, #[cfg(not(feature = "ulp"))] pub uart1: serial::UART1, - #[cfg(any(esp32, not(feature = "ulp")))] + #[cfg(all(esp32, not(feature = "ulp")))] pub uart2: serial::UART2, #[cfg(not(feature = "ulp"))] pub i2c0: i2c::I2C0, @@ -52,12 +54,13 @@ impl Peripherals { pub unsafe fn new() -> Self { Self { + #[cfg(any(not(esp32c3), not(feature = "ulp")))] pins: gpio::Pins::new(), #[cfg(not(feature = "ulp"))] uart0: serial::UART0::new(), #[cfg(not(feature = "ulp"))] uart1: serial::UART1::new(), - #[cfg(any(esp32, not(feature = "ulp")))] + #[cfg(all(esp32, not(feature = "ulp")))] uart2: serial::UART2::new(), #[cfg(not(feature = "ulp"))] i2c0: i2c::I2C0::new(), diff --git a/src/serial.rs b/src/serial.rs index ebf770daf..30b66f96f 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -256,8 +256,8 @@ pub struct Pins< TX: OutputPin, RX: InputPin, // default pins to allow type inference - CTS: InputPin = crate::gpio::Gpio19, - RTS: OutputPin = crate::gpio::Gpio22, + CTS: InputPin = crate::gpio::Gpio1, + RTS: OutputPin = crate::gpio::Gpio2, > { pub tx: TX, pub rx: RX, @@ -276,8 +276,8 @@ pub struct Serial< TX: OutputPin, RX: InputPin, // default pins to allow type inference - CTS: InputPin = crate::gpio::Gpio19, - RTS: OutputPin = crate::gpio::Gpio22, + CTS: InputPin = crate::gpio::Gpio1, + RTS: OutputPin = crate::gpio::Gpio2, > { uart: UART, pins: Pins, diff --git a/src/ulp.rs b/src/ulp.rs index de66252cc..3eedc4bd2 100644 --- a/src/ulp.rs +++ b/src/ulp.rs @@ -1,6 +1,35 @@ -mod reg; +#[cfg(feature = "ulp")] mod pac; +#[cfg(feature = "ulp")] +mod reg; +#[cfg(feature = "ulp")] #[macro_use] pub mod sys; +#[cfg(feature = "ulp")] pub mod delay; + +#[cfg(not(feature = "ulp"))] +#[cfg(any(esp32, esp32s2, esp32s3))] +pub fn enable_timer(enable: bool) { + use core::ptr::{read_volatile, write_volatile}; + + // TODO: Get rid of these hard-codings + const DR_REG_RTCCNTL_BASE: u32 = 0x3f408000; + const RTC_CNTL_STATE0_REG: u32 = DR_REG_RTCCNTL_BASE + 0x0018; + const RTC_CNTL_ULP_CP_SLP_TIMER_EN: u32 = 1 << 31; + + unsafe { + if enable { + write_volatile( + RTC_CNTL_STATE0_REG as *mut u32, + read_volatile(RTC_CNTL_STATE0_REG as *const u32) | RTC_CNTL_ULP_CP_SLP_TIMER_EN, + ); + } else { + write_volatile( + RTC_CNTL_STATE0_REG as *mut u32, + read_volatile(RTC_CNTL_STATE0_REG as *const u32) & !RTC_CNTL_ULP_CP_SLP_TIMER_EN, + ); + } + } +} diff --git a/src/ulp/delay.rs b/src/ulp/delay.rs index 335bd8fa4..705ef7003 100644 --- a/src/ulp/delay.rs +++ b/src/ulp/delay.rs @@ -2,7 +2,7 @@ use embedded_hal::blocking::delay::{DelayMs, DelayUs}; use super::sys::*; -/// ESP-IDF busy-loop based delay for the risc-v ULP coprocessor +/// Busy-loop based delay for the RiscV ULP coprocessor pub struct Ulp; impl DelayUs for Ulp { @@ -33,7 +33,5 @@ impl DelayMs for Ulp { fn delay_cycles(cycles: u32) { let start = get_ccount(); - while get_ccount() - start < cycles { - /* Wait */ - } + while get_ccount() - start < cycles { /* Wait */ } } diff --git a/src/ulp/pac.rs b/src/ulp/pac.rs index b4c3ccbb6..1284c4df9 100644 --- a/src/ulp/pac.rs +++ b/src/ulp/pac.rs @@ -4,7 +4,6 @@ /// - https://github.com/espressif/esp-idf/blob/master/components/soc/esp32s2/include/soc/soc.h (a subset) /// - https://github.com/espressif/esp-idf/blob/master/components/soc/esp32s2/include/soc/sens_reg.h (a subset) /// - https://github.com/espressif/esp-idf/blob/master/components/soc/esp32s2/include/soc/rtc_io_reg.h (a subset) - use super::reg::bit; pub const DR_REG_SENS_BASE: u32 = 0x3f408800; @@ -16,39 +15,52 @@ pub const RTC_CNTL_COCPU_DONE: u32 = bit(25); pub const RTC_CNTL_COCPU_SHUT_RESET_EN: u32 = bit(22); pub const RTC_CNTL_COCPU_SHUT_2_CLK_DIS: u32 = 0x000000FF; pub const RTC_CNTL_COCPU_SHUT_2_CLK_DIS_V: u32 = 0xFF; -pub const RTC_CNTL_SW_CPU_INT: u32 = bit(0); +pub const RTC_CNTL_COCPU_SHUT_2_CLK_DIS_S: u32 = 14; + pub const RTC_CNTL_STATE0_REG: u32 = DR_REG_RTCCNTL_BASE + 0x0018; +pub const RTC_CNTL_SW_CPU_INT: u32 = bit(0); +pub const RTC_CNTL_ULP_CP_SLP_TIMER_EN: u32 = bit(31); +pub const RTC_CNTL_ULP_CP_SLP_TIMER_EN_V: u32 = 0x1; +pub const RTC_CNTL_ULP_CP_SLP_TIMER_EN_S: u32 = 31; pub const SENS_SAR_IO_MUX_CONF_REG: u32 = DR_REG_SENS_BASE + 0x0144; pub const SENS_IOMUX_CLK_GATE_EN_M: u32 = bit(31); -pub const RTC_IO_TOUCH_PAD0_REG: u32 = DR_REG_RTCIO_BASE + 0x94; +pub const RTC_IO_TOUCH_PAD0_REG: u32 = DR_REG_RTCIO_BASE + 0x84; pub const RTC_IO_TOUCH_PAD0_DRV: u32 = 0x00000003; pub const RTC_IO_TOUCH_PAD0_DRV_V: u32 = 0x3; +pub const RTC_IO_TOUCH_PAD0_DRV_S: u32 = 29; pub const RTC_IO_TOUCH_PAD0_MUX_SEL: u32 = bit(19); pub const RTC_IO_TOUCH_PAD0_FUN_SEL: u32 = 0x00000003; pub const RTC_IO_TOUCH_PAD0_FUN_SEL_V: u32 = 0x3; +pub const RTC_IO_TOUCH_PAD0_FUN_SEL_S: u32 = 17; pub const RTC_IO_TOUCH_PAD0_FUN_IE: u32 = bit(13); pub const RTC_IO_TOUCH_PAD0_FUN_IE_V: u32 = 0x01; +pub const RTC_IO_TOUCH_PAD0_FUN_IE_S: u32 = 13; pub const RTC_IO_TOUCH_PAD0_RUE: u32 = bit(27); pub const RTC_IO_TOUCH_PAD0_RDE: u32 = bit(28); pub const RTC_GPIO_ENABLE_W1TS_REG: u32 = DR_REG_RTCIO_BASE + 0x10; pub const RTC_GPIO_ENABLE_W1TS: u32 = 0x0003FFFF; pub const RTC_GPIO_ENABLE_W1TS_V: u32 = 0x3FFFF; +pub const RTC_GPIO_ENABLE_W1TS_S: u32 = 10; pub const RTC_GPIO_ENABLE_W1TC_REG: u32 = DR_REG_RTCIO_BASE + 0x14; pub const RTC_GPIO_ENABLE_W1TC: u32 = 0x0003FFFF; pub const RTC_GPIO_ENABLE_W1TC_V: u32 = 0x3FFFF; +pub const RTC_GPIO_ENABLE_W1TC_S: u32 = 10; pub const RTC_GPIO_IN_REG: u32 = DR_REG_RTCIO_BASE + 0x24; pub const RTC_GPIO_IN_NEXT: u32 = 0x0003FFFF; pub const RTC_GPIO_IN_NEXT_V: u32 = 0x3FFFF; +pub const RTC_GPIO_IN_NEXT_S: u32 = 10; pub const RTC_GPIO_OUT_W1TS_REG: u32 = DR_REG_RTCIO_BASE + 0x4; pub const RTC_GPIO_OUT_DATA_W1TS: u32 = 0x0003FFFF; pub const RTC_GPIO_OUT_DATA_W1TS_V: u32 = 0x3FFFF; +pub const RTC_GPIO_OUT_DATA_W1TS_S: u32 = 10; pub const RTC_GPIO_OUT_W1TC_REG: u32 = DR_REG_RTCIO_BASE + 0x8; pub const RTC_GPIO_OUT_DATA_W1TC: u32 = 0x0003FFFF; pub const RTC_GPIO_OUT_DATA_W1TC_V: u32 = 0x3FFFF; +pub const RTC_GPIO_OUT_DATA_W1TC_S: u32 = 10; diff --git a/src/ulp/reg.rs b/src/ulp/reg.rs index 3651c7f13..b37efffdb 100644 --- a/src/ulp/reg.rs +++ b/src/ulp/reg.rs @@ -2,30 +2,29 @@ /// This module is a manual translation of the following C file from current ESP-IDF master: /// - https://github.com/espressif/esp-idf/blob/master/components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_register_ops.h - use core::ptr::{read_volatile, write_volatile}; /* * When COCPU accesses the RTC register, it needs to convert the access address. * When COCPU accesses the RTC memory, dont need to convert the access address. */ - #[inline(always)] - pub unsafe fn write_rtc_mem(addr: u32, val: i32) { - write_volatile(addr as *mut i32, val); - } +#[inline(always)] +pub unsafe fn write_rtc_mem(addr: u32, val: i32) { + write_volatile(addr as *mut i32, val); +} - #[inline(always)] - pub unsafe fn read_rtc_mem(addr: u32) -> i32 { - read_volatile(addr as *const i32) - } +#[inline(always)] +pub unsafe fn read_rtc_mem(addr: u32) -> i32 { + read_volatile(addr as *const i32) +} - /* - * When COCPU accesses the RTC register, it needs to convert the access address. - * When COCPU accesses the RTC memory, dont need to convert the access address. - */ +/* + * When COCPU accesses the RTC register, it needs to convert the access address. + * When COCPU accesses the RTC memory, dont need to convert the access address. + */ #[inline(always)] pub const fn riscv_reg_conv(addr: u32) -> u32 { - ((addr & 0xffff) << 3 & 0xe000) | addr & 0x1fff | 0x8000 + ((addr & 0xffff) << 3) & 0xe000 | addr & 0x1fff | 0x8000 } #[inline(always)] @@ -67,14 +66,14 @@ pub unsafe fn reg_set_bit(r: u32, b: u32) { #[inline(always)] pub unsafe fn reg_clr_bit(r: u32, b: u32) { let addr = riscv_reg_conv(r) as *mut u32; - write_volatile(addr, read_volatile(addr) & (!b)); + write_volatile(addr, read_volatile(addr) & !b); } // Set bits of register controlled by mask #[inline(always)] pub unsafe fn reg_set_bits(r: u32, b: u32, m: u32) { let addr = riscv_reg_conv(r) as *mut u32; - write_volatile(addr, read_volatile(addr) & (!m) | b & m); + write_volatile(addr, read_volatile(addr) & !m | b & m); } // Get field from register, uses field _S & _V to determine mask @@ -162,7 +161,10 @@ pub unsafe fn get_peri_reg_bits(addr: u32, bit_map: u32, shift: u8) -> u32 { // Set bits of register controlled by mask and shift pub unsafe fn set_peri_reg_bits(addr: u32, bit_map: u32, value: u32, shift: u8) { - write_peri_reg(addr, read_peri_reg(addr) & !(bit_map << shift) | ((value & bit_map) << shift)); + write_peri_reg( + addr, + read_peri_reg(addr) & !(bit_map << shift) | ((value & bit_map) << shift), + ); } // Get field of register diff --git a/src/ulp/sys.rs b/src/ulp/sys.rs index b2be7d144..16138138c 100644 --- a/src/ulp/sys.rs +++ b/src/ulp/sys.rs @@ -1,6 +1,5 @@ /// A mini "esp-idf-ulp-sys" module exposing stuff on top of which the ULP HAL support is implemented /// (currently, only GPIO) + some utilities for the riscv ULP processor - use mutex_trait::*; pub use self::cpu::*; diff --git a/src/ulp/sys/cpu.rs b/src/ulp/sys/cpu.rs index 5ffa7497b..b4f400a1d 100644 --- a/src/ulp/sys/cpu.rs +++ b/src/ulp/sys/cpu.rs @@ -4,12 +4,13 @@ /// - https://github.com/espressif/esp-idf/blob/master/components/ulp/ulp_riscv/include/ulp_riscv/ulp_utils.h /// - https://github.com/espressif/esp-idf/blob/master/components/ulp/ulp_riscv/ulp_utils.c -pub const ULP_RISCV_CYCLES_PER_US_NUM: u32 = 80; -pub const ULP_RISCV_CYCLES_PER_US_DENUM: u32 = 5; -pub const ULP_RISCV_CYCLES_PER_MS: u32 = ULP_RISCV_CYCLES_PER_US_NUM * (1000 / ULP_RISCV_CYCLES_PER_US_DENUM); +pub const ULP_RISCV_CYCLES_PER_US_NUM: u32 = 85; +pub const ULP_RISCV_CYCLES_PER_US_DENUM: u32 = 10; +pub const ULP_RISCV_CYCLES_PER_MS: u32 = + ULP_RISCV_CYCLES_PER_US_NUM * (1000 / ULP_RISCV_CYCLES_PER_US_DENUM); -use crate::ulp::reg::*; use crate::ulp::pac::*; +use crate::ulp::reg::*; #[inline(always)] pub fn get_ccount() -> u32 { @@ -23,24 +24,46 @@ pub fn get_ccount() -> u32 { ccount } -pub unsafe fn wakeup_main_processor() { - set_peri_reg_mask(RTC_CNTL_STATE0_REG, RTC_CNTL_SW_CPU_INT); +pub fn wakeup_main_processor() { + unsafe { set_peri_reg_mask(RTC_CNTL_STATE0_REG, RTC_CNTL_SW_CPU_INT) }; } -pub unsafe fn rescue_from_monitor() { +pub fn rescue_from_monitor() { // Rescue RISCV from monitor state - clear_peri_reg_mask(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_DONE | RTC_CNTL_COCPU_SHUT_RESET_EN); + unsafe { + clear_peri_reg_mask( + RTC_CNTL_COCPU_CTRL_REG, + RTC_CNTL_COCPU_DONE | RTC_CNTL_COCPU_SHUT_RESET_EN, + ) + }; } -pub unsafe fn shutdown() -> ! { - // Setting the delay time after RISCV recv `DONE` signal, Ensure that action `RESET` can be executed in time. - reg_set_field(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_2_CLK_DIS, RTC_CNTL_COCPU_SHUT_2_CLK_DIS_V, 0x3F); - - // Suspends the ulp operation - set_peri_reg_mask(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_DONE); - - // Resets the processor - set_peri_reg_mask(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN); - - loop { } +pub fn enable_timer(enable: bool) { + unsafe { + if enable { + set_peri_reg_mask(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); + } else { + clear_peri_reg_mask(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); + } + } +} + +pub fn shutdown() -> ! { + unsafe { + // Setting the delay time after RISCV recv `DONE` signal, Ensure that action `RESET` can be executed in time. + reg_set_field( + RTC_CNTL_COCPU_CTRL_REG, + RTC_CNTL_COCPU_SHUT_2_CLK_DIS_S, + RTC_CNTL_COCPU_SHUT_2_CLK_DIS_V, + 0x3F, + ); + + // Suspends the ulp operation + set_peri_reg_mask(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_DONE); + + // Resets the processor + set_peri_reg_mask(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN); + } + + loop {} } diff --git a/src/ulp/sys/gpio.rs b/src/ulp/sys/gpio.rs index 3f9cfca29..80153e19f 100644 --- a/src/ulp/sys/gpio.rs +++ b/src/ulp/sys/gpio.rs @@ -1,10 +1,9 @@ +use crate::ulp::pac::*; /// A mini "esp-idf-ulp-sys" module exposing stuff on top of which the ULP HAL support is implemented /// (currently, only GPIO) /// Implemented as a manual transation of a few C fiels from current ESP-IDF S2 master: /// - https://github.com/espressif/esp-idf/blob/master/components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_gpio.h - use crate::ulp::reg::*; -use crate::ulp::pac::*; #[allow(non_camel_case_types)] pub type adc_unit_t = i32; @@ -46,54 +45,109 @@ pub const gpio_pull_mode_t_GPIO_FLOATING: u8 = 3; pub unsafe fn gpio_set_direction(gpio_num: i32, direction: u8) { if direction == gpio_mode_t_GPIO_MODE_DISABLE { // Deinit - clear_peri_reg_mask(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_MUX_SEL); + clear_peri_reg_mask( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_MUX_SEL, + ); return; } else { // Init set_peri_reg_mask(SENS_SAR_IO_MUX_CONF_REG, SENS_IOMUX_CLK_GATE_EN_M); - set_peri_reg_mask(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_MUX_SEL); - reg_set_field(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_FUN_SEL, RTC_IO_TOUCH_PAD0_FUN_SEL_V, 0); + set_peri_reg_mask( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_MUX_SEL, + ); + reg_set_field( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_FUN_SEL_S, + RTC_IO_TOUCH_PAD0_FUN_SEL_V, + 0, + ); } - let input = direction == gpio_mode_t_GPIO_MODE_INPUT || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD; - let output = direction == gpio_mode_t_GPIO_MODE_OUTPUT || direction == gpio_mode_t_GPIO_MODE_OUTPUT_OD || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD; - let od = direction == gpio_mode_t_GPIO_MODE_OUTPUT_OD || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD; + let input = direction == gpio_mode_t_GPIO_MODE_INPUT + || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT + || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD; + let output = direction == gpio_mode_t_GPIO_MODE_OUTPUT + || direction == gpio_mode_t_GPIO_MODE_OUTPUT_OD + || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT + || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD; + let od = direction == gpio_mode_t_GPIO_MODE_OUTPUT_OD + || direction == gpio_mode_t_GPIO_MODE_INPUT_OUTPUT_OD; if input { - set_peri_reg_mask(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_FUN_IE); + set_peri_reg_mask( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_FUN_IE, + ); } else { - clear_peri_reg_mask(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_FUN_IE); + clear_peri_reg_mask( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_FUN_IE, + ); } if output { - reg_set_field(RTC_GPIO_ENABLE_W1TS_REG, RTC_GPIO_ENABLE_W1TS, RTC_GPIO_ENABLE_W1TS_V, bit(gpio_num as u32)); - reg_set_field(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_DRV, RTC_IO_TOUCH_PAD0_DRV_V, if od { 1 } else { 0 }); + reg_set_field( + RTC_GPIO_ENABLE_W1TS_REG, + RTC_GPIO_ENABLE_W1TS_S, + RTC_GPIO_ENABLE_W1TS_V, + bit(gpio_num as u32), + ); + reg_set_field( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_DRV_S, + RTC_IO_TOUCH_PAD0_DRV_V, + if od { 1 } else { 0 }, + ); } else { - reg_set_field(RTC_GPIO_ENABLE_W1TC_REG, RTC_GPIO_ENABLE_W1TC, RTC_GPIO_ENABLE_W1TC_V, bit(gpio_num as u32)); + reg_set_field( + RTC_GPIO_ENABLE_W1TC_REG, + RTC_GPIO_ENABLE_W1TC_S, + RTC_GPIO_ENABLE_W1TC_V, + bit(gpio_num as u32), + ); } } #[inline(always)] pub unsafe fn gpio_set_pull_mode(gpio_num: i32, mode: u8) { - let pullup = mode == gpio_pull_mode_t_GPIO_PULLUP_ONLY || mode == gpio_pull_mode_t_GPIO_PULLUP_PULLDOWN; - let pulldown = mode == gpio_pull_mode_t_GPIO_PULLDOWN_ONLY || mode == gpio_pull_mode_t_GPIO_PULLUP_PULLDOWN; + let pullup = + mode == gpio_pull_mode_t_GPIO_PULLUP_ONLY || mode == gpio_pull_mode_t_GPIO_PULLUP_PULLDOWN; + let pulldown = mode == gpio_pull_mode_t_GPIO_PULLDOWN_ONLY + || mode == gpio_pull_mode_t_GPIO_PULLUP_PULLDOWN; if pullup { - set_peri_reg_mask(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_RUE); + set_peri_reg_mask( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_RUE, + ); } else { - clear_peri_reg_mask(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_RUE); + clear_peri_reg_mask( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_RUE, + ); } if pulldown { - set_peri_reg_mask(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_RDE); + set_peri_reg_mask( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_RDE, + ); } else { - clear_peri_reg_mask(RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, RTC_IO_TOUCH_PAD0_RDE); + clear_peri_reg_mask( + RTC_IO_TOUCH_PAD0_REG + gpio_num as u32 * 4, + RTC_IO_TOUCH_PAD0_RDE, + ); } } #[inline(always)] pub unsafe fn gpio_get_level(gpio_num: i32) -> u8 { - if (reg_get_field(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT, RTC_GPIO_IN_NEXT_V) & bit(gpio_num as u32)) != 0 { + if (reg_get_field(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S, RTC_GPIO_IN_NEXT_V) + & bit(gpio_num as u32)) + != 0 + { 1 } else { 0 @@ -103,8 +157,18 @@ pub unsafe fn gpio_get_level(gpio_num: i32) -> u8 { #[inline(always)] pub unsafe fn gpio_set_level(gpio_num: i32, level: u8) { if level != 0 { - reg_set_field(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS, RTC_GPIO_OUT_DATA_W1TS_V, bit(gpio_num as u32)); + reg_set_field( + RTC_GPIO_OUT_W1TS_REG, + RTC_GPIO_OUT_DATA_W1TS_S, + RTC_GPIO_OUT_DATA_W1TS_V, + bit(gpio_num as u32), + ); } else { - reg_set_field(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC, RTC_GPIO_OUT_DATA_W1TC_V, bit(gpio_num as u32)); + reg_set_field( + RTC_GPIO_OUT_W1TC_REG, + RTC_GPIO_OUT_DATA_W1TC_S, + RTC_GPIO_OUT_DATA_W1TC_V, + bit(gpio_num as u32), + ); } }