Skip to content

Commit c426a36

Browse files
committed
C5: Enable UHCI
1 parent 96e4867 commit c426a36

25 files changed

+211
-86
lines changed

esp-hal/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2525
- `Cpu::all` to iterate over all CPUs (#4890)
2626
- C5: Add initial GPIO support (#4899, #4928, #4935)
2727
- C5: Add PCNT support (#4934)
28-
- C5: Initial UART support (#4948)
28+
- C5: Initial UART support (#4948, #4967)
2929
- C5: Add SPI support (#4943)
3030

3131
### Changed

esp-hal/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a
9595
| Touch | ⚒️ | | | | | |||
9696
| TWAI | ⚒️ | | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ |
9797
| UART | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
98+
| UART || | ⚒️ | ⚒️ | ⚒️ | ⚒️ || ⚒️ |
9899
| LP UART | | | | | ⚒️ | | | |
99100
| ULP (FSM) | ⚒️ | | | | | | ⚒️ | ⚒️ |
100101
| ULP (RISC-V) | | | | | ⚒️ | | ⚒️ | ⚒️ |

esp-hal/src/dma/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2830,7 +2830,7 @@ pub(crate) mod asynch {
28302830
const FAILURE_INTERRUPTS: EnumSet<DmaTxInterrupt> =
28312831
enum_set!(DmaTxInterrupt::DescriptorError);
28322832

2833-
#[cfg_attr(any(esp32c2, esp32c5), expect(dead_code))]
2833+
#[cfg_attr(esp32c2, expect(dead_code))]
28342834
pub fn new(tx: &'a mut ChannelTx<Async, CH>) -> Self {
28352835
Self { tx }
28362836
}

esp-hal/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ use core::marker::PhantomData;
276276

277277
pub use esp_metadata_generated::chip;
278278
use esp_rom_sys as _;
279+
pub(crate) use unstable_driver;
279280
pub(crate) use unstable_module;
280281

281282
metadata!("build_info", CHIP_NAME, chip!());

esp-hal/src/uart/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@
4141
//! [embedded-hal-async]: embedded_hal_async
4242
//! [embedded-io-async]: embedded_io_async_07
4343
44-
/// UHCI wrapper around UART
45-
// TODO add support for PDMA and multiple UHCI for 32/S2 support
46-
#[cfg(all(soc_has_uhci0, dma_kind = "gdma"))]
47-
#[cfg(feature = "unstable")]
48-
pub mod uhci;
44+
crate::unstable_driver! {
45+
/// UHCI wrapper around UART
46+
#[cfg(uhci_driver_supported)]
47+
pub mod uhci;
48+
}
4949

5050
use core::{marker::PhantomData, sync::atomic::Ordering, task::Poll};
5151

@@ -3740,7 +3740,7 @@ impl PartialEq for Info {
37403740
unsafe impl Sync for Info {}
37413741

37423742
for_each_uart! {
3743-
($inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
3743+
($id:literal, $inst:ident, $peri:ident, $rxd:ident, $txd:ident, $cts:ident, $rts:ident) => {
37443744
impl Instance for crate::peripherals::$inst<'_> {
37453745
fn parts(&self) -> (&'static Info, &'static State) {
37463746
#[crate::handler]

esp-hal/src/uart/uhci.rs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
//! software_reset()
8383
//! }
8484
//! ```
85+
// TODO add support for PDMA and multiple UHCI for 32/S2 support
8586

8687
use core::{
8788
mem::ManuallyDrop,
@@ -311,21 +312,35 @@ where
311312
let reg = self.uhci_per.register_block();
312313

313314
for_each_uart! {
314-
(all $( ($peri:ident, $variant:ident, $($pins:ident),*) ),*) => {
315-
315+
(all $( ($id:literal, $peri:ident, $variant:ident, $($pins:ident),*) ),*) => {
316316
reg.conf0().modify(|_, w| {
317-
paste::paste! {
318-
// Clear any previous selection
319-
$(
320-
w.[< $peri:lower _ce >]().clear_bit();
321-
)*
322-
323-
// Select UART
324-
match &self.uart.tx.uart.0 {
325-
$(super::any::Inner::$variant(_) => {
326-
debug!("Uhci will use {}", stringify!($peri));
327-
w.[< $peri:lower _ce >]().set_bit()
328-
})*
317+
cfg_if::cfg_if! {
318+
if #[cfg(uhci_combined_uart_selector_field)] {
319+
unsafe {
320+
w.uart_sel().bits(
321+
match &self.uart.tx.uart.0 {
322+
$(super::any::Inner::$variant(_) => {
323+
debug!("Uhci will use UART{}", stringify!($id));
324+
$id
325+
})*
326+
}
327+
)
328+
}
329+
} else {
330+
paste::paste! {
331+
// Clear any previous selection
332+
$(
333+
w.[< $peri:lower _ce >]().clear_bit();
334+
)*
335+
336+
// Select UART
337+
match &self.uart.tx.uart.0 {
338+
$(super::any::Inner::$variant(_) => {
339+
debug!("Uhci will use {}", stringify!($peri));
340+
w.[< $peri:lower _ce >]().set_bit()
341+
})*
342+
}
343+
}
329344
}
330345
}
331346
});

esp-metadata-generated/src/_build_script_utils.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,7 @@ impl Chip {
12201220
"timergroup_driver_supported",
12211221
"twai_driver_supported",
12221222
"uart_driver_supported",
1223+
"uhci_driver_supported",
12231224
"usb_serial_jtag_driver_supported",
12241225
"wifi_driver_supported",
12251226
"bt_driver_supported",
@@ -1421,6 +1422,7 @@ impl Chip {
14211422
"cargo:rustc-cfg=timergroup_driver_supported",
14221423
"cargo:rustc-cfg=twai_driver_supported",
14231424
"cargo:rustc-cfg=uart_driver_supported",
1425+
"cargo:rustc-cfg=uhci_driver_supported",
14241426
"cargo:rustc-cfg=usb_serial_jtag_driver_supported",
14251427
"cargo:rustc-cfg=wifi_driver_supported",
14261428
"cargo:rustc-cfg=bt_driver_supported",
@@ -1704,6 +1706,7 @@ impl Chip {
17041706
"soc_has_trace0",
17051707
"soc_has_uart0",
17061708
"soc_has_uart1",
1709+
"soc_has_uhci0",
17071710
"soc_has_usb_device",
17081711
"soc_has_dma_ch0",
17091712
"soc_has_dma_ch1",
@@ -1737,6 +1740,7 @@ impl Chip {
17371740
"systimer_driver_supported",
17381741
"timergroup_driver_supported",
17391742
"uart_driver_supported",
1743+
"uhci_driver_supported",
17401744
"spi_master_spi2",
17411745
"spi_slave_spi2",
17421746
"timergroup_timg0",
@@ -1802,6 +1806,7 @@ impl Chip {
18021806
"timergroup_rc_fast_calibration_is_set",
18031807
"uart_ram_size=\"128\"",
18041808
"uart_peripheral_controls_mem_clk",
1809+
"uhci_combined_uart_selector_field",
18051810
],
18061811
cfgs: &[
18071812
"cargo:rustc-cfg=esp32c5",
@@ -1864,6 +1869,7 @@ impl Chip {
18641869
"cargo:rustc-cfg=soc_has_trace0",
18651870
"cargo:rustc-cfg=soc_has_uart0",
18661871
"cargo:rustc-cfg=soc_has_uart1",
1872+
"cargo:rustc-cfg=soc_has_uhci0",
18671873
"cargo:rustc-cfg=soc_has_usb_device",
18681874
"cargo:rustc-cfg=soc_has_dma_ch0",
18691875
"cargo:rustc-cfg=soc_has_dma_ch1",
@@ -1897,6 +1903,7 @@ impl Chip {
18971903
"cargo:rustc-cfg=systimer_driver_supported",
18981904
"cargo:rustc-cfg=timergroup_driver_supported",
18991905
"cargo:rustc-cfg=uart_driver_supported",
1906+
"cargo:rustc-cfg=uhci_driver_supported",
19001907
"cargo:rustc-cfg=spi_master_spi2",
19011908
"cargo:rustc-cfg=spi_slave_spi2",
19021909
"cargo:rustc-cfg=timergroup_timg0",
@@ -1962,6 +1969,7 @@ impl Chip {
19621969
"cargo:rustc-cfg=timergroup_rc_fast_calibration_is_set",
19631970
"cargo:rustc-cfg=uart_ram_size=\"128\"",
19641971
"cargo:rustc-cfg=uart_peripheral_controls_mem_clk",
1972+
"cargo:rustc-cfg=uhci_combined_uart_selector_field",
19651973
],
19661974
memory_layout: &MemoryLayout {
19671975
regions: &[
@@ -2206,6 +2214,7 @@ impl Chip {
22062214
"timergroup_driver_supported",
22072215
"twai_driver_supported",
22082216
"uart_driver_supported",
2217+
"uhci_driver_supported",
22092218
"lp_uart_driver_supported",
22102219
"ulp_riscv_driver_supported",
22112220
"usb_serial_jtag_driver_supported",
@@ -2471,6 +2480,7 @@ impl Chip {
24712480
"cargo:rustc-cfg=timergroup_driver_supported",
24722481
"cargo:rustc-cfg=twai_driver_supported",
24732482
"cargo:rustc-cfg=uart_driver_supported",
2483+
"cargo:rustc-cfg=uhci_driver_supported",
24742484
"cargo:rustc-cfg=lp_uart_driver_supported",
24752485
"cargo:rustc-cfg=ulp_riscv_driver_supported",
24762486
"cargo:rustc-cfg=usb_serial_jtag_driver_supported",
@@ -2861,6 +2871,7 @@ impl Chip {
28612871
"timergroup_driver_supported",
28622872
"twai_driver_supported",
28632873
"uart_driver_supported",
2874+
"uhci_driver_supported",
28642875
"usb_serial_jtag_driver_supported",
28652876
"bt_driver_supported",
28662877
"ieee802154_driver_supported",
@@ -3087,6 +3098,7 @@ impl Chip {
30873098
"cargo:rustc-cfg=timergroup_driver_supported",
30883099
"cargo:rustc-cfg=twai_driver_supported",
30893100
"cargo:rustc-cfg=uart_driver_supported",
3101+
"cargo:rustc-cfg=uhci_driver_supported",
30903102
"cargo:rustc-cfg=usb_serial_jtag_driver_supported",
30913103
"cargo:rustc-cfg=bt_driver_supported",
30923104
"cargo:rustc-cfg=ieee802154_driver_supported",
@@ -4040,6 +4052,7 @@ impl Chip {
40404052
"timergroup_driver_supported",
40414053
"twai_driver_supported",
40424054
"uart_driver_supported",
4055+
"uhci_driver_supported",
40434056
"ulp_fsm_driver_supported",
40444057
"ulp_riscv_driver_supported",
40454058
"usb_otg_driver_supported",
@@ -4288,6 +4301,7 @@ impl Chip {
42884301
"cargo:rustc-cfg=timergroup_driver_supported",
42894302
"cargo:rustc-cfg=twai_driver_supported",
42904303
"cargo:rustc-cfg=uart_driver_supported",
4304+
"cargo:rustc-cfg=uhci_driver_supported",
42914305
"cargo:rustc-cfg=ulp_fsm_driver_supported",
42924306
"cargo:rustc-cfg=ulp_riscv_driver_supported",
42934307
"cargo:rustc-cfg=usb_otg_driver_supported",
@@ -4915,6 +4929,7 @@ pub fn emit_check_cfg_directives() {
49154929
println!("cargo:rustc-check-cfg=cfg(soc_has_dma_ch2)");
49164930
println!("cargo:rustc-check-cfg=cfg(soc_has_tsens)");
49174931
println!("cargo:rustc-check-cfg=cfg(hmac_driver_supported)");
4932+
println!("cargo:rustc-check-cfg=cfg(uhci_driver_supported)");
49184933
println!("cargo:rustc-check-cfg=cfg(usb_serial_jtag_driver_supported)");
49194934
println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_cpu_pll_div_out)");
49204935
println!("cargo:rustc-check-cfg=cfg(soc_has_clock_node_pll_160m)");
@@ -5000,6 +5015,7 @@ pub fn emit_check_cfg_directives() {
50005015
println!("cargo:rustc-check-cfg=cfg(dma_separate_in_out_interrupts)");
50015016
println!("cargo:rustc-check-cfg=cfg(spi_master_has_clk_pre_div)");
50025017
println!("cargo:rustc-check-cfg=cfg(uart_peripheral_controls_mem_clk)");
5018+
println!("cargo:rustc-check-cfg=cfg(uhci_combined_uart_selector_field)");
50035019
println!("cargo:rustc-check-cfg=cfg(esp32c6)");
50045020
println!("cargo:rustc-check-cfg=cfg(soc_has_atomic)");
50055021
println!("cargo:rustc-check-cfg=cfg(soc_has_ieee802154)");

esp-metadata-generated/src/_generated_esp32.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ macro_rules! property {
270270
("uart.peripheral_controls_mem_clk") => {
271271
false
272272
};
273+
("uhci.combined_uart_selector_field") => {
274+
false
275+
};
273276
("wifi.has_wifi6") => {
274277
false
275278
};
@@ -2984,25 +2987,28 @@ macro_rules! for_each_i2c_master {
29842987
///
29852988
/// This macro has one option for its "Individual matcher" case:
29862989
///
2987-
/// Syntax: `($instance:ident, $sys:ident, $rx:ident, $tx:ident, $cts:ident, $rts:ident)`
2990+
/// Syntax: `($id:literal, $instance:ident, $sys:ident, $rx:ident, $tx:ident, $cts:ident,
2991+
/// $rts:ident)`
29882992
///
29892993
/// Macro fragments:
29902994
///
2995+
/// - `$id`: the index of the UART instance
29912996
/// - `$instance`: the name of the UART instance
29922997
/// - `$sys`: the name of the instance as it is in the `esp_hal::system::Peripheral` enum.
29932998
/// - `$rx`, `$tx`, `$cts`, `$rts`: signal names.
29942999
///
2995-
/// Example data: `(UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS)`
3000+
/// Example data: `(0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS)`
29963001
#[macro_export]
29973002
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
29983003
macro_rules! for_each_uart {
29993004
($($pattern:tt => $code:tt;)*) => {
30003005
macro_rules! _for_each_inner_uart { $(($pattern) => $code;)* ($other : tt) => {}
3001-
} _for_each_inner_uart!((UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS));
3002-
_for_each_inner_uart!((UART1, Uart1, U1RXD, U1TXD, U1CTS, U1RTS));
3003-
_for_each_inner_uart!((UART2, Uart2, U2RXD, U2TXD, U2CTS, U2RTS));
3004-
_for_each_inner_uart!((all(UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS), (UART1,
3005-
Uart1, U1RXD, U1TXD, U1CTS, U1RTS), (UART2, Uart2, U2RXD, U2TXD, U2CTS, U2RTS)));
3006+
} _for_each_inner_uart!((0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS));
3007+
_for_each_inner_uart!((1, UART1, Uart1, U1RXD, U1TXD, U1CTS, U1RTS));
3008+
_for_each_inner_uart!((2, UART2, Uart2, U2RXD, U2TXD, U2CTS, U2RTS));
3009+
_for_each_inner_uart!((all(0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS), (1,
3010+
UART1, Uart1, U1RXD, U1TXD, U1CTS, U1RTS), (2, UART2, Uart2, U2RXD, U2TXD, U2CTS,
3011+
U2RTS)));
30063012
};
30073013
}
30083014
/// This macro can be used to generate code for each peripheral instance of the SPI master driver.

esp-metadata-generated/src/_generated_esp32c2.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2421,24 +2421,26 @@ macro_rules! for_each_i2c_master {
24212421
///
24222422
/// This macro has one option for its "Individual matcher" case:
24232423
///
2424-
/// Syntax: `($instance:ident, $sys:ident, $rx:ident, $tx:ident, $cts:ident, $rts:ident)`
2424+
/// Syntax: `($id:literal, $instance:ident, $sys:ident, $rx:ident, $tx:ident, $cts:ident,
2425+
/// $rts:ident)`
24252426
///
24262427
/// Macro fragments:
24272428
///
2429+
/// - `$id`: the index of the UART instance
24282430
/// - `$instance`: the name of the UART instance
24292431
/// - `$sys`: the name of the instance as it is in the `esp_hal::system::Peripheral` enum.
24302432
/// - `$rx`, `$tx`, `$cts`, `$rts`: signal names.
24312433
///
2432-
/// Example data: `(UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS)`
2434+
/// Example data: `(0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS)`
24332435
#[macro_export]
24342436
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
24352437
macro_rules! for_each_uart {
24362438
($($pattern:tt => $code:tt;)*) => {
24372439
macro_rules! _for_each_inner_uart { $(($pattern) => $code;)* ($other : tt) => {}
2438-
} _for_each_inner_uart!((UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS));
2439-
_for_each_inner_uart!((UART1, Uart1, U1RXD, U1TXD, U1CTS, U1RTS));
2440-
_for_each_inner_uart!((all(UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS), (UART1,
2441-
Uart1, U1RXD, U1TXD, U1CTS, U1RTS)));
2440+
} _for_each_inner_uart!((0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS));
2441+
_for_each_inner_uart!((1, UART1, Uart1, U1RXD, U1TXD, U1CTS, U1RTS));
2442+
_for_each_inner_uart!((all(0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS), (1,
2443+
UART1, Uart1, U1RXD, U1TXD, U1CTS, U1RTS)));
24422444
};
24432445
}
24442446
/// This macro can be used to generate code for each peripheral instance of the SPI master driver.

esp-metadata-generated/src/_generated_esp32c3.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,9 @@ macro_rules! property {
294294
("uart.peripheral_controls_mem_clk") => {
295295
false
296296
};
297+
("uhci.combined_uart_selector_field") => {
298+
false
299+
};
297300
("wifi.has_wifi6") => {
298301
false
299302
};
@@ -2965,24 +2968,26 @@ macro_rules! for_each_i2c_master {
29652968
///
29662969
/// This macro has one option for its "Individual matcher" case:
29672970
///
2968-
/// Syntax: `($instance:ident, $sys:ident, $rx:ident, $tx:ident, $cts:ident, $rts:ident)`
2971+
/// Syntax: `($id:literal, $instance:ident, $sys:ident, $rx:ident, $tx:ident, $cts:ident,
2972+
/// $rts:ident)`
29692973
///
29702974
/// Macro fragments:
29712975
///
2976+
/// - `$id`: the index of the UART instance
29722977
/// - `$instance`: the name of the UART instance
29732978
/// - `$sys`: the name of the instance as it is in the `esp_hal::system::Peripheral` enum.
29742979
/// - `$rx`, `$tx`, `$cts`, `$rts`: signal names.
29752980
///
2976-
/// Example data: `(UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS)`
2981+
/// Example data: `(0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS)`
29772982
#[macro_export]
29782983
#[cfg_attr(docsrs, doc(cfg(feature = "_device-selected")))]
29792984
macro_rules! for_each_uart {
29802985
($($pattern:tt => $code:tt;)*) => {
29812986
macro_rules! _for_each_inner_uart { $(($pattern) => $code;)* ($other : tt) => {}
2982-
} _for_each_inner_uart!((UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS));
2983-
_for_each_inner_uart!((UART1, Uart1, U1RXD, U1TXD, U1CTS, U1RTS));
2984-
_for_each_inner_uart!((all(UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS), (UART1,
2985-
Uart1, U1RXD, U1TXD, U1CTS, U1RTS)));
2987+
} _for_each_inner_uart!((0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS));
2988+
_for_each_inner_uart!((1, UART1, Uart1, U1RXD, U1TXD, U1CTS, U1RTS));
2989+
_for_each_inner_uart!((all(0, UART0, Uart0, U0RXD, U0TXD, U0CTS, U0RTS), (1,
2990+
UART1, Uart1, U1RXD, U1TXD, U1CTS, U1RTS)));
29862991
};
29872992
}
29882993
/// This macro can be used to generate code for each peripheral instance of the SPI master driver.

0 commit comments

Comments
 (0)