Move some more peripherals to metadata (#3633)

* Remove gpio bank 1 symbol

* Remove intr status width symbols

* Allow virtual periphs, redo ADC/DAC
This commit is contained in:
Dániel Buga 2025-06-17 10:10:12 +02:00 committed by GitHub
parent e05d588f72
commit 891a5a4a8c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 207 additions and 91 deletions

View File

@ -14,7 +14,7 @@ use core::{
};
// We only have to count on devices that have multiple ADCs sharing the same interrupt
#[cfg(all(adc1, adc2))]
#[cfg(all(adc_adc1, adc_adc2))]
use portable_atomic::{AtomicU32, Ordering};
use procmacros::handler;
@ -41,7 +41,7 @@ mod calibration;
// https://github.com/espressif/esp-idf/blob/903af13e8/components/soc/esp32h2/include/soc/regi2c_saradc.h
// https://github.com/espressif/esp-idf/blob/903af13e8/components/soc/esp32h4/include/soc/regi2c_saradc.h
cfg_if::cfg_if! {
if #[cfg(adc1)] {
if #[cfg(adc_adc1)] {
const ADC_VAL_MASK: u16 = 0xfff;
const ADC_CAL_CNT_MAX: u16 = 32;
const ADC_CAL_CHANNEL: u16 = 15;
@ -137,7 +137,7 @@ pub trait RegisterAccess {
fn set_init_code(data: u16);
}
#[cfg(adc1)]
#[cfg(adc_adc1)]
impl RegisterAccess for crate::peripherals::ADC1<'_> {
fn config_onetime_sample(channel: u8, attenuation: u8) {
APB_SARADC::regs().onetime_sample().modify(|_, w| unsafe {
@ -186,7 +186,7 @@ impl RegisterAccess for crate::peripherals::ADC1<'_> {
}
}
#[cfg(adc1)]
#[cfg(adc_adc1)]
impl super::CalibrationAccess for crate::peripherals::ADC1<'_> {
const ADC_CAL_CNT_MAX: u16 = ADC_CAL_CNT_MAX;
const ADC_CAL_CHANNEL: u16 = ADC_CAL_CHANNEL;
@ -211,7 +211,7 @@ impl super::CalibrationAccess for crate::peripherals::ADC1<'_> {
}
}
#[cfg(adc2)]
#[cfg(adc_adc2)]
impl RegisterAccess for crate::peripherals::ADC2<'_> {
fn config_onetime_sample(channel: u8, attenuation: u8) {
APB_SARADC::regs().onetime_sample().modify(|_, w| unsafe {
@ -258,7 +258,7 @@ impl RegisterAccess for crate::peripherals::ADC2<'_> {
}
}
#[cfg(adc2)]
#[cfg(adc_adc2)]
impl super::CalibrationAccess for crate::peripherals::ADC2<'_> {
const ADC_CAL_CNT_MAX: u16 = ADC_CAL_CNT_MAX;
const ADC_CAL_CHANNEL: u16 = ADC_CAL_CHANNEL;
@ -419,7 +419,7 @@ impl<ADCI> InterruptConfigurable for Adc<'_, ADCI, Blocking> {
}
}
#[cfg(adc1)]
#[cfg(adc_adc1)]
impl super::AdcCalEfuse for crate::peripherals::ADC1<'_> {
fn init_code(atten: Attenuation) -> Option<u16> {
Efuse::rtc_calib_init_code(1, atten)
@ -434,7 +434,7 @@ impl super::AdcCalEfuse for crate::peripherals::ADC1<'_> {
}
}
#[cfg(adc2)]
#[cfg(adc_adc2)]
impl super::AdcCalEfuse for crate::peripherals::ADC2<'_> {
fn init_code(atten: Attenuation) -> Option<u16> {
Efuse::rtc_calib_init_code(2, atten)
@ -575,17 +575,17 @@ where
}
}
#[cfg(all(adc1, adc2))]
#[cfg(all(adc_adc1, adc_adc2))]
static ASYNC_ADC_COUNT: AtomicU32 = AtomicU32::new(0);
pub(super) fn acquire_async_adc() {
#[cfg(all(adc1, adc2))]
#[cfg(all(adc_adc1, adc_adc2))]
ASYNC_ADC_COUNT.fetch_add(1, Ordering::Relaxed);
}
pub(super) fn release_async_adc() -> bool {
cfg_if::cfg_if! {
if #[cfg(all(adc1, adc2))] {
if #[cfg(all(adc_adc1, adc_adc2))] {
ASYNC_ADC_COUNT.fetch_sub(1, Ordering::Relaxed) == 1
} else {
true
@ -598,12 +598,12 @@ pub(crate) fn adc_interrupt_handler() {
let saradc = APB_SARADC::regs();
let interrupt_status = saradc.int_st().read();
#[cfg(adc1)]
#[cfg(adc_adc1)]
if interrupt_status.adc1_done().bit_is_set() {
unsafe { handle_async(crate::peripherals::ADC1::steal()) }
}
#[cfg(adc2)]
#[cfg(adc_adc2)]
if interrupt_status.adc2_done().bit_is_set() {
unsafe { handle_async(crate::peripherals::ADC2::steal()) }
}
@ -629,7 +629,7 @@ pub trait Instance: crate::private::Sealed {
fn waker() -> &'static AtomicWaker;
}
#[cfg(adc1)]
#[cfg(adc_adc1)]
impl Instance for crate::peripherals::ADC1<'_> {
fn enable_interrupt() {
APB_SARADC::regs()
@ -656,7 +656,7 @@ impl Instance for crate::peripherals::ADC1<'_> {
}
}
#[cfg(adc2)]
#[cfg(adc_adc2)]
impl Instance for crate::peripherals::ADC2<'_> {
fn enable_interrupt() {
APB_SARADC::regs()

View File

@ -121,12 +121,14 @@ pub trait Instance: crate::private::Sealed {
}
}
#[cfg(dac_dac1)]
impl<'d> Instance for crate::peripherals::DAC1<'d> {
const INDEX: usize = 0;
type Pin = Dac1Gpio<'d>;
}
#[cfg(dac_dac2)]
impl<'d> Instance for crate::peripherals::DAC2<'d> {
const INDEX: usize = 1;

View File

@ -5,7 +5,7 @@
//! available on the device. For more information about a peripheral driver,
//! please refer to the relevant module documentation.
#[cfg(any(adc1, adc2))]
#[cfg(adc)]
pub mod adc;
#[cfg(dac)]
pub mod dac;

View File

@ -207,12 +207,12 @@ pub(super) extern "C" fn user_gpio_interrupt_handler() {
fn interrupt_status() -> [(GpioBank, u32); GpioBank::COUNT] {
let intrs_bank0 = InterruptStatusRegisterAccess::Bank0.interrupt_status_read();
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
let intrs_bank1 = InterruptStatusRegisterAccess::Bank1.interrupt_status_read();
[
(GpioBank::_0, intrs_bank0),
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
(GpioBank::_1, intrs_bank1),
]
}

View File

@ -466,7 +466,7 @@ pub trait TouchPin: Pin {
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum GpioBank {
_0,
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
_1,
}
@ -480,7 +480,7 @@ impl GpioBank {
fn offset(self) -> u8 {
match self {
Self::_0 => 0,
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
Self::_1 => 32,
}
}
@ -498,7 +498,7 @@ impl GpioBank {
Self::_0 => GPIO::regs()
.enable_w1tc()
.write(|w| unsafe { w.bits(word) }),
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
Self::_1 => GPIO::regs()
.enable1_w1tc()
.write(|w| unsafe { w.bits(word) }),
@ -510,7 +510,7 @@ impl GpioBank {
Self::_0 => GPIO::regs()
.enable_w1ts()
.write(|w| unsafe { w.bits(word) }),
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
Self::_1 => GPIO::regs()
.enable1_w1ts()
.write(|w| unsafe { w.bits(word) }),
@ -520,7 +520,7 @@ impl GpioBank {
fn read_input(self) -> u32 {
match self {
Self::_0 => GPIO::regs().in_().read().bits(),
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
Self::_1 => GPIO::regs().in1().read().bits(),
}
}
@ -528,7 +528,7 @@ impl GpioBank {
fn read_output(self) -> u32 {
match self {
Self::_0 => GPIO::regs().out().read().bits(),
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
Self::_1 => GPIO::regs().out1().read().bits(),
}
}
@ -536,7 +536,7 @@ impl GpioBank {
fn read_interrupt_status(self) -> u32 {
match self {
Self::_0 => GPIO::regs().status().read().bits(),
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
Self::_1 => GPIO::regs().status1().read().bits(),
}
}
@ -546,7 +546,7 @@ impl GpioBank {
Self::_0 => GPIO::regs()
.status_w1tc()
.write(|w| unsafe { w.bits(word) }),
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
Self::_1 => GPIO::regs()
.status1_w1tc()
.write(|w| unsafe { w.bits(word) }),
@ -564,7 +564,7 @@ impl GpioBank {
fn write_output_set(self, word: u32) {
match self {
Self::_0 => GPIO::regs().out_w1ts().write(|w| unsafe { w.bits(word) }),
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
Self::_1 => GPIO::regs().out1_w1ts().write(|w| unsafe { w.bits(word) }),
};
}
@ -572,7 +572,7 @@ impl GpioBank {
fn write_output_clear(self, word: u32) {
match self {
Self::_0 => GPIO::regs().out_w1tc().write(|w| unsafe { w.bits(word) }),
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
Self::_1 => GPIO::regs().out1_w1tc().write(|w| unsafe { w.bits(word) }),
};
}
@ -1777,7 +1777,7 @@ impl private::Sealed for AnyPin<'_> {}
impl<'lt> AnyPin<'lt> {
fn bank(&self) -> GpioBank {
#[cfg(gpio_bank_1)]
#[cfg(gpio_has_bank_1)]
if self.number() >= 32 {
return GpioBank::_1;
}

View File

@ -149,14 +149,7 @@ impl InterruptHandler {
}
}
#[cfg(large_intr_status)]
const STATUS_WORDS: usize = 3;
#[cfg(very_large_intr_status)]
const STATUS_WORDS: usize = 4;
#[cfg(not(any(large_intr_status, very_large_intr_status)))]
const STATUS_WORDS: usize = 2;
const STATUS_WORDS: usize = property!("interrupts.status_registers");
/// Representation of peripheral-interrupt status bits.
#[derive(Clone, Copy, Default, Debug)]
@ -171,21 +164,21 @@ impl InterruptStatus {
}
}
#[cfg(large_intr_status)]
#[cfg(interrupts_status_registers = "3")]
const fn from(w0: u32, w1: u32, w2: u32) -> Self {
Self {
status: [w0, w1, w2],
}
}
#[cfg(very_large_intr_status)]
#[cfg(interrupts_status_registers = "4")]
const fn from(w0: u32, w1: u32, w2: u32, w3: u32) -> Self {
Self {
status: [w0, w1, w2, w3],
}
}
#[cfg(not(any(large_intr_status, very_large_intr_status)))]
#[cfg(interrupts_status_registers = "2")]
const fn from(w0: u32, w1: u32) -> Self {
Self { status: [w0, w1] }
}
@ -213,7 +206,7 @@ impl BitAnd for InterruptStatus {
type Output = InterruptStatus;
fn bitand(self, rhs: Self) -> Self::Output {
#[cfg(large_intr_status)]
#[cfg(interrupts_status_registers = "3")]
return Self::Output {
status: [
self.status[0] & rhs.status[0],
@ -222,7 +215,7 @@ impl BitAnd for InterruptStatus {
],
};
#[cfg(very_large_intr_status)]
#[cfg(interrupts_status_registers = "4")]
return Self::Output {
status: [
self.status[0] & rhs.status[0],
@ -232,7 +225,7 @@ impl BitAnd for InterruptStatus {
],
};
#[cfg(not(any(large_intr_status, very_large_intr_status)))]
#[cfg(interrupts_status_registers = "2")]
return Self::Output {
status: [
self.status[0] & rhs.status[0],

View File

@ -301,13 +301,13 @@ pub fn disable(_core: Cpu, interrupt: Interrupt) {
#[inline]
pub fn status(_core: Cpu) -> InterruptStatus {
cfg_if::cfg_if! {
if #[cfg(large_intr_status)] {
if #[cfg(interrupts_status_registers = "3")] {
InterruptStatus::from(
INTERRUPT_CORE0::regs().intr_status_reg_0().read().bits(),
INTERRUPT_CORE0::regs().intr_status_reg_1().read().bits(),
INTERRUPT_CORE0::regs().int_status_reg_2().read().bits(),
)
} else if #[cfg(very_large_intr_status)] {
} else if #[cfg(interrupts_status_registers = "4")] {
InterruptStatus::from(
INTERRUPT_CORE0::regs().intr_status_reg_0().read().bits(),
INTERRUPT_CORE0::regs().intr_status_reg_1().read().bits(),

View File

@ -230,7 +230,7 @@ pub fn clear(_core: Cpu, which: CpuInterrupt) {
}
/// Get status of peripheral interrupts
#[cfg(large_intr_status)]
#[cfg(interrupts_status_registers = "3")]
pub fn status(core: Cpu) -> InterruptStatus {
unsafe {
match core {
@ -268,7 +268,7 @@ pub fn status(core: Cpu) -> InterruptStatus {
}
/// Get status of peripheral interrupts
#[cfg(very_large_intr_status)]
#[cfg(interrupts_status_registers = "4")]
pub fn status(core: Cpu) -> InterruptStatus {
unsafe {
match core {

View File

@ -306,7 +306,7 @@ unstable_module! {
#[doc(hidden)]
pub mod sync;
// Drivers needed for initialization or they are tightly coupled to something else.
#[cfg(any(adc1, adc2, dac))]
#[cfg(any(adc, dac))]
pub mod analog;
#[cfg(any(systimer, timergroup))]
pub mod timer;

View File

@ -59,17 +59,19 @@ peripherals = [
"uhci1",
]
symbols = [
# Additional peripherals defined by us (the developers):
virtual_peripherals = [
"adc1",
"adc2",
"dac",
"dac1",
"dac2",
]
symbols = [
# Additional peripherals defined by us (the developers):
"pdma",
"phy",
"psram",
"touch",
"large_intr_status",
"gpio_bank_1",
# ROM capabilities
"rom_crc_le",
@ -85,8 +87,23 @@ symbols = [
memory = [{ name = "dram", start = 0x3FFA_E000, end = 0x4000_0000 }]
[device.adc]
status = "partial"
instances = [
{ name = "adc1" },
{ name = "adc2" },
]
[device.dac]
status = "partial"
instances = [
{ name = "dac1" },
{ name = "dac2" },
]
[device.gpio]
status = "supported"
has_bank_1 = true
[device.i2c_master]
status = "supported"
@ -100,6 +117,10 @@ i2c0_data_register_ahb_address = 0x6001301c
[device.i2c_slave]
status = "not_supported"
[device.interrupts]
status = "partial"
status_registers = 3
[device.rmt]
status = "partial"
ram_start = 0x3ff56800
@ -143,10 +164,7 @@ status = "not_supported"
[device.twai]
## Miscellaneous
[device.adc]
[device.dac]
[device.dma]
[device.interrupts]
[device.io_mux]
[device.psram]
[device.temp_sensor]

View File

@ -40,9 +40,12 @@ peripherals = [
"xts_aes",
]
virtual_peripherals = [
"adc1",
]
symbols = [
# Additional peripherals defined by us (the developers):
"adc1",
"assist_debug_sp_monitor",
"gdma",
"phy",
@ -61,6 +64,12 @@ symbols = [
memory = [{ name = "dram", start = 0x3FCA_0000, end = 0x3FCE_0000 }]
[device.adc]
status = "partial"
instances = [
{ name = "adc1" },
]
[device.gpio]
status = "supported"
@ -78,6 +87,10 @@ has_arbitration_en = true
has_tx_fifo_watermark = true
bus_timeout_is_exponential = true
[device.interrupts]
status = "partial"
status_registers = 2
[device.spi_master]
status = "supported"
instances = [{ name = "spi2" }]
@ -102,9 +115,7 @@ status = "supported"
## Miscellaneous
[device.assist_debug]
[device.adc]
[device.dma]
[device.interrupts]
[device.io_mux]
[device.temp_sensor]
[device.sleep]

View File

@ -51,10 +51,13 @@ peripherals = [
"xts_aes",
]
symbols = [
# Additional peripherals defined by us (the developers):
virtual_peripherals = [
"adc1",
"adc2",
]
symbols = [
# Additional peripherals defined by us (the developers):
"assist_debug_sp_monitor",
"assist_debug_region_monitor",
"gdma",
@ -75,6 +78,12 @@ symbols = [
memory = [{ name = "dram", start = 0x3FC8_0000, end = 0x3FCE_0000 }]
[device.adc]
status = "partial"
instances = [
{ name = "adc1" },
{ name = "adc2" },
]
[device.gpio]
status = "supported"
@ -93,6 +102,10 @@ has_arbitration_en = true
has_tx_fifo_watermark = true
bus_timeout_is_exponential = true
[device.interrupts]
status = "partial"
status_registers = 2
[device.rmt]
status = "partial"
ram_start = 0x60016400
@ -128,10 +141,8 @@ status = "not_supported"
[device.usb_serial_jtag]
## Miscellaneous
[device.adc]
[device.assist_debug]
[device.dma]
[device.interrupts]
[device.io_mux]
[device.temp_sensor]
[device.sleep]

View File

@ -77,13 +77,15 @@ peripherals = [
"usb_device",
]
virtual_peripherals = [
"adc1",
]
symbols = [
# Additional peripherals defined by us (the developers):
"adc1",
"assist_debug_sp_monitor",
"assist_debug_region_monitor",
"gdma",
"large_intr_status",
"plic",
"phy",
"lp_core",
@ -105,6 +107,12 @@ symbols = [
memory = [{ name = "dram", start = 0x4080_0000, end = 0x4088_0000 }]
[device.adc]
status = "partial"
instances = [
{ name = "adc1" },
]
[device.gpio]
status = "supported"
@ -124,6 +132,10 @@ has_arbitration_en = true
has_tx_fifo_watermark = true
bus_timeout_is_exponential = true
[device.interrupts]
status = "partial"
status_registers = 3
[device.rmt]
status = "partial"
ram_start = 0x60006400
@ -168,11 +180,9 @@ has_wifi6 = true
[device.usb_serial_jtag]
## Miscellaneous
[device.adc]
[device.assist_debug]
[device.dma]
[device.etm]
[device.interrupts]
[device.io_mux]
[device.sleep]
[device.temp_sensor]

View File

@ -69,9 +69,12 @@ peripherals = [
"usb_device",
]
virtual_peripherals = [
"adc1",
]
symbols = [
# Additional peripherals defined by us (the developers):
"adc1",
"assist_debug_sp_monitor",
"assist_debug_region_monitor",
"gdma",
@ -87,6 +90,12 @@ symbols = [
memory = [{ name = "dram", start = 0x4080_0000, end = 0x4085_0000 }]
[device.adc]
status = "partial"
instances = [
{ name = "adc1" },
]
[device.gpio]
status = "supported"
@ -106,6 +115,10 @@ has_arbitration_en = true
has_tx_fifo_watermark = true
bus_timeout_is_exponential = true
[device.interrupts]
status = "partial"
status_registers = 2
[device.rmt]
status = "partial"
ram_start = 0x60007400
@ -145,11 +158,9 @@ status = "not_supported"
[device.usb_serial_jtag]
## Miscellaneous
[device.adc]
[device.assist_debug]
[device.dma]
[device.etm]
[device.interrupts]
[device.io_mux]
[device.sleep]
[device.systimer]

View File

@ -55,18 +55,20 @@ peripherals = [
"xts_aes",
]
symbols = [
# Additional peripherals defined by us (the developers):
virtual_peripherals = [
"adc1",
"adc2",
"dac",
"dac1",
"dac2",
]
symbols = [
# Additional peripherals defined by us (the developers):
"pdma",
"phy",
"psram",
"psram_dma",
"ulp_riscv_core",
"large_intr_status",
"gpio_bank_1",
"spi_octal",
# ROM capabilities
@ -85,8 +87,23 @@ symbols = [
memory = [{ name = "dram", start = 0x3FFB_0000, end = 0x4000_0000 }]
[device.adc]
status = "partial"
instances = [
{ name = "adc1" },
{ name = "adc2" },
]
[device.dac]
status = "partial"
instances = [
{ name = "dac1" },
{ name = "dac2" },
]
[device.gpio]
status = "supported"
has_bank_1 = true
[device.i2c_master]
status = "supported"
@ -99,6 +116,10 @@ separate_filter_config_registers = true
has_arbitration_en = true
i2c0_data_register_ahb_address = 0x6001301c
[device.interrupts]
status = "partial"
status_registers = 3
[device.rmt]
status = "partial"
ram_start = 0x3f416400
@ -145,10 +166,7 @@ status = "not_supported"
[device.usb_otg]
## Miscellaneous
[device.adc]
[device.dac]
[device.dma]
[device.interrupts]
[device.io_mux]
[device.psram]
[device.sleep]

View File

@ -68,10 +68,13 @@ peripherals = [
"xts_aes",
]
symbols = [
# Additional peripherals defined by us (the developers):
virtual_peripherals = [
"adc1",
"adc2",
]
symbols = [
# Additional peripherals defined by us (the developers):
"assist_debug_region_monitor",
"gdma",
"phy",
@ -79,8 +82,6 @@ symbols = [
"psram_dma",
"octal_psram",
"ulp_riscv_core",
"very_large_intr_status",
"gpio_bank_1",
"spi_octal",
# ROM capabilities
@ -101,8 +102,16 @@ symbols = [
memory = [{ name = "dram", start = 0x3FC8_8000, end = 0x3FD0_0000 }]
[device.adc]
status = "partial"
instances = [
{ name = "adc1" },
{ name = "adc2" },
]
[device.gpio]
status = "supported"
has_bank_1 = true
[device.i2c_master]
status = "supported"
@ -119,6 +128,10 @@ has_arbitration_en = true
has_tx_fifo_watermark = true
bus_timeout_is_exponential = true
[device.interrupts]
status = "partial"
status_registers = 4
[device.rmt]
status = "partial"
ram_start = 0x60016800
@ -164,10 +177,8 @@ status = "not_supported"
[device.usb_serial_jtag]
## Miscellaneous
[device.adc]
[device.assist_debug]
[device.dma]
[device.interrupts]
[device.io_mux]
[device.psram]
[device.sleep]

View File

@ -1,5 +1,5 @@
use core::str::FromStr;
use std::{fmt::Write, sync::OnceLock};
use std::{collections::HashMap, fmt::Write, sync::OnceLock};
use anyhow::{Result, bail, ensure};
use proc_macro2::TokenStream;
@ -192,6 +192,8 @@ struct Device {
trm: String,
peripherals: Vec<String>,
// For now, this is only used to double-check the configuration.
virtual_peripherals: Vec<String>,
symbols: Vec<String>,
memory: Vec<MemoryRegion>,
@ -409,7 +411,7 @@ driver_configs![
AdcProperties {
driver: adc,
name: "ADC",
peripherals: &["adc1", "adc2"],
peripherals: &[],
properties: {}
},
AesProperties {
@ -464,7 +466,10 @@ driver_configs![
driver: gpio,
name: "GPIO",
peripherals: &["gpio"],
properties: {}
properties: {
#[serde(default)]
has_bank_1: bool,
}
},
HmacProperties {
driver: hmac,
@ -520,7 +525,9 @@ driver_configs![
driver: interrupts,
name: "Interrupts",
peripherals: &[],
properties: {}
properties: {
status_registers: u32,
}
},
IoMuxProperties {
driver: io_mux,
@ -752,6 +759,7 @@ impl Config {
cores: 1,
trm: "".to_owned(),
peripherals: Vec::new(),
virtual_peripherals: Vec::new(),
symbols: Vec::new(),
memory: Vec::new(),
peri_config: PeriConfig::default(),
@ -763,7 +771,8 @@ impl Config {
for instance in self.device.peri_config.driver_instances() {
let (driver, peri) = instance.split_once('.').unwrap();
ensure!(
self.device.peripherals.iter().any(|p| p == peri),
self.device.peripherals.iter().any(|p| p == peri)
|| self.device.virtual_peripherals.iter().any(|p| p == peri),
"Driver {driver} marks an implementation for '{peri}' but this peripheral is not defined for '{}'",
self.device.name
);
@ -840,6 +849,7 @@ impl Config {
.properties()
.filter_map(|(name, value)| match value {
Value::Boolean(true) => Some(name.to_string()),
Value::Number(value) => Some(format!("{name}=\"{value}\"")),
_ => None,
}),
)
@ -952,13 +962,34 @@ fn define_all_possible_symbols() {
// Used by our documentation builds to prevent the huge red warning banner.
println!("cargo:rustc-check-cfg=cfg(not_really_docsrs)");
let mut cfg_values: HashMap<String, Vec<String>> = HashMap::new();
for chip in Chip::iter() {
let config = Config::for_chip(&chip);
for symbol in config.all() {
// https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-check-cfg
println!("cargo:rustc-check-cfg=cfg({})", symbol.replace('.', "_"));
if let Some((symbol_name, symbol_value)) = symbol.split_once('=') {
// cfg's with values need special syntax, so let's collect all
// of them separately.
let symbol_name = symbol_name.replace('.', "_");
let entry = cfg_values.entry(symbol_name).or_default();
// Avoid duplicates in the same cfg.
if !entry.contains(&symbol_value.to_string()) {
entry.push(symbol_value.to_string());
}
} else {
// https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-check-cfg
println!("cargo:rustc-check-cfg=cfg({})", symbol.replace('.', "_"));
}
}
}
// Now output all cfgs with values.
for (symbol_name, symbol_values) in cfg_values {
println!(
"cargo:rustc-check-cfg=cfg({symbol_name}, values({}))",
symbol_values.join(",")
);
}
}
pub fn generate_chip_support_status(output: &mut impl Write) -> std::fmt::Result {