diff --git a/esp-hal/CHANGELOG.md b/esp-hal/CHANGELOG.md index c5f2adbbde8..be4bfcbabd7 100644 --- a/esp-hal/CHANGELOG.md +++ b/esp-hal/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixing `esp-wifi` + `TRNG` issue on `ESP32-S2` (#1272) - Fixed core1 startup using the wrong stack on the esp32 and esp32s3 (#1286). - Fixed LCD_CAM i8080 potentially sending garbage to display (#1301) +- ESP32: Apply fix for Errata 3.6 in all the places necessary. (#1315) ### Changed diff --git a/esp-hal/src/gpio.rs b/esp-hal/src/gpio.rs index 41c04026562..c0b3b425b85 100644 --- a/esp-hal/src/gpio.rs +++ b/esp-hal/src/gpio.rs @@ -622,7 +622,7 @@ where .modify(|_, w| unsafe { w.out_sel().bits(OutputSignal::GPIO as OutputSignalType) }); #[cfg(esp32)] - crate::soc::gpio::errata36(GPIONUM, pull_up, pull_down); + crate::soc::gpio::errata36(GPIONUM, Some(pull_up), Some(pull_down)); // NOTE: Workaround to make GPIO18 and GPIO19 work on the ESP32-C3, which by // default are assigned to the `USB_SERIAL_JTAG` peripheral. @@ -1139,6 +1139,9 @@ where fn init_output(&self, alternate: AlternateFunction, open_drain: bool) { let gpio = unsafe { &*GPIO::PTR }; + #[cfg(esp32)] + crate::soc::gpio::errata36(GPIONUM, Some(false), Some(false)); + ::Bank::write_out_en_set(1 << (GPIONUM % 32)); gpio.pin(GPIONUM as usize) .modify(|_, w| w.pad_driver().bit(open_drain)); @@ -1277,10 +1280,16 @@ where } fn internal_pull_up(&mut self, on: bool) -> &mut Self { + #[cfg(esp32)] + crate::soc::gpio::errata36(GPIONUM, Some(on), None); + get_io_mux_reg(GPIONUM).modify(|_, w| w.fun_wpu().bit(on)); self } fn internal_pull_down(&mut self, on: bool) -> &mut Self { + #[cfg(esp32)] + crate::soc::gpio::errata36(GPIONUM, None, Some(on)); + get_io_mux_reg(GPIONUM).modify(|_, w| w.fun_wpd().bit(on)); self } diff --git a/esp-hal/src/soc/esp32/gpio.rs b/esp-hal/src/soc/esp32/gpio.rs index d3bb31044ce..eda75aa89d3 100644 --- a/esp-hal/src/soc/esp32/gpio.rs +++ b/esp-hal/src/soc/esp32/gpio.rs @@ -619,85 +619,141 @@ pub enum OutputSignal { MTDO, } -pub(crate) fn errata36(pin_num: u8, pull_up: bool, pull_down: bool) { +pub(crate) fn errata36(pin_num: u8, pull_up: Option, pull_down: Option) { use crate::peripherals::RTC_IO; let rtcio = unsafe { &*RTC_IO::PTR }; match pin_num { 0 => { - rtcio - .touch_pad1() - .modify(|r, w| unsafe { w.bits(r.bits()).rue().bit(pull_up).rde().bit(pull_down) }); + rtcio.touch_pad1().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.rde().bit(pull_down); + } + w + }); } 2 => { - rtcio - .touch_pad2() - .modify(|r, w| unsafe { w.bits(r.bits()).rue().bit(pull_up).rde().bit(pull_down) }); + rtcio.touch_pad2().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.rde().bit(pull_down); + } + w + }); } 4 => { - rtcio - .touch_pad0() - .modify(|r, w| unsafe { w.bits(r.bits()).rue().bit(pull_up).rde().bit(pull_down) }); + rtcio.touch_pad0().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.rde().bit(pull_down); + } + w + }); } 12 => { - rtcio - .touch_pad5() - .modify(|r, w| unsafe { w.bits(r.bits()).rue().bit(pull_up).rde().bit(pull_down) }); + rtcio.touch_pad5().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.rde().bit(pull_down); + } + w + }); } 13 => { - rtcio - .touch_pad4() - .modify(|r, w| unsafe { w.bits(r.bits()).rue().bit(pull_up).rde().bit(pull_down) }); + rtcio.touch_pad4().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.rde().bit(pull_down); + } + w + }); } 14 => { - rtcio - .touch_pad6() - .modify(|r, w| unsafe { w.bits(r.bits()).rue().bit(pull_up).rde().bit(pull_down) }); + rtcio.touch_pad6().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.rde().bit(pull_down); + } + w + }); } 15 => { - rtcio - .touch_pad3() - .modify(|r, w| unsafe { w.bits(r.bits()).rue().bit(pull_up).rde().bit(pull_down) }); + rtcio.touch_pad3().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.rde().bit(pull_down); + } + w + }); } 25 => { - rtcio.pad_dac1().modify(|r, w| unsafe { - w.bits(r.bits()) - .pdac1_rue() - .bit(pull_up) - .pdac1_rde() - .bit(pull_down) + rtcio.pad_dac1().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.pdac1_rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.pdac1_rde().bit(pull_down); + } + w }); } 26 => { - rtcio.pad_dac2().modify(|r, w| unsafe { - w.bits(r.bits()) - .pdac2_rue() - .bit(pull_up) - .pdac2_rde() - .bit(pull_down) + rtcio.pad_dac2().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.pdac2_rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.pdac2_rde().bit(pull_down); + } + w }); } 27 => { - rtcio - .touch_pad7() - .modify(|r, w| unsafe { w.bits(r.bits()).rue().bit(pull_up).rde().bit(pull_down) }); + rtcio.touch_pad7().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.rde().bit(pull_down); + } + w + }); } 32 => { - rtcio.xtal_32k_pad().modify(|r, w| unsafe { - w.bits(r.bits()) - .x32p_rue() - .bit(pull_up) - .x32p_rde() - .bit(pull_down) + rtcio.xtal_32k_pad().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.x32p_rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.x32p_rde().bit(pull_down); + } + w }); } 33 => { - rtcio.xtal_32k_pad().modify(|r, w| unsafe { - w.bits(r.bits()) - .x32n_rue() - .bit(pull_up) - .x32n_rde() - .bit(pull_down) + rtcio.xtal_32k_pad().modify(|_, w| { + if let Some(pull_up) = pull_up { + w.x32n_rue().bit(pull_up); + } + if let Some(pull_down) = pull_down { + w.x32n_rde().bit(pull_down); + } + w }); } _ => (),