mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 12:50:53 +00:00
Move timer instance config into driver metadata (#3626)
* Remove timg_timer1 symbol * Ensure instances exist * Rename timers to timergroup * Remove unnecessary cfg
This commit is contained in:
parent
1b5a85e7d6
commit
793b01beaa
@ -168,7 +168,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
for (key, value) in &cfg {
|
for (key, value) in &cfg {
|
||||||
if let Value::Bool(true) = value {
|
if let Value::Bool(true) = value {
|
||||||
config_symbols.push(key);
|
config_symbols.push(key.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +230,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
// Helper Functions
|
// Helper Functions
|
||||||
|
|
||||||
fn copy_dir_all(
|
fn copy_dir_all(
|
||||||
config_symbols: &[&str],
|
config_symbols: &[String],
|
||||||
cfg: &HashMap<String, Value>,
|
cfg: &HashMap<String, Value>,
|
||||||
src: impl AsRef<Path>,
|
src: impl AsRef<Path>,
|
||||||
dst: impl AsRef<Path>,
|
dst: impl AsRef<Path>,
|
||||||
@ -260,7 +260,7 @@ fn copy_dir_all(
|
|||||||
|
|
||||||
/// A naive pre-processor for linker scripts
|
/// A naive pre-processor for linker scripts
|
||||||
fn preprocess_file(
|
fn preprocess_file(
|
||||||
config: &[&str],
|
config: &[String],
|
||||||
cfg: &HashMap<String, Value>,
|
cfg: &HashMap<String, Value>,
|
||||||
src: impl AsRef<Path>,
|
src: impl AsRef<Path>,
|
||||||
dst: impl AsRef<Path>,
|
dst: impl AsRef<Path>,
|
||||||
@ -279,7 +279,7 @@ fn preprocess_file(
|
|||||||
|
|
||||||
if let Some(condition) = trimmed.strip_prefix("#IF ") {
|
if let Some(condition) = trimmed.strip_prefix("#IF ") {
|
||||||
let should_take = take.iter().all(|v| *v);
|
let should_take = take.iter().all(|v| *v);
|
||||||
let should_take = should_take && config.contains(&condition);
|
let should_take = should_take && config.iter().any(|c| c.as_str() == condition);
|
||||||
take.push(should_take);
|
take.push(should_take);
|
||||||
continue;
|
continue;
|
||||||
} else if trimmed == "#ELSE" {
|
} else if trimmed == "#ELSE" {
|
||||||
|
@ -58,8 +58,9 @@ pub struct WatchdogConfig {
|
|||||||
/// Configures the reset watchdog timer.
|
/// Configures the reset watchdog timer.
|
||||||
rwdt: WatchdogStatus,
|
rwdt: WatchdogStatus,
|
||||||
/// Configures the `timg0` watchdog timer.
|
/// Configures the `timg0` watchdog timer.
|
||||||
|
#[cfg(timergroup_timg0)]
|
||||||
timg0: WatchdogStatus,
|
timg0: WatchdogStatus,
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
/// Configures the `timg1` watchdog timer.
|
/// Configures the `timg1` watchdog timer.
|
||||||
///
|
///
|
||||||
/// By default, the bootloader does not enable this watchdog timer.
|
/// By default, the bootloader does not enable this watchdog timer.
|
||||||
|
@ -308,7 +308,7 @@ unstable_module! {
|
|||||||
// Drivers needed for initialization or they are tightly coupled to something else.
|
// Drivers needed for initialization or they are tightly coupled to something else.
|
||||||
#[cfg(any(adc1, adc2, dac))]
|
#[cfg(any(adc1, adc2, dac))]
|
||||||
pub mod analog;
|
pub mod analog;
|
||||||
#[cfg(any(systimer, timg0, timg1))]
|
#[cfg(any(systimer, timergroup))]
|
||||||
pub mod timer;
|
pub mod timer;
|
||||||
#[cfg(any(lp_clkrst, rtc_cntl))]
|
#[cfg(any(lp_clkrst, rtc_cntl))]
|
||||||
pub mod rtc_cntl;
|
pub mod rtc_cntl;
|
||||||
@ -325,7 +325,6 @@ unstable_driver! {
|
|||||||
pub mod aes;
|
pub mod aes;
|
||||||
#[cfg(assist_debug)]
|
#[cfg(assist_debug)]
|
||||||
pub mod assist_debug;
|
pub mod assist_debug;
|
||||||
#[cfg(any(xtensa, all(riscv, systimer)))]
|
|
||||||
pub mod delay;
|
pub mod delay;
|
||||||
#[cfg(ecc)]
|
#[cfg(ecc)]
|
||||||
pub mod ecc;
|
pub mod ecc;
|
||||||
@ -634,6 +633,7 @@ pub fn init(config: Config) -> Peripherals {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(timergroup_timg0)]
|
||||||
match config.watchdog.timg0() {
|
match config.watchdog.timg0() {
|
||||||
WatchdogStatus::Enabled(duration) => {
|
WatchdogStatus::Enabled(duration) => {
|
||||||
let mut timg0_wd = crate::timer::timg::Wdt::<crate::peripherals::TIMG0<'static>>::new();
|
let mut timg0_wd = crate::timer::timg::Wdt::<crate::peripherals::TIMG0<'static>>::new();
|
||||||
@ -645,7 +645,7 @@ pub fn init(config: Config) -> Peripherals {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
match config.watchdog.timg1() {
|
match config.watchdog.timg1() {
|
||||||
WatchdogStatus::Enabled(duration) => {
|
WatchdogStatus::Enabled(duration) => {
|
||||||
let mut timg1_wd = crate::timer::timg::Wdt::<crate::peripherals::TIMG1<'static>>::new();
|
let mut timg1_wd = crate::timer::timg::Wdt::<crate::peripherals::TIMG1<'static>>::new();
|
||||||
@ -664,9 +664,10 @@ pub fn init(config: Config) -> Peripherals {
|
|||||||
|
|
||||||
rtc.rwdt.disable();
|
rtc.rwdt.disable();
|
||||||
|
|
||||||
|
#[cfg(timergroup_timg0)]
|
||||||
crate::timer::timg::Wdt::<crate::peripherals::TIMG0<'static>>::new().disable();
|
crate::timer::timg::Wdt::<crate::peripherals::TIMG0<'static>>::new().disable();
|
||||||
|
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
crate::timer::timg::Wdt::<crate::peripherals::TIMG1<'static>>::new().disable();
|
crate::timer::timg::Wdt::<crate::peripherals::TIMG1<'static>>::new().disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,7 @@ impl Peripheral {
|
|||||||
Peripheral::UsbDevice,
|
Peripheral::UsbDevice,
|
||||||
#[cfg(systimer)]
|
#[cfg(systimer)]
|
||||||
Peripheral::Systimer,
|
Peripheral::Systimer,
|
||||||
|
#[cfg(timg0)]
|
||||||
Peripheral::Timg0,
|
Peripheral::Timg0,
|
||||||
#[cfg(esp32c6)] // used by some wifi calibration steps.
|
#[cfg(esp32c6)] // used by some wifi calibration steps.
|
||||||
// TODO: We should probably automatically enable this when needed.
|
// TODO: We should probably automatically enable this when needed.
|
||||||
|
@ -60,7 +60,7 @@ use crate::{
|
|||||||
|
|
||||||
#[cfg(systimer)]
|
#[cfg(systimer)]
|
||||||
pub mod systimer;
|
pub mod systimer;
|
||||||
#[cfg(any(timg0, timg1))]
|
#[cfg(timergroup)]
|
||||||
pub mod timg;
|
pub mod timg;
|
||||||
|
|
||||||
/// Timer errors.
|
/// Timer errors.
|
||||||
@ -416,6 +416,7 @@ where
|
|||||||
crate::any_peripheral! {
|
crate::any_peripheral! {
|
||||||
/// Any Timer peripheral.
|
/// Any Timer peripheral.
|
||||||
pub peripheral AnyTimer<'d> {
|
pub peripheral AnyTimer<'d> {
|
||||||
|
#[cfg(timergroup)]
|
||||||
TimgTimer(timg::Timer<'d>),
|
TimgTimer(timg::Timer<'d>),
|
||||||
#[cfg(systimer)]
|
#[cfg(systimer)]
|
||||||
SystimerAlarm(systimer::Alarm<'d>),
|
SystimerAlarm(systimer::Alarm<'d>),
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
use super::Error;
|
use super::Error;
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
use crate::peripherals::TIMG1;
|
use crate::peripherals::TIMG1;
|
||||||
#[cfg(any(esp32c6, esp32h2))]
|
#[cfg(any(esp32c6, esp32h2))]
|
||||||
use crate::soc::constants::TIMG_DEFAULT_CLK_SRC;
|
use crate::soc::constants::TIMG_DEFAULT_CLK_SRC;
|
||||||
@ -84,21 +84,21 @@ use crate::{
|
|||||||
time::{Duration, Instant, Rate},
|
time::{Duration, Instant, Rate},
|
||||||
};
|
};
|
||||||
|
|
||||||
const NUM_TIMG: usize = 1 + cfg!(timg1) as usize;
|
const NUM_TIMG: usize = 1 + cfg!(timergroup_timg1) as usize;
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
// We need no locks when a TIMG has a single timer, and we don't need locks for ESP32
|
// We need no locks when a TIMG has a single timer, and we don't need locks for ESP32
|
||||||
// and S2 where the effective interrupt enable register (config) is not shared between
|
// and S2 where the effective interrupt enable register (config) is not shared between
|
||||||
// the timers.
|
// the timers.
|
||||||
if #[cfg(all(timg_timer1, not(any(esp32, esp32s2))))] {
|
if #[cfg(all(timergroup_timg_has_timer1, not(any(esp32, esp32s2))))] {
|
||||||
use crate::sync::{lock, RawMutex};
|
use crate::sync::{lock, RawMutex};
|
||||||
static INT_ENA_LOCK: [RawMutex; NUM_TIMG] = [const { RawMutex::new() }; NUM_TIMG];
|
static INT_ENA_LOCK: [RawMutex; NUM_TIMG] = [const { RawMutex::new() }; NUM_TIMG];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A timer group consisting of
|
/// A timer group consisting of
|
||||||
#[cfg_attr(not(timg_timer1), doc = "a general purpose timer")]
|
#[cfg_attr(not(timergroup_timg_has_timer1), doc = "a general purpose timer")]
|
||||||
#[cfg_attr(timg_timer1, doc = "2 timers")]
|
#[cfg_attr(timergroup_timg_has_timer1, doc = "2 timers")]
|
||||||
/// and a watchdog timer.
|
/// and a watchdog timer.
|
||||||
pub struct TimerGroup<'d, T>
|
pub struct TimerGroup<'d, T>
|
||||||
where
|
where
|
||||||
@ -108,7 +108,7 @@ where
|
|||||||
/// Timer 0
|
/// Timer 0
|
||||||
pub timer0: Timer<'d>,
|
pub timer0: Timer<'d>,
|
||||||
/// Timer 1
|
/// Timer 1
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
pub timer1: Timer<'d>,
|
pub timer1: Timer<'d>,
|
||||||
/// Watchdog timer
|
/// Watchdog timer
|
||||||
pub wdt: Wdt<T>,
|
pub wdt: Wdt<T>,
|
||||||
@ -125,6 +125,7 @@ pub trait TimerGroupInstance {
|
|||||||
fn wdt_interrupt() -> Interrupt;
|
fn wdt_interrupt() -> Interrupt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(timergroup_timg0)]
|
||||||
impl TimerGroupInstance for TIMG0<'_> {
|
impl TimerGroupInstance for TIMG0<'_> {
|
||||||
fn id() -> u8 {
|
fn id() -> u8 {
|
||||||
0
|
0
|
||||||
@ -186,7 +187,7 @@ impl TimerGroupInstance for TIMG0<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
impl TimerGroupInstance for crate::peripherals::TIMG1<'_> {
|
impl TimerGroupInstance for crate::peripherals::TIMG1<'_> {
|
||||||
fn id() -> u8 {
|
fn id() -> u8 {
|
||||||
1
|
1
|
||||||
@ -262,7 +263,7 @@ where
|
|||||||
register_block: T::register_block(),
|
register_block: T::register_block(),
|
||||||
_lifetime: PhantomData,
|
_lifetime: PhantomData,
|
||||||
},
|
},
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
timer1: Timer {
|
timer1: Timer {
|
||||||
timer: 1,
|
timer: 1,
|
||||||
tg: T::id(),
|
tg: T::id(),
|
||||||
@ -325,11 +326,11 @@ impl super::Timer for Timer<'_> {
|
|||||||
fn async_interrupt_handler(&self) -> InterruptHandler {
|
fn async_interrupt_handler(&self) -> InterruptHandler {
|
||||||
match (self.timer_group(), self.timer_number()) {
|
match (self.timer_group(), self.timer_number()) {
|
||||||
(0, 0) => asynch::timg0_timer0_handler,
|
(0, 0) => asynch::timg0_timer0_handler,
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
(0, 1) => asynch::timg0_timer1_handler,
|
(0, 1) => asynch::timg0_timer1_handler,
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
(1, 0) => asynch::timg1_timer0_handler,
|
(1, 0) => asynch::timg1_timer0_handler,
|
||||||
#[cfg(all(timg_timer1, timg1))]
|
#[cfg(all(timergroup_timg_has_timer1, timergroup_timg1))]
|
||||||
(1, 1) => asynch::timg1_timer1_handler,
|
(1, 1) => asynch::timg1_timer1_handler,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@ -338,11 +339,11 @@ impl super::Timer for Timer<'_> {
|
|||||||
fn peripheral_interrupt(&self) -> Interrupt {
|
fn peripheral_interrupt(&self) -> Interrupt {
|
||||||
match (self.timer_group(), self.timer_number()) {
|
match (self.timer_group(), self.timer_number()) {
|
||||||
(0, 0) => Interrupt::TG0_T0_LEVEL,
|
(0, 0) => Interrupt::TG0_T0_LEVEL,
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
(0, 1) => Interrupt::TG0_T1_LEVEL,
|
(0, 1) => Interrupt::TG0_T1_LEVEL,
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
(1, 0) => Interrupt::TG1_T0_LEVEL,
|
(1, 0) => Interrupt::TG1_T0_LEVEL,
|
||||||
#[cfg(all(timg_timer1, timg1))]
|
#[cfg(all(timergroup_timg_has_timer1, timergroup_timg1))]
|
||||||
(1, 1) => Interrupt::TG1_T1_LEVEL,
|
(1, 1) => Interrupt::TG1_T1_LEVEL,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@ -398,11 +399,11 @@ impl Timer<'_> {
|
|||||||
pub(crate) fn set_interrupt_handler(&self, handler: InterruptHandler) {
|
pub(crate) fn set_interrupt_handler(&self, handler: InterruptHandler) {
|
||||||
let interrupt = match (self.timer_group(), self.timer_number()) {
|
let interrupt = match (self.timer_group(), self.timer_number()) {
|
||||||
(0, 0) => Interrupt::TG0_T0_LEVEL,
|
(0, 0) => Interrupt::TG0_T0_LEVEL,
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
(0, 1) => Interrupt::TG0_T1_LEVEL,
|
(0, 1) => Interrupt::TG0_T1_LEVEL,
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
(1, 0) => Interrupt::TG1_T0_LEVEL,
|
(1, 0) => Interrupt::TG1_T0_LEVEL,
|
||||||
#[cfg(all(timg_timer1, timg1))]
|
#[cfg(all(timergroup_timg_has_timer1, timergroup_timg1))]
|
||||||
(1, 1) => Interrupt::TG1_T1_LEVEL,
|
(1, 1) => Interrupt::TG1_T1_LEVEL,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
@ -560,7 +561,7 @@ impl Timer<'_> {
|
|||||||
.t(self.timer as usize)
|
.t(self.timer as usize)
|
||||||
.config()
|
.config()
|
||||||
.modify(|_, w| w.level_int_en().bit(state));
|
.modify(|_, w| w.level_int_en().bit(state));
|
||||||
} else if #[cfg(timg_timer1)] {
|
} else if #[cfg(timergroup_timg_has_timer1)] {
|
||||||
lock(&INT_ENA_LOCK[self.timer_group() as usize], || {
|
lock(&INT_ENA_LOCK[self.timer_group() as usize], || {
|
||||||
self.register_block()
|
self.register_block()
|
||||||
.int_ena()
|
.int_ena()
|
||||||
@ -828,7 +829,7 @@ mod asynch {
|
|||||||
use crate::asynch::AtomicWaker;
|
use crate::asynch::AtomicWaker;
|
||||||
|
|
||||||
const NUM_WAKERS: usize = {
|
const NUM_WAKERS: usize = {
|
||||||
let timer_per_group = 1 + cfg!(timg_timer1) as usize;
|
let timer_per_group = 1 + cfg!(timergroup_timg_has_timer1) as usize;
|
||||||
NUM_TIMG * timer_per_group
|
NUM_TIMG * timer_per_group
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -859,7 +860,7 @@ mod asynch {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
#[handler]
|
#[handler]
|
||||||
pub(crate) fn timg1_timer0_handler() {
|
pub(crate) fn timg1_timer0_handler() {
|
||||||
handle_irq(Timer {
|
handle_irq(Timer {
|
||||||
@ -870,7 +871,7 @@ mod asynch {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
#[handler]
|
#[handler]
|
||||||
pub(crate) fn timg0_timer1_handler() {
|
pub(crate) fn timg0_timer1_handler() {
|
||||||
handle_irq(Timer {
|
handle_irq(Timer {
|
||||||
@ -881,7 +882,7 @@ mod asynch {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(timg1, timg_timer1))]
|
#[cfg(all(timergroup_timg1, timergroup_timg_has_timer1))]
|
||||||
#[handler]
|
#[handler]
|
||||||
pub(crate) fn timg1_timer1_handler() {
|
pub(crate) fn timg1_timer1_handler() {
|
||||||
handle_irq(Timer {
|
handle_irq(Timer {
|
||||||
|
@ -67,7 +67,6 @@ symbols = [
|
|||||||
"pdma",
|
"pdma",
|
||||||
"phy",
|
"phy",
|
||||||
"psram",
|
"psram",
|
||||||
"timg_timer1",
|
|
||||||
"touch",
|
"touch",
|
||||||
"large_intr_status",
|
"large_intr_status",
|
||||||
"gpio_bank_1",
|
"gpio_bank_1",
|
||||||
@ -108,6 +107,10 @@ channel_ram_size = 64
|
|||||||
[device.spi_master]
|
[device.spi_master]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
|
[device.timergroup]
|
||||||
|
timg_has_timer1 = true
|
||||||
|
instances = [{ name = "timg0" }, { name = "timg1" }]
|
||||||
|
|
||||||
[device.uart]
|
[device.uart]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
@ -146,7 +149,7 @@ status = "not_supported"
|
|||||||
[device.psram]
|
[device.psram]
|
||||||
[device.temp_sensor]
|
[device.temp_sensor]
|
||||||
[device.sleep]
|
[device.sleep]
|
||||||
[device.timers]
|
|
||||||
[device.ulp_fsm]
|
[device.ulp_fsm]
|
||||||
|
|
||||||
## Radio
|
## Radio
|
||||||
|
@ -80,6 +80,9 @@ bus_timeout_is_exponential = true
|
|||||||
[device.spi_master]
|
[device.spi_master]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
|
[device.timergroup]
|
||||||
|
instances = [{ name = "timg0" }]
|
||||||
|
|
||||||
[device.uart]
|
[device.uart]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
@ -103,7 +106,6 @@ status = "supported"
|
|||||||
[device.io_mux]
|
[device.io_mux]
|
||||||
[device.temp_sensor]
|
[device.temp_sensor]
|
||||||
[device.sleep]
|
[device.sleep]
|
||||||
[device.timers]
|
|
||||||
[device.systimer]
|
[device.systimer]
|
||||||
|
|
||||||
## Radio
|
## Radio
|
||||||
|
@ -100,6 +100,9 @@ channel_ram_size = 48
|
|||||||
[device.spi_master]
|
[device.spi_master]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
|
[device.timergroup]
|
||||||
|
instances = [{ name = "timg0" }, { name = "timg1" }]
|
||||||
|
|
||||||
[device.uart]
|
[device.uart]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
@ -129,7 +132,6 @@ status = "not_supported"
|
|||||||
[device.interrupts]
|
[device.interrupts]
|
||||||
[device.io_mux]
|
[device.io_mux]
|
||||||
[device.temp_sensor]
|
[device.temp_sensor]
|
||||||
[device.timers]
|
|
||||||
[device.sleep]
|
[device.sleep]
|
||||||
[device.systimer]
|
[device.systimer]
|
||||||
|
|
||||||
|
@ -131,6 +131,9 @@ channel_ram_size = 48
|
|||||||
[device.spi_master]
|
[device.spi_master]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
|
[device.timergroup]
|
||||||
|
instances = [{ name = "timg0" }, { name = "timg1" }]
|
||||||
|
|
||||||
[device.uart]
|
[device.uart]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
@ -172,7 +175,6 @@ has_wifi6 = true
|
|||||||
[device.sleep]
|
[device.sleep]
|
||||||
[device.temp_sensor]
|
[device.temp_sensor]
|
||||||
[device.systimer]
|
[device.systimer]
|
||||||
[device.timers]
|
|
||||||
[device.ulp_riscv]
|
[device.ulp_riscv]
|
||||||
|
|
||||||
## Radio
|
## Radio
|
||||||
|
@ -113,6 +113,9 @@ channel_ram_size = 48
|
|||||||
[device.spi_master]
|
[device.spi_master]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
|
[device.timergroup]
|
||||||
|
instances = [{ name = "timg0" }, { name = "timg1" }]
|
||||||
|
|
||||||
[device.uart]
|
[device.uart]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
@ -149,7 +152,6 @@ status = "not_supported"
|
|||||||
[device.sleep]
|
[device.sleep]
|
||||||
[device.systimer]
|
[device.systimer]
|
||||||
[device.temp_sensor]
|
[device.temp_sensor]
|
||||||
[device.timers]
|
|
||||||
|
|
||||||
## Radio
|
## Radio
|
||||||
[device.bt]
|
[device.bt]
|
||||||
|
@ -65,7 +65,6 @@ symbols = [
|
|||||||
"psram",
|
"psram",
|
||||||
"psram_dma",
|
"psram_dma",
|
||||||
"ulp_riscv_core",
|
"ulp_riscv_core",
|
||||||
"timg_timer1",
|
|
||||||
"large_intr_status",
|
"large_intr_status",
|
||||||
"gpio_bank_1",
|
"gpio_bank_1",
|
||||||
"spi_octal",
|
"spi_octal",
|
||||||
@ -107,6 +106,10 @@ channel_ram_size = 64
|
|||||||
[device.spi_master]
|
[device.spi_master]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
|
[device.timergroup]
|
||||||
|
timg_has_timer1 = true
|
||||||
|
instances = [{ name = "timg0" }, { name = "timg1" }]
|
||||||
|
|
||||||
[device.uart]
|
[device.uart]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
@ -148,7 +151,6 @@ status = "not_supported"
|
|||||||
[device.psram]
|
[device.psram]
|
||||||
[device.sleep]
|
[device.sleep]
|
||||||
[device.systimer]
|
[device.systimer]
|
||||||
[device.timers]
|
|
||||||
[device.temp_sensor]
|
[device.temp_sensor]
|
||||||
[device.ulp_fsm]
|
[device.ulp_fsm]
|
||||||
[device.ulp_riscv]
|
[device.ulp_riscv]
|
||||||
|
@ -79,7 +79,6 @@ symbols = [
|
|||||||
"psram_dma",
|
"psram_dma",
|
||||||
"octal_psram",
|
"octal_psram",
|
||||||
"ulp_riscv_core",
|
"ulp_riscv_core",
|
||||||
"timg_timer1",
|
|
||||||
"very_large_intr_status",
|
"very_large_intr_status",
|
||||||
"gpio_bank_1",
|
"gpio_bank_1",
|
||||||
"spi_octal",
|
"spi_octal",
|
||||||
@ -127,6 +126,10 @@ channel_ram_size = 48
|
|||||||
[device.spi_master]
|
[device.spi_master]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
|
[device.timergroup]
|
||||||
|
timg_has_timer1 = true
|
||||||
|
instances = [{ name = "timg0" }, { name = "timg1" }]
|
||||||
|
|
||||||
[device.uart]
|
[device.uart]
|
||||||
status = "supported"
|
status = "supported"
|
||||||
|
|
||||||
@ -168,7 +171,6 @@ status = "not_supported"
|
|||||||
[device.sleep]
|
[device.sleep]
|
||||||
[device.systimer]
|
[device.systimer]
|
||||||
[device.temp_sensor]
|
[device.temp_sensor]
|
||||||
[device.timers]
|
|
||||||
[device.ulp_fsm]
|
[device.ulp_fsm]
|
||||||
[device.ulp_riscv]
|
[device.ulp_riscv]
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
use std::{fmt::Write, sync::OnceLock};
|
use std::{fmt::Write, sync::OnceLock};
|
||||||
|
|
||||||
use anyhow::{Result, bail};
|
use anyhow::{Result, bail, ensure};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
@ -257,6 +257,20 @@ impl SupportStatus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An empty configuration, used when a driver just wants to declare that
|
||||||
|
/// it supports a peripheral, but does not have any configuration options.
|
||||||
|
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
struct EmptyInstanceConfig {}
|
||||||
|
|
||||||
|
/// A peripheral instance for which a driver is implemented.
|
||||||
|
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
struct PeriInstance<I> {
|
||||||
|
/// The name of the instance
|
||||||
|
name: String,
|
||||||
|
#[serde(flatten)]
|
||||||
|
instance_config: I,
|
||||||
|
}
|
||||||
|
|
||||||
struct SupportItem {
|
struct SupportItem {
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
config_group: &'static str,
|
config_group: &'static str,
|
||||||
@ -276,9 +290,10 @@ macro_rules! driver_configs {
|
|||||||
struct $struct {
|
struct $struct {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
status: SupportStatus,
|
status: SupportStatus,
|
||||||
// If empty, the driver supports a single instance only.
|
/// The list of peripherals for which this driver is implemented.
|
||||||
|
/// If empty, the driver supports a single instance only.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
instances: Vec<String>,
|
instances: Vec<PeriInstance<EmptyInstanceConfig>>,
|
||||||
$(
|
$(
|
||||||
$(#[$meta])?
|
$(#[$meta])?
|
||||||
$config: $ty,
|
$config: $ty,
|
||||||
@ -362,6 +377,14 @@ macro_rules! driver_configs {
|
|||||||
} )))*
|
} )))*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn driver_instances(&self) -> impl Iterator<Item = String> {
|
||||||
|
// Chain all driver instances from each driver.
|
||||||
|
std::iter::empty()
|
||||||
|
$(.chain(self.$driver.iter().flat_map(|d| {
|
||||||
|
d.instances.iter().map(|i| format!("{}.{}", stringify!($driver), i.name.as_str()))
|
||||||
|
})))*
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all properties of all peripherals.
|
/// Returns an iterator over all properties of all peripherals.
|
||||||
fn properties(&self) -> impl Iterator<Item = (&str, Value)> {
|
fn properties(&self) -> impl Iterator<Item = (&str, Value)> {
|
||||||
// Chain all properties from each driver.
|
// Chain all properties from each driver.
|
||||||
@ -617,10 +640,13 @@ driver_configs![
|
|||||||
properties: {}
|
properties: {}
|
||||||
},
|
},
|
||||||
TimersProperties {
|
TimersProperties {
|
||||||
driver: timers,
|
driver: timergroup,
|
||||||
name: "Timers",
|
name: "Timers",
|
||||||
peripherals: &["timg0", "timg1"],
|
peripherals: &[],
|
||||||
properties: {}
|
properties: {
|
||||||
|
#[serde(default)]
|
||||||
|
timg_has_timer1: bool,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
TouchProperties {
|
TouchProperties {
|
||||||
driver: touch,
|
driver: touch,
|
||||||
@ -702,7 +728,7 @@ pub struct Config {
|
|||||||
impl Config {
|
impl Config {
|
||||||
/// The configuration for the specified chip.
|
/// The configuration for the specified chip.
|
||||||
pub fn for_chip(chip: &Chip) -> &Self {
|
pub fn for_chip(chip: &Chip) -> &Self {
|
||||||
match chip {
|
let config = match chip {
|
||||||
Chip::Esp32 => include_toml!(Config, "../devices/esp32.toml"),
|
Chip::Esp32 => include_toml!(Config, "../devices/esp32.toml"),
|
||||||
Chip::Esp32c2 => include_toml!(Config, "../devices/esp32c2.toml"),
|
Chip::Esp32c2 => include_toml!(Config, "../devices/esp32c2.toml"),
|
||||||
Chip::Esp32c3 => include_toml!(Config, "../devices/esp32c3.toml"),
|
Chip::Esp32c3 => include_toml!(Config, "../devices/esp32c3.toml"),
|
||||||
@ -710,7 +736,11 @@ impl Config {
|
|||||||
Chip::Esp32h2 => include_toml!(Config, "../devices/esp32h2.toml"),
|
Chip::Esp32h2 => include_toml!(Config, "../devices/esp32h2.toml"),
|
||||||
Chip::Esp32s2 => include_toml!(Config, "../devices/esp32s2.toml"),
|
Chip::Esp32s2 => include_toml!(Config, "../devices/esp32s2.toml"),
|
||||||
Chip::Esp32s3 => include_toml!(Config, "../devices/esp32s3.toml"),
|
Chip::Esp32s3 => include_toml!(Config, "../devices/esp32s3.toml"),
|
||||||
}
|
};
|
||||||
|
|
||||||
|
config.validate().expect("Invalid device configuration");
|
||||||
|
|
||||||
|
config
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an empty configuration
|
/// Create an empty configuration
|
||||||
@ -729,6 +759,19 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate(&self) -> Result<()> {
|
||||||
|
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),
|
||||||
|
"Driver {driver} marks an implementation for '{peri}' but this peripheral is not defined for '{}'",
|
||||||
|
self.device.name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// The name of the device.
|
/// The name of the device.
|
||||||
pub fn name(&self) -> String {
|
pub fn name(&self) -> String {
|
||||||
self.device.name.clone()
|
self.device.name.clone()
|
||||||
@ -767,25 +810,31 @@ impl Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// All configuration values for the device.
|
/// All configuration values for the device.
|
||||||
pub fn all(&self) -> impl Iterator<Item = &str> + '_ {
|
pub fn all(&self) -> impl Iterator<Item = String> + '_ {
|
||||||
[
|
[
|
||||||
self.device.name.as_str(),
|
self.device.name.clone(),
|
||||||
self.device.arch.as_ref(),
|
self.device.arch.to_string(),
|
||||||
match self.cores() {
|
match self.cores() {
|
||||||
Cores::Single => "single_core",
|
Cores::Single => String::from("single_core"),
|
||||||
Cores::Multi => "multi_core",
|
Cores::Multi => String::from("multi_core"),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(self.device.peripherals.iter().map(|s| s.as_str()))
|
.chain(self.device.peripherals.iter().cloned())
|
||||||
.chain(self.device.symbols.iter().map(|s| s.as_str()))
|
.chain(self.device.symbols.iter().cloned())
|
||||||
.chain(self.device.peri_config.driver_names())
|
.chain(
|
||||||
|
self.device
|
||||||
|
.peri_config
|
||||||
|
.driver_names()
|
||||||
|
.map(|name| name.to_string()),
|
||||||
|
)
|
||||||
|
.chain(self.device.peri_config.driver_instances())
|
||||||
.chain(
|
.chain(
|
||||||
self.device
|
self.device
|
||||||
.peri_config
|
.peri_config
|
||||||
.properties()
|
.properties()
|
||||||
.filter_map(|(name, value)| match value {
|
.filter_map(|(name, value)| match value {
|
||||||
Value::Boolean(true) => Some(name),
|
Value::Boolean(true) => Some(name.to_string()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -137,14 +137,14 @@ pub use executor::Executor;
|
|||||||
macro_rules! init_embassy {
|
macro_rules! init_embassy {
|
||||||
($peripherals:expr, 2) => {{
|
($peripherals:expr, 2) => {{
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(timg_timer1)] {
|
if #[cfg(timergroup_timg_has_timer1)] {
|
||||||
use esp_hal::timer::timg::TimerGroup;
|
use esp_hal::timer::timg::TimerGroup;
|
||||||
let timg0 = TimerGroup::new($peripherals.TIMG0);
|
let timg0 = TimerGroup::new($peripherals.TIMG0);
|
||||||
esp_hal_embassy::init([
|
esp_hal_embassy::init([
|
||||||
timg0.timer0,
|
timg0.timer0,
|
||||||
timg0.timer1,
|
timg0.timer1,
|
||||||
]);
|
]);
|
||||||
} else if #[cfg(timg1)] {
|
} else if #[cfg(timergroup_timg1)] {
|
||||||
use esp_hal::timer::timg::TimerGroup;
|
use esp_hal::timer::timg::TimerGroup;
|
||||||
let timg0 = TimerGroup::new($peripherals.TIMG0);
|
let timg0 = TimerGroup::new($peripherals.TIMG0);
|
||||||
let timg1 = TimerGroup::new($peripherals.TIMG1);
|
let timg1 = TimerGroup::new($peripherals.TIMG1);
|
||||||
|
@ -94,22 +94,23 @@ mod tests {
|
|||||||
test_async_delay_ns(OneShotTimer::new(alarms.alarm0).into_async(), 10_000).await;
|
test_async_delay_ns(OneShotTimer::new(alarms.alarm0).into_async(), 10_000).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(timergroup_timg0)]
|
||||||
#[test]
|
#[test]
|
||||||
async fn test_timg0_async_delay_ns(ctx: Context) {
|
async fn test_timg0_async_delay_ns(ctx: Context) {
|
||||||
let timg0 = TimerGroup::new(ctx.peripherals.TIMG0);
|
let timg0 = TimerGroup::new(ctx.peripherals.TIMG0);
|
||||||
|
|
||||||
test_async_delay_ns(OneShotTimer::new(timg0.timer0).into_async(), 10_000).await;
|
test_async_delay_ns(OneShotTimer::new(timg0.timer0).into_async(), 10_000).await;
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
test_async_delay_ns(OneShotTimer::new(timg0.timer1).into_async(), 10_000).await;
|
test_async_delay_ns(OneShotTimer::new(timg0.timer1).into_async(), 10_000).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
#[test]
|
#[test]
|
||||||
async fn test_timg1_async_delay_ns(ctx: Context) {
|
async fn test_timg1_async_delay_ns(ctx: Context) {
|
||||||
let timg1 = TimerGroup::new(ctx.peripherals.TIMG1);
|
let timg1 = TimerGroup::new(ctx.peripherals.TIMG1);
|
||||||
|
|
||||||
test_async_delay_ns(OneShotTimer::new(timg1.timer0).into_async(), 10_000).await;
|
test_async_delay_ns(OneShotTimer::new(timg1.timer0).into_async(), 10_000).await;
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
test_async_delay_ns(OneShotTimer::new(timg1.timer1).into_async(), 10_000).await;
|
test_async_delay_ns(OneShotTimer::new(timg1.timer1).into_async(), 10_000).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,22 +122,23 @@ mod tests {
|
|||||||
test_async_delay_us(OneShotTimer::new(alarms.alarm0).into_async(), 10).await;
|
test_async_delay_us(OneShotTimer::new(alarms.alarm0).into_async(), 10).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(timergroup_timg0)]
|
||||||
#[test]
|
#[test]
|
||||||
async fn test_timg0_async_delay_us(ctx: Context) {
|
async fn test_timg0_async_delay_us(ctx: Context) {
|
||||||
let timg0 = TimerGroup::new(ctx.peripherals.TIMG0);
|
let timg0 = TimerGroup::new(ctx.peripherals.TIMG0);
|
||||||
|
|
||||||
test_async_delay_us(OneShotTimer::new(timg0.timer0).into_async(), 10).await;
|
test_async_delay_us(OneShotTimer::new(timg0.timer0).into_async(), 10).await;
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
test_async_delay_us(OneShotTimer::new(timg0.timer1).into_async(), 10).await;
|
test_async_delay_us(OneShotTimer::new(timg0.timer1).into_async(), 10).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
#[test]
|
#[test]
|
||||||
async fn test_timg1_async_delay_us(ctx: Context) {
|
async fn test_timg1_async_delay_us(ctx: Context) {
|
||||||
let timg1 = TimerGroup::new(ctx.peripherals.TIMG1);
|
let timg1 = TimerGroup::new(ctx.peripherals.TIMG1);
|
||||||
|
|
||||||
test_async_delay_us(OneShotTimer::new(timg1.timer0).into_async(), 10).await;
|
test_async_delay_us(OneShotTimer::new(timg1.timer0).into_async(), 10).await;
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
test_async_delay_us(OneShotTimer::new(timg1.timer1).into_async(), 10).await;
|
test_async_delay_us(OneShotTimer::new(timg1.timer1).into_async(), 10).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,22 +150,23 @@ mod tests {
|
|||||||
test_async_delay_ms(OneShotTimer::new(alarms.alarm0).into_async(), 1).await;
|
test_async_delay_ms(OneShotTimer::new(alarms.alarm0).into_async(), 1).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(timergroup_timg0)]
|
||||||
#[test]
|
#[test]
|
||||||
async fn test_timg0_async_delay_ms(ctx: Context) {
|
async fn test_timg0_async_delay_ms(ctx: Context) {
|
||||||
let timg0 = TimerGroup::new(ctx.peripherals.TIMG0);
|
let timg0 = TimerGroup::new(ctx.peripherals.TIMG0);
|
||||||
|
|
||||||
test_async_delay_ms(OneShotTimer::new(timg0.timer0).into_async(), 1).await;
|
test_async_delay_ms(OneShotTimer::new(timg0.timer0).into_async(), 1).await;
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
test_async_delay_ms(OneShotTimer::new(timg0.timer1).into_async(), 1).await;
|
test_async_delay_ms(OneShotTimer::new(timg0.timer1).into_async(), 1).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
#[test]
|
#[test]
|
||||||
async fn test_timg1_async_delay_ms(ctx: Context) {
|
async fn test_timg1_async_delay_ms(ctx: Context) {
|
||||||
let timg1 = TimerGroup::new(ctx.peripherals.TIMG1);
|
let timg1 = TimerGroup::new(ctx.peripherals.TIMG1);
|
||||||
|
|
||||||
test_async_delay_ms(OneShotTimer::new(timg1.timer0).into_async(), 1).await;
|
test_async_delay_ms(OneShotTimer::new(timg1.timer0).into_async(), 1).await;
|
||||||
#[cfg(timg_timer1)]
|
#[cfg(timergroup_timg_has_timer1)]
|
||||||
test_async_delay_ms(OneShotTimer::new(timg1.timer1).into_async(), 1).await;
|
test_async_delay_ms(OneShotTimer::new(timg1.timer1).into_async(), 1).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(timergroup_timg0)]
|
||||||
fn test_feeding_timg0_wdt() {
|
fn test_feeding_timg0_wdt() {
|
||||||
let peripherals = esp_hal::init(
|
let peripherals = esp_hal::init(
|
||||||
Config::default().with_watchdog(
|
Config::default().with_watchdog(
|
||||||
@ -44,7 +45,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(timg1)]
|
#[cfg(timergroup_timg1)]
|
||||||
fn test_feeding_timg1_wdt() {
|
fn test_feeding_timg1_wdt() {
|
||||||
let peripherals = esp_hal::init(
|
let peripherals = esp_hal::init(
|
||||||
Config::default().with_watchdog(
|
Config::default().with_watchdog(
|
||||||
@ -64,6 +65,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[cfg(timergroup_timg0)]
|
||||||
fn test_feeding_timg0_wdt_max_clock() {
|
fn test_feeding_timg0_wdt_max_clock() {
|
||||||
let peripherals = esp_hal::init(
|
let peripherals = esp_hal::init(
|
||||||
Config::default()
|
Config::default()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user