mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-29 05:10:55 +00:00
PCNT cleanup (part2) && SYSTIMER update (#1520)
* PCNT cleanup (part2) * SYSTIMER update pac * etm update
This commit is contained in:
parent
f70ef1a593
commit
ee4424961e
@ -52,13 +52,13 @@ xtensa-lx = { version = "0.9.0", optional = true }
|
||||
# IMPORTANT:
|
||||
# Each supported device MUST have its PAC included below along with a
|
||||
# corresponding feature.
|
||||
esp32 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "d7ee5ce", features = ["critical-section", "rt"], optional = true }
|
||||
esp32c2 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "d7ee5ce", features = ["critical-section", "rt"], optional = true }
|
||||
esp32c3 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "d7ee5ce", features = ["critical-section", "rt"], optional = true }
|
||||
esp32c6 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "d7ee5ce", features = ["critical-section", "rt"], optional = true }
|
||||
esp32h2 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "d7ee5ce", features = ["critical-section", "rt"], optional = true }
|
||||
esp32s2 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "d7ee5ce", features = ["critical-section", "rt"], optional = true }
|
||||
esp32s3 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "d7ee5ce", features = ["critical-section", "rt"], optional = true }
|
||||
esp32 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "c90dc69", features = ["critical-section", "rt"], optional = true }
|
||||
esp32c2 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "c90dc69", features = ["critical-section", "rt"], optional = true }
|
||||
esp32c3 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "c90dc69", features = ["critical-section", "rt"], optional = true }
|
||||
esp32c6 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "c90dc69", features = ["critical-section", "rt"], optional = true }
|
||||
esp32h2 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "c90dc69", features = ["critical-section", "rt"], optional = true }
|
||||
esp32s2 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "c90dc69", features = ["critical-section", "rt"], optional = true }
|
||||
esp32s3 = { git = "https://github.com/esp-rs/esp-pacs/", rev = "c90dc69", features = ["critical-section", "rt"], optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "riscv32")'.dependencies]
|
||||
esp-riscv-rt = { version = "0.8.0", path = "../esp-riscv-rt" }
|
||||
|
@ -314,11 +314,11 @@ fn enable_event_channel(channel: u8, pin: u8) {
|
||||
let gpio_sd = unsafe { crate::peripherals::GPIO_SD::steal() };
|
||||
gpio_sd
|
||||
.etm_event_ch_cfg(channel as usize)
|
||||
.modify(|_, w| w.etm_ch0_event_en().clear_bit());
|
||||
.modify(|_, w| w.event_en().clear_bit());
|
||||
gpio_sd
|
||||
.etm_event_ch_cfg(channel as usize)
|
||||
.modify(|_, w| unsafe { w.etm_ch0_event_sel().bits(pin) });
|
||||
.modify(|_, w| unsafe { w.event_sel().bits(pin) });
|
||||
gpio_sd
|
||||
.etm_event_ch_cfg(channel as usize)
|
||||
.modify(|_, w| w.etm_ch0_event_en().set_bit());
|
||||
.modify(|_, w| w.event_en().set_bit());
|
||||
}
|
||||
|
@ -18,36 +18,14 @@ use crate::{
|
||||
/// Channel number
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub enum Number {
|
||||
Channel0,
|
||||
Channel1,
|
||||
Channel0 = 0,
|
||||
Channel1 = 1,
|
||||
}
|
||||
|
||||
/// PCNT channel action on signal edge
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum EdgeMode {
|
||||
/// Hold current count value
|
||||
Hold = 0,
|
||||
/// Increase count value
|
||||
#[default]
|
||||
Increment = 1,
|
||||
/// Decrease count value
|
||||
Decrement = 2,
|
||||
}
|
||||
|
||||
/// PCNT channel action on control level
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
pub enum CtrlMode {
|
||||
/// Keep current count mode
|
||||
Keep = 0,
|
||||
/// Invert current count mode (increase -> decrease, decrease -> increase)
|
||||
#[default]
|
||||
Reverse = 1,
|
||||
/// Hold current count value
|
||||
Disable = 2,
|
||||
}
|
||||
pub use crate::peripherals::pcnt::unit::conf0::{CTRL_MODE as CtrlMode, EDGE_MODE as EdgeMode};
|
||||
|
||||
/// Pulse Counter configuration for a single channel
|
||||
#[derive(Debug, Copy, Clone, Default)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Config {
|
||||
/// PCNT low control mode
|
||||
pub lctrl_mode: CtrlMode,
|
||||
@ -61,6 +39,19 @@ pub struct Config {
|
||||
pub invert_sig: bool,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
lctrl_mode: CtrlMode::Reverse,
|
||||
hctrl_mode: CtrlMode::Reverse,
|
||||
pos_edge: EdgeMode::Increment,
|
||||
neg_edge: EdgeMode::Increment,
|
||||
invert_ctrl: false,
|
||||
invert_sig: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// PcntPin can be always high, always low, or an actual pin
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PcntSource {
|
||||
@ -96,33 +87,16 @@ impl Channel {
|
||||
/// Configure the channel
|
||||
pub fn configure(&mut self, ctrl_signal: PcntSource, edge_signal: PcntSource, config: Config) {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
let conf0 = pcnt.u_conf0(self.unit as usize);
|
||||
match self.channel {
|
||||
Number::Channel0 => {
|
||||
conf0.modify(|_, w| unsafe {
|
||||
w.ch0_hctrl_mode()
|
||||
.bits(config.hctrl_mode as u8)
|
||||
.ch0_lctrl_mode()
|
||||
.bits(config.lctrl_mode as u8)
|
||||
.ch0_neg_mode()
|
||||
.bits(config.neg_edge as u8)
|
||||
.ch0_pos_mode()
|
||||
.bits(config.pos_edge as u8)
|
||||
});
|
||||
}
|
||||
Number::Channel1 => {
|
||||
conf0.modify(|_, w| unsafe {
|
||||
w.ch1_hctrl_mode()
|
||||
.bits(config.hctrl_mode as u8)
|
||||
.ch1_lctrl_mode()
|
||||
.bits(config.lctrl_mode as u8)
|
||||
.ch1_neg_mode()
|
||||
.bits(config.neg_edge as u8)
|
||||
.ch1_pos_mode()
|
||||
.bits(config.pos_edge as u8)
|
||||
});
|
||||
}
|
||||
}
|
||||
let conf0 = pcnt.unit(self.unit as usize).conf0();
|
||||
|
||||
conf0.modify(|_, w| {
|
||||
w.ch_hctrl_mode(self.channel as u8)
|
||||
.variant(config.hctrl_mode);
|
||||
w.ch_lctrl_mode(self.channel as u8)
|
||||
.variant(config.lctrl_mode);
|
||||
w.ch_neg_mode(self.channel as u8).variant(config.neg_edge);
|
||||
w.ch_pos_mode(self.channel as u8).variant(config.pos_edge)
|
||||
});
|
||||
self.set_ctrl_signal(ctrl_signal, config.invert_ctrl);
|
||||
self.set_edge_signal(edge_signal, config.invert_sig);
|
||||
}
|
||||
@ -172,12 +146,9 @@ impl Channel {
|
||||
unsafe { &*GPIO::PTR }
|
||||
.func_in_sel_cfg(signal as usize)
|
||||
.modify(|_, w| unsafe {
|
||||
w.sel()
|
||||
.set_bit()
|
||||
.in_inv_sel()
|
||||
.bit(invert)
|
||||
.in_sel()
|
||||
.bits(source.source)
|
||||
w.sel().set_bit();
|
||||
w.in_inv_sel().bit(invert);
|
||||
w.in_sel().bits(source.source)
|
||||
});
|
||||
}
|
||||
self
|
||||
@ -228,12 +199,9 @@ impl Channel {
|
||||
unsafe { &*GPIO::PTR }
|
||||
.func_in_sel_cfg(signal as usize)
|
||||
.modify(|_, w| unsafe {
|
||||
w.sel()
|
||||
.set_bit()
|
||||
.in_inv_sel()
|
||||
.bit(invert)
|
||||
.in_sel()
|
||||
.bits(source.source)
|
||||
w.sel().set_bit();
|
||||
w.in_inv_sel().bit(invert);
|
||||
w.in_sel().bits(source.source)
|
||||
});
|
||||
}
|
||||
self
|
||||
|
@ -101,21 +101,16 @@ impl Unit {
|
||||
pub(super) fn new(number: Number) -> Self {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
// disable filter and all events
|
||||
pcnt.u_conf0(number as usize).modify(|_, w| unsafe {
|
||||
w.filter_en()
|
||||
.clear_bit()
|
||||
.filter_thres()
|
||||
.bits(0)
|
||||
.thr_l_lim_en()
|
||||
.clear_bit()
|
||||
.thr_h_lim_en()
|
||||
.clear_bit()
|
||||
.thr_thres0_en()
|
||||
.clear_bit()
|
||||
.thr_thres1_en()
|
||||
.clear_bit()
|
||||
.thr_zero_en()
|
||||
.clear_bit()
|
||||
pcnt.unit(number as usize).conf0().modify(|_, w| {
|
||||
w.filter_en().clear_bit();
|
||||
unsafe {
|
||||
w.filter_thres().bits(0);
|
||||
}
|
||||
w.thr_l_lim_en().clear_bit();
|
||||
w.thr_h_lim_en().clear_bit();
|
||||
w.thr_thres0_en().clear_bit();
|
||||
w.thr_thres1_en().clear_bit();
|
||||
w.thr_zero_en().clear_bit()
|
||||
});
|
||||
Self { number }
|
||||
}
|
||||
@ -140,21 +135,19 @@ impl Unit {
|
||||
}
|
||||
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
let number = self.number as usize;
|
||||
pcnt.u_conf2(number).write(|w| unsafe {
|
||||
w.cnt_l_lim()
|
||||
.bits(config.low_limit as u16)
|
||||
.cnt_h_lim()
|
||||
.bits(config.high_limit as u16)
|
||||
let unit = pcnt.unit(self.number as usize);
|
||||
unit.conf2().write(|w| unsafe {
|
||||
w.cnt_l_lim().bits(config.low_limit as u16);
|
||||
w.cnt_h_lim().bits(config.high_limit as u16)
|
||||
});
|
||||
pcnt.u_conf1(number).write(|w| unsafe {
|
||||
w.cnt_thres0()
|
||||
.bits(config.thresh0 as u16)
|
||||
.cnt_thres1()
|
||||
.bits(config.thresh1 as u16)
|
||||
unit.conf1().write(|w| unsafe {
|
||||
w.cnt_thres0().bits(config.thresh0 as u16);
|
||||
w.cnt_thres1().bits(config.thresh1 as u16)
|
||||
});
|
||||
unit.conf0().modify(|_, w| unsafe {
|
||||
w.filter_thres().bits(filter);
|
||||
w.filter_en().bit(filter_en)
|
||||
});
|
||||
pcnt.u_conf0(number)
|
||||
.modify(|_, w| unsafe { w.filter_thres().bits(filter).filter_en().bit(filter_en) });
|
||||
self.pause();
|
||||
self.clear();
|
||||
Ok(())
|
||||
@ -167,90 +160,41 @@ impl Unit {
|
||||
pub fn clear(&self) {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
critical_section::with(|_cs| {
|
||||
match self.number {
|
||||
Number::Unit0 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u0().set_bit()),
|
||||
Number::Unit1 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u1().set_bit()),
|
||||
Number::Unit2 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u2().set_bit()),
|
||||
Number::Unit3 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u3().set_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit4 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u4().set_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit5 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u5().set_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit6 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u6().set_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit7 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u7().set_bit()),
|
||||
}
|
||||
pcnt.ctrl()
|
||||
.modify(|_, w| w.cnt_rst_u(self.number as u8).set_bit());
|
||||
// TODO: does this need a delay? (liebman / Jan 2 2023)
|
||||
match self.number {
|
||||
Number::Unit0 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u0().clear_bit()),
|
||||
Number::Unit1 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u1().clear_bit()),
|
||||
Number::Unit2 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u2().clear_bit()),
|
||||
Number::Unit3 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u3().clear_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit4 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u4().clear_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit5 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u5().clear_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit6 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u6().clear_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit7 => pcnt.ctrl().modify(|_, w| w.cnt_rst_u7().clear_bit()),
|
||||
}
|
||||
pcnt.ctrl()
|
||||
.modify(|_, w| w.cnt_rst_u(self.number as u8).clear_bit());
|
||||
});
|
||||
}
|
||||
|
||||
/// Pause the counter
|
||||
pub fn pause(&self) {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
critical_section::with(|_cs| match self.number {
|
||||
Number::Unit0 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u0().set_bit()),
|
||||
Number::Unit1 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u1().set_bit()),
|
||||
Number::Unit2 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u2().set_bit()),
|
||||
Number::Unit3 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u3().set_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit4 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u4().set_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit5 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u5().set_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit6 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u6().set_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit7 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u7().set_bit()),
|
||||
critical_section::with(|_cs| {
|
||||
pcnt.ctrl()
|
||||
.modify(|_, w| w.cnt_pause_u(self.number as u8).set_bit());
|
||||
});
|
||||
}
|
||||
|
||||
/// Resume the counter
|
||||
pub fn resume(&self) {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
critical_section::with(|_cs| match self.number {
|
||||
Number::Unit0 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u0().clear_bit()),
|
||||
Number::Unit1 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u1().clear_bit()),
|
||||
Number::Unit2 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u2().clear_bit()),
|
||||
Number::Unit3 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u3().clear_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit4 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u4().clear_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit5 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u5().clear_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit6 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u6().clear_bit()),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit7 => pcnt.ctrl().modify(|_, w| w.cnt_pause_u7().clear_bit()),
|
||||
critical_section::with(|_cs| {
|
||||
pcnt.ctrl()
|
||||
.modify(|_, w| w.cnt_pause_u(self.number as u8).clear_bit());
|
||||
});
|
||||
}
|
||||
|
||||
/// Enable which events generate interrupts on this unit.
|
||||
pub fn events(&self, events: Events) {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
pcnt.u_conf0(self.number as usize).modify(|_, w| {
|
||||
w.thr_l_lim_en()
|
||||
.bit(events.low_limit)
|
||||
.thr_h_lim_en()
|
||||
.bit(events.high_limit)
|
||||
.thr_thres0_en()
|
||||
.bit(events.thresh0)
|
||||
.thr_thres1_en()
|
||||
.bit(events.thresh1)
|
||||
.thr_zero_en()
|
||||
.bit(events.zero)
|
||||
pcnt.unit(self.number as usize).conf0().modify(|_, w| {
|
||||
w.thr_l_lim_en().bit(events.low_limit);
|
||||
w.thr_h_lim_en().bit(events.high_limit);
|
||||
w.thr_thres0_en().bit(events.thresh0);
|
||||
w.thr_thres1_en().bit(events.thresh1);
|
||||
w.thr_zero_en().bit(events.zero)
|
||||
});
|
||||
}
|
||||
|
||||
@ -282,20 +226,8 @@ impl Unit {
|
||||
pub fn listen(&self) {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
critical_section::with(|_cs| {
|
||||
pcnt.int_ena().modify(|_, w| match self.number {
|
||||
Number::Unit0 => w.cnt_thr_event_u0().set_bit(),
|
||||
Number::Unit1 => w.cnt_thr_event_u1().set_bit(),
|
||||
Number::Unit2 => w.cnt_thr_event_u2().set_bit(),
|
||||
Number::Unit3 => w.cnt_thr_event_u3().set_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit4 => w.cnt_thr_event_u4().set_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit5 => w.cnt_thr_event_u5().set_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit6 => w.cnt_thr_event_u6().set_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit7 => w.cnt_thr_event_u7().set_bit(),
|
||||
})
|
||||
pcnt.int_ena()
|
||||
.modify(|_, w| w.cnt_thr_event_u(self.number as u8).set_bit());
|
||||
});
|
||||
}
|
||||
|
||||
@ -303,60 +235,26 @@ impl Unit {
|
||||
pub fn unlisten(&self, _cs: CriticalSection) {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
critical_section::with(|_cs| {
|
||||
pcnt.int_ena().write(|w| match self.number {
|
||||
Number::Unit0 => w.cnt_thr_event_u0().clear_bit(),
|
||||
Number::Unit1 => w.cnt_thr_event_u1().clear_bit(),
|
||||
Number::Unit2 => w.cnt_thr_event_u2().clear_bit(),
|
||||
Number::Unit3 => w.cnt_thr_event_u3().clear_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit4 => w.cnt_thr_event_u4().clear_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit5 => w.cnt_thr_event_u5().clear_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit6 => w.cnt_thr_event_u6().clear_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit7 => w.cnt_thr_event_u7().clear_bit(),
|
||||
})
|
||||
pcnt.int_ena()
|
||||
.write(|w| w.cnt_thr_event_u(self.number as u8).clear_bit());
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns true if an interrupt is active for this unit.
|
||||
pub fn interrupt_set(&self) -> bool {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
match self.number {
|
||||
Number::Unit0 => pcnt.int_st().read().cnt_thr_event_u0().bit(),
|
||||
Number::Unit1 => pcnt.int_st().read().cnt_thr_event_u1().bit(),
|
||||
Number::Unit2 => pcnt.int_st().read().cnt_thr_event_u2().bit(),
|
||||
Number::Unit3 => pcnt.int_st().read().cnt_thr_event_u3().bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit4 => pcnt.int_st().read().cnt_thr_event_u4().bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit5 => pcnt.int_st().read().cnt_thr_event_u5().bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit6 => pcnt.int_st().read().cnt_thr_event_u6().bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit7 => pcnt.int_st().read().cnt_thr_event_u7().bit(),
|
||||
}
|
||||
pcnt.int_st()
|
||||
.read()
|
||||
.cnt_thr_event_u(self.number as u8)
|
||||
.bit()
|
||||
}
|
||||
|
||||
/// Clear the interrupt bit for this unit.
|
||||
pub fn reset_interrupt(&self) {
|
||||
let pcnt = unsafe { &*crate::peripherals::PCNT::ptr() };
|
||||
critical_section::with(|_cs| {
|
||||
pcnt.int_clr().write(|w| match self.number {
|
||||
Number::Unit0 => w.cnt_thr_event_u0().set_bit(),
|
||||
Number::Unit1 => w.cnt_thr_event_u1().set_bit(),
|
||||
Number::Unit2 => w.cnt_thr_event_u2().set_bit(),
|
||||
Number::Unit3 => w.cnt_thr_event_u3().set_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit4 => w.cnt_thr_event_u4().set_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit5 => w.cnt_thr_event_u5().set_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit6 => w.cnt_thr_event_u6().set_bit(),
|
||||
#[cfg(esp32)]
|
||||
Number::Unit7 => w.cnt_thr_event_u7().set_bit(),
|
||||
})
|
||||
pcnt.int_clr()
|
||||
.write(|w| w.cnt_thr_event_u(self.number as u8).set_bit());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
//! alarm0.wait_until(SystemTimer::now().wrapping_add(SystemTimer::TICKS_PER_SECOND));
|
||||
//! ```
|
||||
|
||||
use core::{marker::PhantomData, mem::transmute};
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use fugit::MicrosDurationU32;
|
||||
|
||||
@ -32,18 +32,7 @@ use crate::{
|
||||
interrupt::InterruptHandler,
|
||||
peripheral::Peripheral,
|
||||
peripherals::{
|
||||
generic::Reg,
|
||||
systimer::{
|
||||
target0_conf::TARGET0_CONF_SPEC,
|
||||
target0_hi::TARGET0_HI_SPEC,
|
||||
target0_lo::TARGET0_LO_SPEC,
|
||||
target1_conf::TARGET1_CONF_SPEC,
|
||||
target1_hi::TARGET1_HI_SPEC,
|
||||
target1_lo::TARGET1_LO_SPEC,
|
||||
target2_conf::TARGET2_CONF_SPEC,
|
||||
target2_hi::TARGET2_HI_SPEC,
|
||||
target2_lo::TARGET2_LO_SPEC,
|
||||
},
|
||||
systimer::{TARGET_CONF, TRGT},
|
||||
SYSTIMER,
|
||||
},
|
||||
};
|
||||
@ -88,19 +77,12 @@ impl<'d> SystemTimer<'d, crate::Blocking> {
|
||||
// worst case scenario the second accessor ends up reading
|
||||
// an older time stamp
|
||||
let systimer = unsafe { &*SYSTIMER::ptr() };
|
||||
systimer
|
||||
.unit0_op()
|
||||
.modify(|_, w| w.timer_unit0_update().set_bit());
|
||||
systimer.unit0_op().modify(|_, w| w.update().set_bit());
|
||||
|
||||
while !systimer
|
||||
.unit0_op()
|
||||
.read()
|
||||
.timer_unit0_value_valid()
|
||||
.bit_is_set()
|
||||
{}
|
||||
while !systimer.unit0_op().read().value_valid().bit_is_set() {}
|
||||
|
||||
let value_lo = systimer.unit0_value_lo().read().bits();
|
||||
let value_hi = systimer.unit0_value_hi().read().bits();
|
||||
let value_lo = systimer.unit0_value().lo().read().bits();
|
||||
let value_hi = systimer.unit0_value().hi().read().bits();
|
||||
|
||||
((value_hi as u64) << 32) | value_lo as u64
|
||||
}
|
||||
@ -141,74 +123,30 @@ impl<T, DM: crate::Mode, const CHANNEL: u8> Alarm<T, DM, CHANNEL> {
|
||||
Self { _pd: PhantomData }
|
||||
}
|
||||
|
||||
fn configure(
|
||||
&self,
|
||||
conf: impl FnOnce(&Reg<TARGET0_CONF_SPEC>, &Reg<TARGET0_HI_SPEC>, &Reg<TARGET0_LO_SPEC>),
|
||||
) {
|
||||
fn configure(&self, conf: impl FnOnce(&TARGET_CONF, &TRGT)) {
|
||||
unsafe {
|
||||
let systimer = &*SYSTIMER::ptr();
|
||||
let (tconf, hi, lo): (
|
||||
&Reg<TARGET0_CONF_SPEC>,
|
||||
&Reg<TARGET0_HI_SPEC>,
|
||||
&Reg<TARGET0_LO_SPEC>,
|
||||
) = match CHANNEL {
|
||||
0 => (
|
||||
systimer.target0_conf(),
|
||||
systimer.target0_hi(),
|
||||
systimer.target0_lo(),
|
||||
),
|
||||
1 => (
|
||||
transmute::<&Reg<TARGET1_CONF_SPEC>, &Reg<TARGET0_CONF_SPEC>>(
|
||||
systimer.target1_conf(),
|
||||
),
|
||||
transmute::<&Reg<TARGET1_HI_SPEC>, &Reg<TARGET0_HI_SPEC>>(
|
||||
systimer.target1_hi(),
|
||||
),
|
||||
transmute::<&Reg<TARGET1_LO_SPEC>, &Reg<TARGET0_LO_SPEC>>(
|
||||
systimer.target1_lo(),
|
||||
),
|
||||
),
|
||||
2 => (
|
||||
transmute::<&Reg<TARGET2_CONF_SPEC>, &Reg<TARGET0_CONF_SPEC>>(
|
||||
systimer.target2_conf(),
|
||||
),
|
||||
transmute::<&Reg<TARGET2_HI_SPEC>, &Reg<TARGET0_HI_SPEC>>(
|
||||
systimer.target2_hi(),
|
||||
),
|
||||
transmute::<&Reg<TARGET2_LO_SPEC>, &Reg<TARGET0_LO_SPEC>>(
|
||||
systimer.target2_lo(),
|
||||
),
|
||||
),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let tconf = systimer.target_conf(CHANNEL as usize);
|
||||
let target = systimer.trgt(CHANNEL as usize);
|
||||
|
||||
#[cfg(esp32s2)]
|
||||
systimer.step().write(|w| w.timer_xtal_step().bits(0x1)); // run at XTAL freq, not 80 * XTAL freq
|
||||
systimer.step().write(|w| w.xtal_step().bits(0x1)); // run at XTAL freq, not 80 * XTAL freq
|
||||
|
||||
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
|
||||
#[cfg(not(esp32s2))]
|
||||
{
|
||||
tconf.write(|w| w.target0_timer_unit_sel().clear_bit()); // default, use unit 0
|
||||
tconf.write(|w| w.timer_unit_sel().clear_bit()); // default, use unit 0
|
||||
systimer
|
||||
.conf()
|
||||
.modify(|_, w| w.timer_unit0_core0_stall_en().clear_bit());
|
||||
}
|
||||
|
||||
conf(tconf, hi, lo);
|
||||
conf(tconf, target);
|
||||
|
||||
#[cfg(any(esp32c2, esp32c3, esp32c6, esp32h2, esp32s3))]
|
||||
#[cfg(not(esp32s2))]
|
||||
{
|
||||
match CHANNEL {
|
||||
0 => systimer
|
||||
.comp0_load()
|
||||
.write(|w| w.timer_comp0_load().set_bit()),
|
||||
1 => systimer
|
||||
.comp1_load()
|
||||
.write(|w| w.timer_comp1_load().set_bit()),
|
||||
2 => systimer
|
||||
.comp2_load()
|
||||
.write(|w| w.timer_comp2_load().set_bit()),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
systimer
|
||||
.comp_load(CHANNEL as usize)
|
||||
.write(|w| w.load().set_bit());
|
||||
|
||||
systimer.conf().modify(|_r, w| match CHANNEL {
|
||||
0 => w.target0_work_en().set_bit(),
|
||||
@ -219,53 +157,37 @@ impl<T, DM: crate::Mode, const CHANNEL: u8> Alarm<T, DM, CHANNEL> {
|
||||
}
|
||||
|
||||
#[cfg(esp32s2)]
|
||||
tconf.modify(|_r, w| match CHANNEL {
|
||||
0 => w.target0_work_en().set_bit(),
|
||||
1 => w.target0_work_en().set_bit(),
|
||||
2 => w.target0_work_en().set_bit(),
|
||||
_ => unreachable!(),
|
||||
});
|
||||
tconf.modify(|_r, w| w.work_en().set_bit());
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn enable_interrupt_internal(&self, val: bool) {
|
||||
let systimer = unsafe { &*SYSTIMER::ptr() };
|
||||
match CHANNEL {
|
||||
0 => systimer.int_ena().modify(|_, w| w.target0().bit(val)),
|
||||
1 => systimer.int_ena().modify(|_, w| w.target1().bit(val)),
|
||||
2 => systimer.int_ena().modify(|_, w| w.target2().bit(val)),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
systimer.int_ena().modify(|_, w| w.target(CHANNEL).bit(val));
|
||||
}
|
||||
|
||||
pub(crate) fn clear_interrupt_internal(&self) {
|
||||
let systimer = unsafe { &*SYSTIMER::ptr() };
|
||||
match CHANNEL {
|
||||
0 => systimer.int_clr().write(|w| w.target0().clear_bit_by_one()),
|
||||
1 => systimer.int_clr().write(|w| w.target1().clear_bit_by_one()),
|
||||
2 => systimer.int_clr().write(|w| w.target2().clear_bit_by_one()),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
systimer
|
||||
.int_clr()
|
||||
.write(|w| w.target(CHANNEL).clear_bit_by_one());
|
||||
}
|
||||
|
||||
pub(crate) fn set_target_internal(&self, timestamp: u64) {
|
||||
self.configure(|tconf, hi, lo| unsafe {
|
||||
tconf.write(|w| w.target0_period_mode().clear_bit()); // target mode
|
||||
hi.write(|w| w.timer_target0_hi().bits((timestamp >> 32) as u32));
|
||||
lo.write(|w| w.timer_target0_lo().bits((timestamp & 0xFFFF_FFFF) as u32));
|
||||
self.configure(|tconf, target| unsafe {
|
||||
tconf.write(|w| w.period_mode().clear_bit()); // target mode
|
||||
target.hi().write(|w| w.hi().bits((timestamp >> 32) as u32));
|
||||
target
|
||||
.lo()
|
||||
.write(|w| w.lo().set((timestamp & 0xFFFF_FFFF) as u32));
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn set_period_internal(&self, ticks: u32) {
|
||||
self.configure(|tconf, hi, lo| unsafe {
|
||||
tconf.write(|w| {
|
||||
w.target0_period_mode()
|
||||
.set_bit()
|
||||
.target0_period()
|
||||
.bits(ticks)
|
||||
});
|
||||
hi.write(|w| w.timer_target0_hi().bits(0));
|
||||
lo.write(|w| w.timer_target0_lo().bits(0));
|
||||
self.configure(|tconf, target| {
|
||||
tconf.write(|w| unsafe { w.period_mode().set_bit().period().bits(ticks) });
|
||||
target.hi().write(|w| w.hi().set(0));
|
||||
target.lo().write(|w| w.lo().set(0));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -328,17 +250,9 @@ impl<DM: crate::Mode, const CHANNEL: u8> Alarm<Target, DM, CHANNEL> {
|
||||
pub fn wait_until(&mut self, timestamp: u64) {
|
||||
self.clear_interrupt_internal();
|
||||
self.set_target(timestamp);
|
||||
let r = unsafe { &*crate::peripherals::SYSTIMER::PTR }.int_raw();
|
||||
loop {
|
||||
let r = unsafe { &*crate::peripherals::SYSTIMER::PTR }
|
||||
.int_raw()
|
||||
.read();
|
||||
|
||||
if match CHANNEL {
|
||||
0 => r.target0().bit_is_set(),
|
||||
1 => r.target1().bit_is_set(),
|
||||
2 => r.target2().bit_is_set(),
|
||||
_ => unreachable!(),
|
||||
} {
|
||||
if r.read().target(CHANNEL).bit_is_set() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -455,16 +369,11 @@ mod asynch {
|
||||
}
|
||||
|
||||
fn event_bit_is_clear(&self) -> bool {
|
||||
let r = unsafe { &*crate::peripherals::SYSTIMER::PTR }
|
||||
unsafe { &*crate::peripherals::SYSTIMER::PTR }
|
||||
.int_ena()
|
||||
.read();
|
||||
|
||||
match N {
|
||||
0 => r.target0().bit_is_clear(),
|
||||
1 => r.target1().bit_is_clear(),
|
||||
2 => r.target2().bit_is_clear(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
.read()
|
||||
.target(N)
|
||||
.bit_is_clear()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user