fix esp32c3 uart initialization (#1156)

* fix esp32c3 uart initialization

Implement uart initialization according to the [esp32c3 technical
reference manual section 26.5.2.1](https://www.espressif.com/sites/default/files/documentation/esp32-c3_technical_reference_manual_en.pdf#subsubsection.26.5.2)

* add fix to changelog
This commit is contained in:
Felix Richter 2024-02-21 15:44:37 +01:00 committed by GitHub
parent 9378639e4c
commit 4bc1aaaefa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 60 additions and 15 deletions

View File

@ -38,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Wait for registers to get synced before reading the timer count for all chips (#1183)
- Fix I2C error handling (#1184)
- Fix circular DMA (#1189)
- Fix esp32c3 uart initialization (#1156)
### Changed

View File

@ -459,9 +459,7 @@ where
where
P: UartPins,
{
T::enable_peripheral();
T::disable_rx_interrupts();
T::disable_tx_interrupts();
Self::init();
if let Some(ref mut pins) = pins {
pins.configure_pins(
@ -479,10 +477,10 @@ where
symbol_len: config.symbol_length(),
};
serial.change_baud(config.baudrate, clocks);
serial.change_data_bits(config.data_bits);
serial.change_parity(config.parity);
serial.change_stop_bits(config.stop_bits);
serial.change_baud(config.baudrate, clocks);
serial
}
@ -904,24 +902,70 @@ where
.write(|w| unsafe { w.clkdiv().bits(divider).frag().bits(0) });
}
#[cfg(any(esp32c6, esp32h2))] // TODO introduce a cfg symbol for this
#[cfg(esp32c3)]
#[inline(always)]
fn init() {
let system = unsafe { crate::peripherals::SYSTEM::steal() };
if !system.perip_clk_en0().read().uart_mem_clk_en().bit() {
system
.perip_clk_en0()
.modify(|_, w| w.uart_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());
// 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!"),
});
T::register_block()
.clk_conf()
.modify(|_, w| w.rst_core().clear_bit());
T::disable_rx_interrupts();
T::disable_tx_interrupts();
}
#[cfg(not(esp32c3))]
#[inline(always)]
fn init() {
T::enable_peripheral();
T::disable_rx_interrupts();
T::disable_tx_interrupts();
}
#[cfg(any(esp32c3, esp32c6, esp32h2))] // TODO introduce a cfg symbol for this
#[inline(always)]
fn sync_regs(&self) {
T::register_block()
.reg_update()
.modify(|_, w| w.reg_update().set_bit());
#[cfg(any(esp32c6, esp32h2))]
let update_reg = T::register_block().reg_update();
while T::register_block()
.reg_update()
.read()
.reg_update()
.bit_is_set()
{
#[cfg(esp32c3)]
let update_reg = T::register_block().id();
update_reg.modify(|_, w| w.reg_update().set_bit());
while update_reg.read().reg_update().bit_is_set() {
// wait
}
}
#[cfg(not(any(esp32c6, esp32h2)))]
#[cfg(not(any(esp32c3, esp32c6, esp32h2)))]
#[inline(always)]
fn sync_regs(&mut self) {}
}