Use metadata to define LP peripheral FIFO sizes (#3812)

This commit is contained in:
Dániel Buga 2025-07-17 14:16:24 +02:00 committed by GitHub
parent fdc2a33e67
commit e146e03c72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 146 additions and 45 deletions

View File

@ -64,6 +64,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a
| GPIO | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| HMAC | | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ |
| I2C master | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| LP I2C master | | | | ⚒️ | | | |
| I2C slave | ❌ | | ❌ | ❌ | ❌ | ❌ | ❌ |
| I2S | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ |
| Interrupts | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ |
@ -90,6 +91,7 @@ For help getting started with this HAL, please refer to [The Rust on ESP Book] a
| Touch | ⚒️ | | | | | ❌ | ❌ |
| TWAI | ⚒️ | | ⚒️ | ⚒️ | ⚒️ | ⚒️ | ⚒️ |
| UART | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
| LP UART | | | | ⚒️ | | | |
| ULP (FSM) | ⚒️ | | | | | ⚒️ | ⚒️ |
| ULP (RISC-V) | | | | ⚒️ | | ⚒️ | ⚒️ |
| USB OTG FS | | | | | | ⚒️ | ⚒️ |

View File

@ -2340,7 +2340,7 @@ pub(super) fn intr_handler(uart: &Info, state: &State) {
}
/// Low-power UART
#[cfg(soc_has_lp_uart)]
#[cfg(lp_uart)]
#[instability::unstable]
pub mod lp_uart {
use crate::{
@ -2631,8 +2631,8 @@ pub struct State {
impl Info {
// Currently we don't support merging adjacent FIFO memory, so the max size is
// 128 bytes, the max threshold is 127 bytes.
const UART_FIFO_SIZE: u16 = 128;
const RX_FIFO_MAX_THRHD: u16 = 127;
const UART_FIFO_SIZE: u16 = property!("uart.ram_size");
const RX_FIFO_MAX_THRHD: u16 = Self::UART_FIFO_SIZE - 1;
const TX_FIFO_MAX_THRHD: u16 = Self::RX_FIFO_MAX_THRHD;
/// Returns the register block for this UART instance.

View File

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Fixed size of LP_UART's RAM block (#3812)
### Removed

View File

@ -31,10 +31,14 @@ esp32s3-ulp = { version = "0.3.0", features = ["critical-section"], option
nb = { version = "1.1.0", optional = true }
procmacros = { version = "0.19.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
riscv = { version = "0.11.1", features = ["critical-section-single-hart"] }
esp-metadata-generated = { version = "0.1.0", path = "../esp-metadata-generated" }
[dev-dependencies]
panic-halt = "0.2.0"
[build-dependencies]
esp-metadata-generated = { version = "0.1.0", path = "../esp-metadata-generated", features = ["build-script"] }
[features]
default = ["embedded-hal"]
@ -47,11 +51,11 @@ debug = [
# Chip Support Feature Flags
# Target the ESP32-C6.
esp32c6 = ["dep:esp32c6-lp", "procmacros/is-lp-core", "dep:nb"]
esp32c6 = ["dep:esp32c6-lp", "esp-metadata-generated/esp32c6", "procmacros/is-lp-core", "dep:nb"]
# Target the ESP32-S2.
esp32s2 = ["dep:esp32s2-ulp", "procmacros/is-ulp-core"]
esp32s2 = ["dep:esp32s2-ulp", "esp-metadata-generated/esp32s2", "procmacros/is-ulp-core"]
# Target the ESP32-S3.
esp32s3 = ["dep:esp32s3-ulp", "procmacros/is-ulp-core"]
esp32s3 = ["dep:esp32s3-ulp", "esp-metadata-generated/esp32s3", "procmacros/is-ulp-core"]
#! ### Trait Implementation Feature Flags
## Implement the traits defined in the `1.0.0` releases of `embedded-hal` and

View File

@ -1,48 +1,26 @@
use std::{env, error::Error, fs, path::PathBuf};
#[macro_export]
macro_rules! assert_unique_used_features {
($($feature:literal),+ $(,)?) => {
assert!(
(0 $(+ cfg!(feature = $feature) as usize)+ ) == 1,
"Exactly one of the following features must be enabled: {}",
[$($feature),+].join(", ")
);
};
}
use esp_metadata_generated::Chip;
fn main() -> Result<(), Box<dyn Error>> {
// NOTE: update when adding new device support!
// Ensure that exactly one chip has been specified:
assert_unique_used_features!("esp32c6", "esp32s2", "esp32s3");
// NOTE: update when adding new device support!
// Determine the name of the configured device:
let device_name = if cfg!(feature = "esp32c6") {
"esp32c6"
} else if cfg!(feature = "esp32s2") {
"esp32s2"
} else if cfg!(feature = "esp32s3") {
"esp32s3"
} else {
unreachable!() // We've confirmed exactly one known device was selected
};
let chip = Chip::from_cargo_feature()?;
// Define all necessary configuration symbols for the configured device:
println!("cargo:rustc-cfg={device_name}");
chip.define_cfgs();
// Copy the required linker script to the `out` directory:
let source_file = match chip {
Chip::Esp32c6 => "ld/link-lp.x",
Chip::Esp32s2 | Chip::Esp32s3 => "ld/link-ulp.x",
_ => unreachable!(),
};
// Put the linker script somewhere the linker can find it:
let out = PathBuf::from(env::var_os("OUT_DIR").unwrap());
println!("cargo:rustc-link-search={}", out.display());
// Copy the required linker script to the `out` directory:
if cfg!(feature = "esp32c6") {
fs::copy("ld/link-lp.x", out.join("link.x"))?;
println!("cargo:rerun-if-changed=ld/link-lp.x");
} else if cfg!(feature = "esp32s2") || cfg!(feature = "esp32s3") {
fs::copy("ld/link-ulp.x", out.join("link.x"))?;
println!("cargo:rerun-if-changed=ld/link-ulp.x");
}
fs::copy(source_file, out.join("link.x"))?;
println!("cargo:rerun-if-changed=ld/link-ulp.x");
// Done!
Ok(())

View File

@ -12,7 +12,7 @@ const I2C_LL_INTR_MASK: u32 = (1 << LP_I2C_TRANS_COMPLETE_INT_ST_S)
| (1 << LP_I2C_END_DETECT_INT_ST_S)
| (1 << LP_I2C_NACK_INT_ST_S);
const LP_I2C_FIFO_LEN: u32 = 16;
const LP_I2C_FIFO_LEN: u32 = property!("lp_i2c_master.fifo_size");
#[doc(hidden)]
pub unsafe fn conjure() -> LpI2c {

View File

@ -18,13 +18,17 @@
#![deny(missing_docs)]
#![no_std]
#[allow(unused_imports, reason = "Only used for some MCUs currently")]
#[macro_use]
extern crate esp_metadata_generated;
use core::arch::global_asm;
pub mod delay;
pub mod gpio;
#[cfg(esp32c6)]
#[cfg(lp_i2c_master)]
pub mod i2c;
#[cfg(esp32c6)]
#[cfg(lp_uart)]
pub mod uart;
#[cfg(feature = "esp32c6")]

View File

@ -36,7 +36,7 @@
use crate::pac::LP_UART;
const UART_FIFO_SIZE: u16 = 128;
const UART_FIFO_SIZE: u16 = property!("lp_uart.ram_size");
#[doc(hidden)]
pub unsafe fn conjure() -> LpUart {

View File

@ -278,6 +278,7 @@ impl Chip {
"rmt_ram_start=\"1073047552\"",
"rmt_channel_ram_size=\"64\"",
"timergroup_timg_has_timer1",
"uart_ram_size=\"128\"",
"has_dram_region",
],
cfgs: &[
@ -419,6 +420,7 @@ impl Chip {
"cargo:rustc-cfg=rmt_ram_start=\"1073047552\"",
"cargo:rustc-cfg=rmt_channel_ram_size=\"64\"",
"cargo:rustc-cfg=timergroup_timg_has_timer1",
"cargo:rustc-cfg=uart_ram_size=\"128\"",
"cargo:rustc-cfg=has_dram_region",
],
},
@ -524,6 +526,7 @@ impl Chip {
"i2c_master_ll_intr_mask=\"262143\"",
"i2c_master_fifo_size=\"16\"",
"interrupts_status_registers=\"2\"",
"uart_ram_size=\"128\"",
"has_dram_region",
],
cfgs: &[
@ -625,6 +628,7 @@ impl Chip {
"cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"",
"cargo:rustc-cfg=i2c_master_fifo_size=\"16\"",
"cargo:rustc-cfg=interrupts_status_registers=\"2\"",
"cargo:rustc-cfg=uart_ram_size=\"128\"",
"cargo:rustc-cfg=has_dram_region",
],
},
@ -750,6 +754,7 @@ impl Chip {
"interrupts_status_registers=\"2\"",
"rmt_ram_start=\"1610703872\"",
"rmt_channel_ram_size=\"48\"",
"uart_ram_size=\"128\"",
"has_dram_region",
],
cfgs: &[
@ -871,6 +876,7 @@ impl Chip {
"cargo:rustc-cfg=interrupts_status_registers=\"2\"",
"cargo:rustc-cfg=rmt_ram_start=\"1610703872\"",
"cargo:rustc-cfg=rmt_channel_ram_size=\"48\"",
"cargo:rustc-cfg=uart_ram_size=\"128\"",
"cargo:rustc-cfg=has_dram_region",
],
},
@ -990,6 +996,7 @@ impl Chip {
"gpio",
"hmac",
"i2c_master",
"lp_i2c_master",
"i2s",
"interrupts",
"io_mux",
@ -1010,6 +1017,7 @@ impl Chip {
"timergroup",
"twai",
"uart",
"lp_uart",
"ulp_riscv",
"usb_serial_jtag",
"wifi",
@ -1043,9 +1051,12 @@ impl Chip {
"i2c_master_max_bus_timeout=\"31\"",
"i2c_master_ll_intr_mask=\"262143\"",
"i2c_master_fifo_size=\"32\"",
"lp_i2c_master_fifo_size=\"16\"",
"interrupts_status_registers=\"3\"",
"rmt_ram_start=\"1610638336\"",
"rmt_channel_ram_size=\"48\"",
"uart_ram_size=\"128\"",
"lp_uart_ram_size=\"32\"",
"wifi_has_wifi6",
"has_dram_region",
],
@ -1162,6 +1173,7 @@ impl Chip {
"cargo:rustc-cfg=gpio",
"cargo:rustc-cfg=hmac",
"cargo:rustc-cfg=i2c_master",
"cargo:rustc-cfg=lp_i2c_master",
"cargo:rustc-cfg=i2s",
"cargo:rustc-cfg=interrupts",
"cargo:rustc-cfg=io_mux",
@ -1182,6 +1194,7 @@ impl Chip {
"cargo:rustc-cfg=timergroup",
"cargo:rustc-cfg=twai",
"cargo:rustc-cfg=uart",
"cargo:rustc-cfg=lp_uart",
"cargo:rustc-cfg=ulp_riscv",
"cargo:rustc-cfg=usb_serial_jtag",
"cargo:rustc-cfg=wifi",
@ -1215,9 +1228,12 @@ impl Chip {
"cargo:rustc-cfg=i2c_master_max_bus_timeout=\"31\"",
"cargo:rustc-cfg=i2c_master_ll_intr_mask=\"262143\"",
"cargo:rustc-cfg=i2c_master_fifo_size=\"32\"",
"cargo:rustc-cfg=lp_i2c_master_fifo_size=\"16\"",
"cargo:rustc-cfg=interrupts_status_registers=\"3\"",
"cargo:rustc-cfg=rmt_ram_start=\"1610638336\"",
"cargo:rustc-cfg=rmt_channel_ram_size=\"48\"",
"cargo:rustc-cfg=uart_ram_size=\"128\"",
"cargo:rustc-cfg=lp_uart_ram_size=\"32\"",
"cargo:rustc-cfg=wifi_has_wifi6",
"cargo:rustc-cfg=has_dram_region",
],
@ -1373,6 +1389,7 @@ impl Chip {
"interrupts_status_registers=\"2\"",
"rmt_ram_start=\"1610642432\"",
"rmt_channel_ram_size=\"48\"",
"uart_ram_size=\"128\"",
"has_dram_region",
],
cfgs: &[
@ -1523,6 +1540,7 @@ impl Chip {
"cargo:rustc-cfg=interrupts_status_registers=\"2\"",
"cargo:rustc-cfg=rmt_ram_start=\"1610642432\"",
"cargo:rustc-cfg=rmt_channel_ram_size=\"48\"",
"cargo:rustc-cfg=uart_ram_size=\"128\"",
"cargo:rustc-cfg=has_dram_region",
],
},
@ -1669,6 +1687,7 @@ impl Chip {
"rmt_channel_ram_size=\"64\"",
"spi_master_has_octal",
"timergroup_timg_has_timer1",
"uart_ram_size=\"128\"",
"has_dram_region",
],
cfgs: &[
@ -1811,6 +1830,7 @@ impl Chip {
"cargo:rustc-cfg=rmt_channel_ram_size=\"64\"",
"cargo:rustc-cfg=spi_master_has_octal",
"cargo:rustc-cfg=timergroup_timg_has_timer1",
"cargo:rustc-cfg=uart_ram_size=\"128\"",
"cargo:rustc-cfg=has_dram_region",
],
},
@ -1977,6 +1997,7 @@ impl Chip {
"rmt_channel_ram_size=\"48\"",
"spi_master_has_octal",
"timergroup_timg_has_timer1",
"uart_ram_size=\"128\"",
"has_dram_region",
],
cfgs: &[
@ -2139,6 +2160,7 @@ impl Chip {
"cargo:rustc-cfg=rmt_channel_ram_size=\"48\"",
"cargo:rustc-cfg=spi_master_has_octal",
"cargo:rustc-cfg=timergroup_timg_has_timer1",
"cargo:rustc-cfg=uart_ram_size=\"128\"",
"cargo:rustc-cfg=has_dram_region",
],
},
@ -2372,7 +2394,9 @@ impl Config {
println!("cargo:rustc-check-cfg=cfg(lp_core)");
println!("cargo:rustc-check-cfg=cfg(pm_support_beacon_wakeup)");
println!("cargo:rustc-check-cfg=cfg(etm)");
println!("cargo:rustc-check-cfg=cfg(lp_i2c_master)");
println!("cargo:rustc-check-cfg=cfg(parl_io)");
println!("cargo:rustc-check-cfg=cfg(lp_uart)");
println!("cargo:rustc-check-cfg=cfg(ulp_riscv)");
println!("cargo:rustc-check-cfg=cfg(ieee802154)");
println!("cargo:rustc-check-cfg=cfg(i2c_master_can_estimate_nack_reason)");
@ -2430,6 +2454,9 @@ impl Config {
"cargo:rustc-check-cfg=cfg(rmt_ram_start, values(\"1073047552\",\"1610703872\",\"1610638336\",\"1610642432\",\"1061250048\",\"1610704896\"))"
);
println!("cargo:rustc-check-cfg=cfg(rmt_channel_ram_size, values(\"64\",\"48\"))");
println!("cargo:rustc-check-cfg=cfg(uart_ram_size, values(\"128\"))");
println!("cargo:rustc-check-cfg=cfg(lp_i2c_master_fifo_size, values(\"16\"))");
println!("cargo:rustc-check-cfg=cfg(lp_uart_ram_size, values(\"32\"))");
for cfg in self.cfgs {
println!("{cfg}");
}

View File

@ -156,6 +156,12 @@ macro_rules! property {
("timergroup.timg_has_timer1") => {
true
};
("uart.ram_size") => {
128
};
("uart.ram_size", str) => {
stringify!(128)
};
("wifi.has_wifi6") => {
false
};

View File

@ -144,6 +144,12 @@ macro_rules! property {
("timergroup.timg_has_timer1") => {
false
};
("uart.ram_size") => {
128
};
("uart.ram_size", str) => {
stringify!(128)
};
("wifi.has_wifi6") => {
false
};

View File

@ -156,6 +156,12 @@ macro_rules! property {
("timergroup.timg_has_timer1") => {
false
};
("uart.ram_size") => {
128
};
("uart.ram_size", str) => {
stringify!(128)
};
("wifi.has_wifi6") => {
false
};

View File

@ -132,6 +132,12 @@ macro_rules! property {
("i2c_master.fifo_size", str) => {
stringify!(32)
};
("lp_i2c_master.fifo_size") => {
16
};
("lp_i2c_master.fifo_size", str) => {
stringify!(16)
};
("interrupts.status_registers") => {
3
};
@ -156,6 +162,18 @@ macro_rules! property {
("timergroup.timg_has_timer1") => {
false
};
("uart.ram_size") => {
128
};
("uart.ram_size", str) => {
stringify!(128)
};
("lp_uart.ram_size") => {
32
};
("lp_uart.ram_size", str) => {
stringify!(32)
};
("wifi.has_wifi6") => {
true
};

View File

@ -156,6 +156,12 @@ macro_rules! property {
("timergroup.timg_has_timer1") => {
false
};
("uart.ram_size") => {
128
};
("uart.ram_size", str) => {
stringify!(128)
};
}
/// Macro to get the address range of the given memory region.
#[macro_export]

View File

@ -156,6 +156,12 @@ macro_rules! property {
("timergroup.timg_has_timer1") => {
true
};
("uart.ram_size") => {
128
};
("uart.ram_size", str) => {
stringify!(128)
};
("wifi.has_wifi6") => {
false
};

View File

@ -156,6 +156,12 @@ macro_rules! property {
("timergroup.timg_has_timer1") => {
true
};
("uart.ram_size") => {
128
};
("uart.ram_size", str) => {
stringify!(128)
};
("wifi.has_wifi6") => {
false
};

View File

@ -607,6 +607,7 @@ instances = [
{ name = "uart1", sys_instance = "Uart1", tx = "U1TXD", rx = "U1RXD", cts = "U1CTS", rts = "U1RTS" },
{ name = "uart2", sys_instance = "Uart2", tx = "U2TXD", rx = "U2RXD", cts = "U2CTS", rts = "U2RTS" },
]
ram_size = 128
[device.ethernet]
support_status = "not_supported"

View File

@ -261,6 +261,7 @@ instances = [
{ name = "uart0", sys_instance = "Uart0", tx = "U0TXD", rx = "U0RXD", cts = "U0CTS", rts = "U0RTS" },
{ name = "uart1", sys_instance = "Uart1", tx = "U1TXD", rx = "U1RXD", cts = "U1CTS", rts = "U1RTS" },
]
ram_size = 128
# Other drivers which are partially supported but have no other configuration:

View File

@ -307,6 +307,7 @@ instances = [
{ name = "uart0", sys_instance = "Uart0", tx = "U0TXD", rx = "U0RXD", cts = "U0CTS", rts = "U0RTS" },
{ name = "uart1", sys_instance = "Uart1", tx = "U1TXD", rx = "U1RXD", cts = "U1CTS", rts = "U1RTS" },
]
ram_size = 128
[device.ds]
support_status = "not_supported"

View File

@ -425,6 +425,10 @@ has_arbitration_en = true
has_tx_fifo_watermark = true
bus_timeout_is_exponential = true
[device.lp_i2c_master]
support_status = "partial"
fifo_size = 16
[device.i2c_slave]
support_status = "not_supported"
@ -457,6 +461,11 @@ instances = [
{ name = "uart0", sys_instance = "Uart0", tx = "U0TXD", rx = "U0RXD", cts = "U0CTS", rts = "U0RTS" },
{ name = "uart1", sys_instance = "Uart1", tx = "U1TXD", rx = "U1RXD", cts = "U1CTS", rts = "U1RTS" },
]
ram_size = 128
[device.lp_uart]
support_status = "partial"
ram_size = 32
[device.ds]
support_status = "not_supported"

View File

@ -378,6 +378,7 @@ instances = [
{ name = "uart0", sys_instance = "Uart0", tx = "U0TXD", rx = "U0RXD", cts = "U0CTS", rts = "U0RTS" },
{ name = "uart1", sys_instance = "Uart1", tx = "U1TXD", rx = "U1RXD", cts = "U1CTS", rts = "U1RTS" },
]
ram_size = 128
[device.ds]
support_status = "not_supported"

View File

@ -429,6 +429,7 @@ instances = [
{ name = "uart0", sys_instance = "Uart0", tx = "U0TXD", rx = "U0RXD", cts = "U0CTS", rts = "U0RTS" },
{ name = "uart1", sys_instance = "Uart1", tx = "U1TXD", rx = "U1RXD", cts = "U1CTS", rts = "U1RTS" },
]
ram_size = 128
[device.rgb_display] # via SPI and I2S
support_status = "not_supported"

View File

@ -605,6 +605,7 @@ instances = [
{ name = "uart1", sys_instance = "Uart1", tx = "U1TXD", rx = "U1RXD", cts = "U1CTS", rts = "U1RTS" },
{ name = "uart2", sys_instance = "Uart2", tx = "U2TXD", rx = "U2RXD", cts = "U2CTS", rts = "U2RTS" },
]
ram_size = 128
[device.touch]
support_status = "not_supported"

View File

@ -329,6 +329,13 @@ driver_configs![
fifo_size: u32,
}
},
LpI2cMasterProperties {
driver: lp_i2c_master,
name: "LP I2C master",
properties: {
fifo_size: u32,
}
},
I2cSlaveProperties {
driver: i2c_slave,
name: "I2C slave",
@ -468,7 +475,16 @@ driver_configs![
UartProperties<UartInstanceConfig> {
driver: uart,
name: "UART",
properties: {}
properties: {
ram_size: u32,
}
},
LpUartProperties {
driver: lp_uart,
name: "LP UART",
properties: {
ram_size: u32,
}
},
UlpFsmProperties {
driver: ulp_fsm,