From e72276807f8e063469ca1121491c50b5fde70a6f Mon Sep 17 00:00:00 2001 From: bjoernQ Date: Tue, 27 Feb 2024 15:51:11 +0100 Subject: [PATCH 1/5] UART init for all chips --- esp-hal/src/system.rs | 396 ++++++++++++++++++++++++++++++++++++++++++ esp-hal/src/uart.rs | 52 ++++-- 2 files changed, 431 insertions(+), 17 deletions(-) diff --git a/esp-hal/src/system.rs b/esp-hal/src/system.rs index b338e82255c..8f5f9f41e2d 100755 --- a/esp-hal/src/system.rs +++ b/esp-hal/src/system.rs @@ -393,6 +393,210 @@ impl PeripheralClockControl { } }); } + + /// Resets the given peripheral + pub(crate) fn reset(peripheral: Peripheral) { + let system = unsafe { &*SYSTEM::PTR }; + + #[cfg(esp32)] + let (perip_rst_en0, peri_rst_en) = { (&system.perip_rst_en(), &system.peri_rst_en()) }; + #[cfg(not(any(esp32, esp32p4)))] + let perip_rst_en0 = { &system.perip_rst_en0() }; + + #[cfg(any(esp32c2, esp32c3, esp32s2, esp32s3))] + let perip_rst_en1 = { &system.perip_rst_en1() }; + + critical_section::with(|_cs| match peripheral { + #[cfg(spi2)] + Peripheral::Spi2 => { + perip_rst_en0.modify(|_, w| w.spi2_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.spi2_rst().clear_bit()); + } + #[cfg(spi3)] + Peripheral::Spi3 => { + perip_rst_en0.modify(|_, w| w.spi3_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.spi3_rst().clear_bit()); + } + #[cfg(all(i2c0, esp32))] + Peripheral::I2cExt0 => { + perip_rst_en0.modify(|_, w| w.i2c0_ext0_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.i2c0_ext0_rst().clear_bit()); + } + #[cfg(all(i2c0, not(esp32)))] + Peripheral::I2cExt0 => { + perip_rst_en0.modify(|_, w| w.i2c_ext0_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.i2c_ext0_rst().clear_bit()); + } + #[cfg(i2c1)] + Peripheral::I2cExt1 => { + perip_rst_en0.modify(|_, w| w.i2c_ext1_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.i2c_ext1_rst().clear_bit()); + } + #[cfg(rmt)] + Peripheral::Rmt => { + perip_rst_en0.modify(|_, w| w.rmt_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.rmt_rst().clear_bit()); + } + #[cfg(ledc)] + Peripheral::Ledc => { + perip_rst_en0.modify(|_, w| w.ledc_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.ledc_rst().clear_bit()); + } + #[cfg(mcpwm0)] + Peripheral::Mcpwm0 => { + perip_rst_en0.modify(|_, w| w.pwm0_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.pwm0_rst().clear_bit()); + } + #[cfg(mcpwm1)] + Peripheral::Mcpwm1 => { + perip_rst_en0.modify(|_, w| w.pwm1_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.pwm1_rst().clear_bit()); + } + #[cfg(pcnt)] + Peripheral::Pcnt => { + perip_rst_en0.modify(|_, w| w.pcnt_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.pcnt_rst().clear_bit()); + } + #[cfg(apb_saradc)] + Peripheral::ApbSarAdc => { + perip_rst_en0.modify(|_, w| w.apb_saradc_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.apb_saradc_rst().clear_bit()); + } + #[cfg(gdma)] + Peripheral::Gdma => { + perip_rst_en1.modify(|_, w| w.dma_rst().set_bit()); + perip_rst_en1.modify(|_, w| w.dma_rst().clear_bit()); + } + #[cfg(esp32)] + Peripheral::Dma => { + perip_rst_en0.modify(|_, w| w.spi_dma_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.spi_dma_rst().clear_bit()); + } + #[cfg(esp32s2)] + Peripheral::Dma => { + perip_rst_en0.modify(|_, w| w.spi2_dma_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.spi2_dma_rst().clear_bit()); + perip_rst_en0.modify(|_, w| w.spi3_dma_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.spi3_dma_rst().clear_bit()); + } + #[cfg(esp32c3)] + Peripheral::I2s0 => { + // on ESP32-C3 note that i2s1_clk_en / rst is really I2s0 + perip_rst_en0.modify(|_, w| w.i2s1_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit()); + } + #[cfg(any(esp32s3, esp32, esp32s2))] + Peripheral::I2s0 => { + perip_rst_en0.modify(|_, w| w.i2s0_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.i2s0_rst().clear_bit()); + } + #[cfg(any(esp32s3, esp32))] + Peripheral::I2s1 => { + perip_rst_en0.modify(|_, w| w.i2s1_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.i2s1_rst().clear_bit()); + } + #[cfg(usb0)] + Peripheral::Usb => { + perip_rst_en0.modify(|_, w| w.usb_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.usb_rst().clear_bit()); + } + #[cfg(twai0)] + Peripheral::Twai0 => { + perip_rst_en0.modify(|_, w| w.twai_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.twai_rst().clear_bit()); + } + #[cfg(esp32)] + Peripheral::Aes => { + peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() | 1) }); + peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & (!1)) }); + } + #[cfg(any(esp32c3, esp32s2, esp32s3))] + Peripheral::Aes => { + perip_rst_en1.modify(|_, w| w.crypto_aes_rst().set_bit()); + perip_rst_en1.modify(|_, w| w.crypto_aes_rst().clear_bit()); + } + #[cfg(timg0)] + Peripheral::Timg0 => { + #[cfg(any(esp32c3, esp32s2, esp32s3))] + perip_rst_en0.modify(|_, w| w.timers_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.timergroup_rst().set_bit()); + #[cfg(any(esp32c3, esp32s2, esp32s3))] + perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit()); + perip_rst_en0.modify(|_, w| w.timergroup_rst().clear_bit()); + } + #[cfg(timg1)] + Peripheral::Timg1 => { + #[cfg(any(esp32c3, esp32s2, esp32s3))] + perip_rst_en0.modify(|_, w| w.timers_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.timergroup1_rst().set_bit()); + #[cfg(any(esp32c3, esp32s2, esp32s3))] + perip_rst_en0.modify(|_, w| w.timers_rst().clear_bit()); + perip_rst_en0.modify(|_, w| w.timergroup1_rst().clear_bit()); + } + #[cfg(sha)] + Peripheral::Sha => { + #[cfg(not(esp32))] + perip_rst_en1.modify(|_, w| w.crypto_sha_rst().set_bit()); + #[cfg(not(esp32))] + perip_rst_en1.modify(|_, w| w.crypto_sha_rst().clear_bit()); + } + #[cfg(esp32c3)] + Peripheral::UsbDevice => { + perip_rst_en0.modify(|_, w| w.usb_device_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.usb_device_rst().clear_bit()); + } + #[cfg(esp32s3)] + Peripheral::UsbDevice => { + perip_rst_en1.modify(|_, w| w.usb_device_rst().set_bit()); + perip_rst_en1.modify(|_, w| w.usb_device_rst().clear_bit()); + } + #[cfg(uart0)] + Peripheral::Uart0 => { + perip_rst_en0.modify(|_, w| w.uart_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.uart_rst().clear_bit()); + } + #[cfg(uart1)] + Peripheral::Uart1 => { + perip_rst_en0.modify(|_, w| w.uart1_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.uart1_rst().clear_bit()); + } + #[cfg(all(uart2, esp32s3))] + Peripheral::Uart2 => { + perip_rst_en1.modify(|_, w| w.uart2_rst().set_bit()); + perip_rst_en1.modify(|_, w| w.uart2_rst().clear_bit()); + } + #[cfg(all(uart2, esp32))] + Peripheral::Uart2 => { + perip_rst_en0.modify(|_, w| w.uart2_rst().set_bit()); + perip_rst_en0.modify(|_, w| w.uart2_rst().clear_bit()); + } + #[cfg(all(rsa, esp32))] + Peripheral::Rsa => { + peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() | 1 << 2) }); + peri_rst_en.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << 2)) }); + } + #[cfg(all(rsa, any(esp32c3, esp32s2, esp32s3)))] + Peripheral::Rsa => { + perip_rst_en1.modify(|_, w| w.crypto_rsa_rst().set_bit()); + perip_rst_en1.modify(|_, w| w.crypto_rsa_rst().clear_bit()); + } + #[cfg(hmac)] + Peripheral::Hmac => { + perip_rst_en1.modify(|_, w| w.crypto_hmac_rst().set_bit()); + perip_rst_en1.modify(|_, w| w.crypto_hmac_rst().clear_bit()); + } + #[cfg(ecc)] + Peripheral::Ecc => { + perip_rst_en1.modify(|_, w| w.crypto_ecc_rst().set_bit()); + perip_rst_en1.modify(|_, w| w.crypto_ecc_rst().clear_bit()); + } + #[cfg(lcd_cam)] + Peripheral::LcdCam => { + perip_rst_en1.modify(|_, w| w.lcd_cam_rst().set_bit()); + perip_rst_en1.modify(|_, w| w.lcd_cam_rst().clear_bit()); + } + }); + } } #[cfg(any(esp32c6, esp32h2))] @@ -603,6 +807,198 @@ impl PeripheralClockControl { } } } + + /// Resets the given peripheral + pub(crate) fn reset(peripheral: Peripheral) { + let system = unsafe { &*SYSTEM::PTR }; + + match peripheral { + #[cfg(spi2)] + Peripheral::Spi2 => { + system.spi2_conf().modify(|_, w| w.spi2_rst_en().set_bit()); + system + .spi2_conf() + .modify(|_, w| w.spi2_rst_en().clear_bit()); + } + #[cfg(i2c0)] + Peripheral::I2cExt0 => { + #[cfg(any(esp32c6, esp32h2))] + { + system.i2c0_conf().modify(|_, w| w.i2c0_rst_en().set_bit()); + system + .i2c0_conf() + .modify(|_, w| w.i2c0_rst_en().clear_bit()); + } + } + #[cfg(i2c1)] + Peripheral::I2cExt1 => { + #[cfg(esp32h2)] + { + system.i2c1_conf().modify(|_, w| w.i2c1_rst_en().set_bit()); + system + .i2c1_conf() + .modify(|_, w| w.i2c1_rst_en().clear_bit()); + } + } + #[cfg(rmt)] + Peripheral::Rmt => { + system.rmt_conf().modify(|_, w| w.rmt_rst_en().set_bit()); + system.rmt_conf().modify(|_, w| w.rmt_rst_en().clear_bit()); + } + #[cfg(ledc)] + Peripheral::Ledc => { + system.ledc_conf().modify(|_, w| w.ledc_rst_en().set_bit()); + system + .ledc_conf() + .modify(|_, w| w.ledc_rst_en().clear_bit()); + } + #[cfg(mcpwm0)] + Peripheral::Mcpwm0 => { + system.pwm_conf().modify(|_, w| w.pwm_rst_en().set_bit()); + system.pwm_conf().modify(|_, w| w.pwm_rst_en().clear_bit()); + } + #[cfg(mcpwm1)] + Peripheral::Mcpwm1 => { + system.pwm_conf.modify(|_, w| w.pwm_rst_en().set_bit()); + system.pwm_conf.modify(|_, w| w.pwm_rst_en().clear_bit()); + } + #[cfg(apb_saradc)] + Peripheral::ApbSarAdc => { + system + .saradc_conf() + .modify(|_, w| w.saradc_reg_rst_en().set_bit()); + system + .saradc_conf() + .modify(|_, w| w.saradc_reg_rst_en().clear_bit()); + } + #[cfg(gdma)] + Peripheral::Gdma => { + system.gdma_conf().modify(|_, w| w.gdma_rst_en().set_bit()); + system + .gdma_conf() + .modify(|_, w| w.gdma_rst_en().clear_bit()); + } + #[cfg(i2s0)] + Peripheral::I2s0 => { + system.i2s_conf().modify(|_, w| w.i2s_rst_en().set_bit()); + system.i2s_conf().modify(|_, w| w.i2s_rst_en().clear_bit()); + } + #[cfg(twai0)] + Peripheral::Twai0 => { + system + .twai0_conf() + .modify(|_, w| w.twai0_rst_en().set_bit()); + system + .twai0_conf() + .modify(|_, w| w.twai0_rst_en().clear_bit()); + } + #[cfg(twai1)] + Peripheral::Twai1 => { + system + .twai1_conf() + .modify(|_, w| w.twai1_rst_en().set_bit()); + system + .twai1_conf() + .modify(|_, w| w.twai1_rst_en().clear_bit()); + } + #[cfg(aes)] + Peripheral::Aes => { + system.aes_conf().modify(|_, w| w.aes_rst_en().set_bit()); + system.aes_conf().modify(|_, w| w.aes_rst_en().clear_bit()); + } + #[cfg(pcnt)] + Peripheral::Pcnt => { + system.pcnt_conf().modify(|_, w| w.pcnt_rst_en().set_bit()); + system + .pcnt_conf() + .modify(|_, w| w.pcnt_rst_en().clear_bit()); + } + #[cfg(timg0)] + Peripheral::Timg0 => { + // no reset? + } + #[cfg(timg1)] + Peripheral::Timg1 => { + // no reset? + } + #[cfg(lp_wdt)] + Peripheral::Wdt => { + // no reset? + } + #[cfg(sha)] + Peripheral::Sha => { + system.sha_conf().modify(|_, w| w.sha_rst_en().set_bit()); + system.sha_conf().modify(|_, w| w.sha_rst_en().clear_bit()); + } + #[cfg(usb_device)] + Peripheral::UsbDevice => { + system + .usb_device_conf() + .modify(|_, w| w.usb_device_rst_en().set_bit()); + system + .usb_device_conf() + .modify(|_, w| w.usb_device_rst_en().clear_bit()); + } + #[cfg(uart0)] + Peripheral::Uart0 => { + system + .uart0_conf() + .modify(|_, w| w.uart0_rst_en().set_bit()); + system + .uart0_conf() + .modify(|_, w| w.uart0_rst_en().clear_bit()); + } + #[cfg(uart1)] + Peripheral::Uart1 => { + system + .uart1_conf() + .modify(|_, w| w.uart1_rst_en().set_bit()); + system + .uart1_conf() + .modify(|_, w| w.uart1_rst_en().clear_bit()); + } + #[cfg(rsa)] + Peripheral::Rsa => { + system.rsa_conf().modify(|_, w| w.rsa_rst_en().set_bit()); + system.rsa_conf().modify(|_, w| w.rsa_rst_en().clear_bit()); + } + #[cfg(parl_io)] + Peripheral::ParlIo => { + system + .parl_io_conf() + .modify(|_, w| w.parl_rst_en().set_bit()); + system + .parl_io_conf() + .modify(|_, w| w.parl_rst_en().clear_bit()); + } + #[cfg(hmac)] + Peripheral::Hmac => { + system.hmac_conf().modify(|_, w| w.hmac_rst_en().set_bit()); + system + .hmac_conf() + .modify(|_, w| w.hmac_rst_en().clear_bit()); + } + #[cfg(ecc)] + Peripheral::Ecc => { + system.ecc_conf().modify(|_, w| w.ecc_rst_en().set_bit()); + system.ecc_conf().modify(|_, w| w.ecc_rst_en().clear_bit()); + } + #[cfg(soc_etm)] + Peripheral::Etm => { + system.etm_conf().modify(|_, w| w.etm_rst_en().set_bit()); + system.etm_conf().modify(|_, w| w.etm_rst_en().clear_bit()); + } + #[cfg(trace0)] + Peripheral::Trace0 => { + system + .trace_conf() + .modify(|_, w| w.trace_rst_en().set_bit()); + system + .trace_conf() + .modify(|_, w| w.trace_rst_en().clear_bit()); + } + } + } } #[cfg(esp32p4)] diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index b720d97919e..8e5f80ae952 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -902,7 +902,7 @@ where .write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) }); } - #[cfg(esp32c3)] + #[cfg(any(esp32c2, esp32c3, esp32s3))] #[inline(always)] fn init() { let system = unsafe { crate::peripherals::SYSTEM::steal() }; @@ -919,21 +919,33 @@ where .clk_conf() .modify(|_, w| w.rst_core().set_bit()); - // TODO use T::reset_peripheral() as soon as it is present in esp-hal - system - .perip_rst_en0() - .modify(|_, w| match T::uart_number() { - 0 => w.uart_rst().set_bit(), - 1 => w.uart1_rst().set_bit(), - _ => panic!("Unknown Uart Device!"), - }); - system - .perip_rst_en0() - .modify(|_, w| match T::uart_number() { - 0 => w.uart_rst().clear_bit(), - 1 => w.uart1_rst().clear_bit(), - _ => panic!("Unknown Uart Device!"), - }); + // reset peripheral + T::reset_peripheral(); + + T::register_block() + .clk_conf() + .modify(|_, w| w.rst_core().clear_bit()); + T::disable_rx_interrupts(); + T::disable_tx_interrupts(); + } + + #[cfg(any(esp32c6, esp32h2))] + #[inline(always)] + fn init() { + T::register_block() + .conf0() + .modify(|_, w| w.mem_clk_en().set_bit()); + + // initialize peripheral by setting clk_enable and clearing uart_reset bits + T::enable_peripheral(); + + T::register_block() + .clk_conf() + .modify(|_, w| w.rst_core().set_bit()); + + // reset peripheral + T::reset_peripheral(); + T::register_block() .clk_conf() .modify(|_, w| w.rst_core().clear_bit()); @@ -941,10 +953,11 @@ where T::disable_tx_interrupts(); } - #[cfg(not(esp32c3))] + #[cfg(any(esp32, esp32s2))] #[inline(always)] fn init() { T::enable_peripheral(); + T::reset_peripheral(); T::disable_rx_interrupts(); T::disable_tx_interrupts(); } @@ -1106,6 +1119,7 @@ pub trait Instance { fn cts_signal() -> InputSignal; fn rts_signal() -> OutputSignal; fn enable_peripheral(); + fn reset_peripheral(); } macro_rules! impl_instance { @@ -1140,6 +1154,10 @@ macro_rules! impl_instance { fn enable_peripheral() { PeripheralClockControl::enable(crate::system::Peripheral::$peri); } + + fn reset_peripheral() { + PeripheralClockControl::reset(crate::system::Peripheral::$peri); + } } }; } From df35ad8e5c4cf38ddac00b33abfcf4da5f48903a Mon Sep 17 00:00:00 2001 From: bjoernQ Date: Wed, 28 Feb 2024 10:45:46 +0100 Subject: [PATCH 2/5] Avoid UART reset for the console UART --- esp-hal/src/uart.rs | 65 +++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 23 deletions(-) diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index 8e5f80ae952..ae0da3f59b4 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -53,6 +53,7 @@ use crate::{ system::PeripheralClockControl, }; +const CONSOLE_UART_NUM: usize = 0; const UART_FIFO_SIZE: u16 = 128; /// Custom serial error type @@ -494,7 +495,7 @@ where } /// Split the Uart into a transmitter and receiver, which is - /// particuarly useful when having two tasks correlating to + /// particularly useful when having two tasks correlating to /// transmitting and receiving. pub fn split(self) -> (UartTx<'d, T>, UartRx<'d, T>) { (self.tx, self.rx) @@ -915,16 +916,21 @@ where // initialize peripheral by setting clk_enable and clearing uart_reset bits T::enable_peripheral(); - T::register_block() - .clk_conf() - .modify(|_, w| w.rst_core().set_bit()); + // don't reset the console UART - this will cause trouble at least on ESP32-S3 + // ideally this should be configurable once we have a solution for https://github.com/esp-rs/esp-hal/issues/1111 + // see https://github.com/espressif/esp-idf/blob/5f4249357372f209fdd57288265741aaba21a2b1/components/esp_driver_uart/src/uart.c#L179 + if T::uart_number() != CONSOLE_UART_NUM { + T::register_block() + .clk_conf() + .modify(|_, w| w.rst_core().set_bit()); - // reset peripheral - T::reset_peripheral(); + // reset peripheral + T::reset_peripheral(); - T::register_block() - .clk_conf() - .modify(|_, w| w.rst_core().clear_bit()); + T::register_block() + .clk_conf() + .modify(|_, w| w.rst_core().clear_bit()); + } T::disable_rx_interrupts(); T::disable_tx_interrupts(); } @@ -939,16 +945,22 @@ where // initialize peripheral by setting clk_enable and clearing uart_reset bits T::enable_peripheral(); - T::register_block() - .clk_conf() - .modify(|_, w| w.rst_core().set_bit()); + // don't reset the console UART - this will cause trouble at least on ESP32-S3 + // ideally this should be configurable once we have a solution for https://github.com/esp-rs/esp-hal/issues/1111 + // see https://github.com/espressif/esp-idf/blob/5f4249357372f209fdd57288265741aaba21a2b1/components/esp_driver_uart/src/uart.c#L179 + if T::uart_number() != CONSOLE_UART_NUM { + T::register_block() + .clk_conf() + .modify(|_, w| w.rst_core().set_bit()); - // reset peripheral - T::reset_peripheral(); + // reset peripheral + T::reset_peripheral(); + + T::register_block() + .clk_conf() + .modify(|_, w| w.rst_core().clear_bit()); + } - T::register_block() - .clk_conf() - .modify(|_, w| w.rst_core().clear_bit()); T::disable_rx_interrupts(); T::disable_tx_interrupts(); } @@ -957,18 +969,25 @@ where #[inline(always)] fn init() { T::enable_peripheral(); - T::reset_peripheral(); + + // don't reset the console UART - this will cause trouble at least on ESP32-S3 + // ideally this should be configurable once we have a solution for https://github.com/esp-rs/esp-hal/issues/1111 + // see https://github.com/espressif/esp-idf/blob/5f4249357372f209fdd57288265741aaba21a2b1/components/esp_driver_uart/src/uart.c#L179 + if T::uart_number() != CONSOLE_UART_NUM { + T::reset_peripheral(); + } + T::disable_rx_interrupts(); T::disable_tx_interrupts(); } - #[cfg(any(esp32c3, esp32c6, esp32h2))] // TODO introduce a cfg symbol for this + #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] // TODO introduce a cfg symbol for this #[inline(always)] fn sync_regs(&self) { #[cfg(any(esp32c6, esp32h2))] let update_reg = T::register_block().reg_update(); - #[cfg(esp32c3)] + #[cfg(any(esp32c3, esp32s3))] let update_reg = T::register_block().id(); update_reg.modify(|_, w| w.reg_update().set_bit()); @@ -978,7 +997,7 @@ where } } - #[cfg(not(any(esp32c3, esp32c6, esp32h2)))] + #[cfg(not(any(esp32c3, esp32c6, esp32h2, esp32s3)))] #[inline(always)] fn sync_regs(&mut self) {} } @@ -1534,7 +1553,7 @@ mod asynch { impl<'d, T: Instance> Drop for UartRxFuture<'d, T> { fn drop(&mut self) { - // Although the isr disables the interrupt that occured directly, we need to + // Although the isr disables the interrupt that occurred directly, we need to // disable the other interrupts (= the ones that did not occur), as // soon as this future goes out of scope. let int_ena = &T::register_block().int_ena(); @@ -1696,7 +1715,7 @@ mod asynch { /// /// The interrupts in question are enabled during the body of this /// function. The method immediately returns when the interrupt - /// has already occured before calling this method (e.g. status + /// has already occurred before calling this method (e.g. status /// bit set, but interrupt not enabled) /// /// # Params From 3f0978fbe239a5cb7826e040b0ce0e1e8d97718e Mon Sep 17 00:00:00 2001 From: bjoernQ Date: Wed, 28 Feb 2024 10:46:10 +0100 Subject: [PATCH 3/5] Fix comments --- examples/src/bin/advanced_serial.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/src/bin/advanced_serial.rs b/examples/src/bin/advanced_serial.rs index 8c8954beb9b..5cc6405397d 100644 --- a/examples/src/bin/advanced_serial.rs +++ b/examples/src/bin/advanced_serial.rs @@ -4,8 +4,8 @@ //! of the configuration change the output signal. //! //! The following wiring is assumed: -//! - TX => GPIO1 -//! - RX => GPIO2 +//! - TX => GPIO4 +//! - RX => GPIO5 //% CHIPS: esp32 esp32c2 esp32c3 esp32c6 esp32h2 esp32s2 esp32s3 From 6bd0c9e14aa1a376862e2a6ae24846d52d921382 Mon Sep 17 00:00:00 2001 From: bjoernQ Date: Wed, 28 Feb 2024 11:02:19 +0100 Subject: [PATCH 4/5] CHANGELOG.md entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4c9dce58e2..5f174c58dd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix circular DMA (#1189) - Fix esp32c3 uart initialization (#1156) - Fix ESP32-S2 I2C read (#1214) +- Reset/init UART if it's not the console UART (#1213) ### Changed From e4b2549523e3e1a6e2a2e3d91fdaaa9107ea3680 Mon Sep 17 00:00:00 2001 From: bjoernQ Date: Wed, 28 Feb 2024 14:10:11 +0100 Subject: [PATCH 5/5] Introduce a `uart_peripheral_reset` function --- esp-hal/src/uart.rs | 66 +++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/esp-hal/src/uart.rs b/esp-hal/src/uart.rs index ae0da3f59b4..08bd24cbe90 100644 --- a/esp-hal/src/uart.rs +++ b/esp-hal/src/uart.rs @@ -448,7 +448,7 @@ where impl<'d, T> Uart<'d, T> where - T: Instance, + T: Instance + 'd, { /// Create a new UART instance with defaults pub fn new_with_config

( @@ -915,22 +915,7 @@ where // initialize peripheral by setting clk_enable and clearing uart_reset bits T::enable_peripheral(); - - // don't reset the console UART - this will cause trouble at least on ESP32-S3 - // ideally this should be configurable once we have a solution for https://github.com/esp-rs/esp-hal/issues/1111 - // see https://github.com/espressif/esp-idf/blob/5f4249357372f209fdd57288265741aaba21a2b1/components/esp_driver_uart/src/uart.c#L179 - if T::uart_number() != CONSOLE_UART_NUM { - T::register_block() - .clk_conf() - .modify(|_, w| w.rst_core().set_bit()); - - // reset peripheral - T::reset_peripheral(); - - T::register_block() - .clk_conf() - .modify(|_, w| w.rst_core().clear_bit()); - } + Self::uart_peripheral_reset(); T::disable_rx_interrupts(); T::disable_tx_interrupts(); } @@ -944,11 +929,34 @@ where // initialize peripheral by setting clk_enable and clearing uart_reset bits T::enable_peripheral(); + Self::uart_peripheral_reset(); + T::disable_rx_interrupts(); + T::disable_tx_interrupts(); + } + + #[cfg(any(esp32, esp32s2))] + #[inline(always)] + fn init() { + T::enable_peripheral(); + Self::uart_peripheral_reset(); + T::disable_rx_interrupts(); + T::disable_tx_interrupts(); + } - // don't reset the console UART - this will cause trouble at least on ESP32-S3 - // ideally this should be configurable once we have a solution for https://github.com/esp-rs/esp-hal/issues/1111 + #[inline(always)] + fn uart_peripheral_reset() { + // don't reset the console UART - this will cause trouble (i.e. the UART will + // start to transmit garbage) + // + // We should only reset the console UART if it was absolutely unused before. + // Apparently the bootloader (and maybe the ROM code) writing to the UART is + // already enough to make this a no-go. (i.e. one needs to mute the ROM + // code via efuse / strapping pin AND use a silent bootloader) + // + // Ideally this should be configurable once we have a solution for https://github.com/esp-rs/esp-hal/issues/1111 // see https://github.com/espressif/esp-idf/blob/5f4249357372f209fdd57288265741aaba21a2b1/components/esp_driver_uart/src/uart.c#L179 if T::uart_number() != CONSOLE_UART_NUM { + #[cfg(not(any(esp32, esp32s2)))] T::register_block() .clk_conf() .modify(|_, w| w.rst_core().set_bit()); @@ -956,29 +964,11 @@ where // reset peripheral T::reset_peripheral(); + #[cfg(not(any(esp32, esp32s2)))] T::register_block() .clk_conf() .modify(|_, w| w.rst_core().clear_bit()); } - - T::disable_rx_interrupts(); - T::disable_tx_interrupts(); - } - - #[cfg(any(esp32, esp32s2))] - #[inline(always)] - fn init() { - T::enable_peripheral(); - - // don't reset the console UART - this will cause trouble at least on ESP32-S3 - // ideally this should be configurable once we have a solution for https://github.com/esp-rs/esp-hal/issues/1111 - // see https://github.com/espressif/esp-idf/blob/5f4249357372f209fdd57288265741aaba21a2b1/components/esp_driver_uart/src/uart.c#L179 - if T::uart_number() != CONSOLE_UART_NUM { - T::reset_peripheral(); - } - - T::disable_rx_interrupts(); - T::disable_tx_interrupts(); } #[cfg(any(esp32c3, esp32c6, esp32h2, esp32s3))] // TODO introduce a cfg symbol for this