Add the esp-hal-common crate and make ESP32/ESP32-C3 use its Timer
This commit is contained in:
parent
2bc97768b6
commit
dfab5d6c1b
18
esp-hal-common/Cargo.toml
Normal file
18
esp-hal-common/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "esp-hal-common"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
embedded-hal = { version = "0.2", features = ["unproven"] }
|
||||
nb = "1.0"
|
||||
void = { version = "1.0", default-features = false }
|
||||
# Each supported device MUST have its PAC included below.
|
||||
esp32 = { path = "../../esp-pacs/esp32", optional = true }
|
||||
esp32c3 = { path = "../../esp-pacs/esp32c3", optional = true }
|
||||
esp32s2 = { path = "../../esp-pacs/esp32s2", optional = true }
|
||||
|
||||
[features]
|
||||
enable-esp32 = ["esp32"]
|
||||
enable-esp32c3 = ["esp32c3"]
|
||||
enable-esp32s2 = ["esp32s2"]
|
||||
11
esp-hal-common/build.rs
Normal file
11
esp-hal-common/build.rs
Normal file
@ -0,0 +1,11 @@
|
||||
fn main() {
|
||||
let chip_features = [
|
||||
cfg!(feature = "enable-esp32"),
|
||||
cfg!(feature = "enable-esp32c3"),
|
||||
cfg!(feature = "enable-esp32s2"),
|
||||
];
|
||||
|
||||
if chip_features.iter().filter(|&&f| f).count() != 1 {
|
||||
panic!("Exactly one chip must be selected via its cargo feature");
|
||||
}
|
||||
}
|
||||
12
esp-hal-common/src/lib.rs
Normal file
12
esp-hal-common/src/lib.rs
Normal file
@ -0,0 +1,12 @@
|
||||
#![no_std]
|
||||
|
||||
#[cfg(feature = "esp32")]
|
||||
pub use esp32 as pac;
|
||||
#[cfg(feature = "esp32c3")]
|
||||
pub use esp32c3 as pac;
|
||||
#[cfg(feature = "esp32s2")]
|
||||
pub use esp32s2 as pac;
|
||||
|
||||
pub mod timer;
|
||||
|
||||
pub use timer::Timer;
|
||||
@ -135,7 +135,7 @@ where
|
||||
let int_raw_is_clear = self
|
||||
.timg
|
||||
.as_timg0()
|
||||
.int_raw_timg
|
||||
.int_raw_timers
|
||||
.read()
|
||||
.t0_int_raw()
|
||||
.bit_is_clear();
|
||||
@ -145,7 +145,7 @@ where
|
||||
} else {
|
||||
self.timg
|
||||
.as_timg0()
|
||||
.int_clr_timg
|
||||
.int_clr_timers
|
||||
.write(|w| w.t0_int_clr().set_bit());
|
||||
|
||||
self.timg.set_alarm_active(true);
|
||||
@ -14,6 +14,10 @@ xtensa-lx-rt = { version = "0.7", optional = true, features = ["lx6"] }
|
||||
[dependencies.esp32]
|
||||
path = "../../esp-pacs/esp32"
|
||||
|
||||
[dependencies.esp-hal-common]
|
||||
path = "../esp-hal-common"
|
||||
features = ["enable-esp32"]
|
||||
|
||||
[dev-dependencies]
|
||||
panic-halt = "0.2"
|
||||
|
||||
|
||||
@ -2,13 +2,12 @@
|
||||
|
||||
pub use embedded_hal as ehal;
|
||||
pub use esp32 as pac;
|
||||
pub use esp_hal_common::Timer;
|
||||
|
||||
pub mod prelude;
|
||||
pub mod serial;
|
||||
pub mod timer;
|
||||
|
||||
pub use serial::Serial;
|
||||
pub use timer::Timer;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn DefaultHandler(_level: u32, _interrupt: pac::Interrupt) {}
|
||||
|
||||
@ -1,196 +0,0 @@
|
||||
use embedded_hal::{
|
||||
timer::{Cancel, CountDown, Periodic},
|
||||
watchdog::WatchdogDisable,
|
||||
};
|
||||
use void::Void;
|
||||
|
||||
use crate::pac::{timg0::RegisterBlock, TIMG0, TIMG1};
|
||||
|
||||
pub struct Timer<T> {
|
||||
timg: T,
|
||||
}
|
||||
|
||||
pub enum Error {
|
||||
/// Report that the timer is active and certain management
|
||||
/// operations cannot be performed safely
|
||||
TimerActive,
|
||||
/// Report that the timer is inactive and thus not
|
||||
/// ever reaching any potentially configured alarm value
|
||||
TimerInactive,
|
||||
/// Report that the alarm functionality is disabled
|
||||
AlarmInactive,
|
||||
}
|
||||
|
||||
impl<T> Timer<T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
pub fn new(timg: T) -> Self {
|
||||
Self { timg }
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Instance {
|
||||
fn as_timg0(&self) -> &RegisterBlock;
|
||||
|
||||
fn reset_counter(&mut self) {
|
||||
self.as_timg0()
|
||||
.t0loadhi
|
||||
.write(|w| unsafe { w.t0_load_hi().bits(0) });
|
||||
|
||||
self.as_timg0()
|
||||
.t0load
|
||||
.write(|w| unsafe { w.t0_load().bits(1) });
|
||||
}
|
||||
|
||||
fn set_counter_active(&mut self, state: bool) {
|
||||
self.as_timg0().t0config.modify(|_, w| w.t0_en().bit(state));
|
||||
}
|
||||
|
||||
fn is_counter_active(&mut self) -> bool {
|
||||
self.as_timg0().t0config.read().t0_en().bit_is_set()
|
||||
}
|
||||
|
||||
fn set_counter_decrementing(&mut self, decrementing: bool) {
|
||||
self.as_timg0()
|
||||
.t0config
|
||||
.modify(|_, w| w.t0_increase().bit(!decrementing));
|
||||
}
|
||||
|
||||
fn set_auto_reload(&mut self, auto_reload: bool) {
|
||||
self.as_timg0()
|
||||
.t0config
|
||||
.modify(|_, w| w.t0_autoreload().bit(auto_reload));
|
||||
}
|
||||
|
||||
fn set_alarm_active(&mut self, state: bool) {
|
||||
self.as_timg0()
|
||||
.t0config
|
||||
.modify(|_, w| w.t0_alarm_en().bit(state));
|
||||
}
|
||||
|
||||
fn is_alarm_active(&mut self) -> bool {
|
||||
self.as_timg0().t0config.read().t0_alarm_en().bit_is_set()
|
||||
}
|
||||
|
||||
fn load_alarm_value(&mut self, value: u64) {
|
||||
let value = value & 0x3F_FFFF_FFFF_FFFF;
|
||||
let high = (value >> 32) as u32;
|
||||
let low = (value & 0xFFFF_FFFF) as u32;
|
||||
|
||||
self.as_timg0()
|
||||
.t0alarmlo
|
||||
.write(|w| unsafe { w.t0_alarm_lo().bits(low) });
|
||||
self.as_timg0()
|
||||
.t0alarmhi
|
||||
.write(|w| unsafe { w.t0_alarm_hi().bits(high) });
|
||||
}
|
||||
|
||||
fn set_wdt_enabled(&mut self, enabled: bool) {
|
||||
self.as_timg0()
|
||||
.wdtwprotect
|
||||
.write(|w| unsafe { w.wdt_wkey().bits(0u32) });
|
||||
|
||||
self.as_timg0()
|
||||
.wdtconfig0
|
||||
.write(|w| w.wdt_en().bit(enabled));
|
||||
|
||||
self.as_timg0()
|
||||
.wdtwprotect
|
||||
.write(|w| unsafe { w.wdt_wkey().bits(0x50D8_3AA1u32) });
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> CountDown for Timer<T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
type Time = u64;
|
||||
|
||||
fn start<Time>(&mut self, timeout: Time)
|
||||
where
|
||||
Time: Into<u64>,
|
||||
{
|
||||
self.timg.set_counter_active(false);
|
||||
self.timg.set_alarm_active(false);
|
||||
|
||||
self.timg.reset_counter();
|
||||
self.timg.load_alarm_value(timeout.into());
|
||||
|
||||
self.timg.set_counter_decrementing(false);
|
||||
self.timg.set_auto_reload(true);
|
||||
self.timg.set_counter_active(true);
|
||||
self.timg.set_alarm_active(true);
|
||||
}
|
||||
|
||||
fn wait(&mut self) -> nb::Result<(), Void> {
|
||||
if !self.timg.is_counter_active() {
|
||||
panic!("Called wait on an inactive timer!");
|
||||
}
|
||||
|
||||
let int_raw_is_clear = self
|
||||
.timg
|
||||
.as_timg0()
|
||||
.int_raw_timers
|
||||
.read()
|
||||
.t0_int_raw()
|
||||
.bit_is_clear();
|
||||
|
||||
if int_raw_is_clear {
|
||||
Err(nb::Error::WouldBlock)
|
||||
} else {
|
||||
self.timg
|
||||
.as_timg0()
|
||||
.int_clr_timers
|
||||
.write(|w| w.t0_int_clr().set_bit());
|
||||
|
||||
self.timg.set_alarm_active(true);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Periodic for Timer<T> where T: Instance {}
|
||||
|
||||
impl<T> Cancel for Timer<T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn cancel(&mut self) -> Result<(), Error> {
|
||||
if !self.timg.is_counter_active() {
|
||||
return Err(Error::TimerInactive);
|
||||
} else if !self.timg.is_alarm_active() {
|
||||
return Err(Error::AlarmInactive);
|
||||
}
|
||||
|
||||
self.timg.set_counter_active(false);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> WatchdogDisable for Timer<T>
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
fn disable(&mut self) {
|
||||
self.timg.set_wdt_enabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance for TIMG0 {
|
||||
#[inline(always)]
|
||||
fn as_timg0(&self) -> &RegisterBlock {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance for TIMG1 {
|
||||
#[inline(always)]
|
||||
fn as_timg0(&self) -> &RegisterBlock {
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,10 @@ void = { version = "1.0", default-features = false }
|
||||
[dependencies.esp32c3]
|
||||
path = "../../esp-pacs/esp32c3"
|
||||
|
||||
[dependencies.esp-hal-common]
|
||||
path = "../esp-hal-common"
|
||||
features = ["enable-esp32c3"]
|
||||
|
||||
[dependencies.riscv-rt]
|
||||
git = "https://github.com/MabezDev/riscv-rt"
|
||||
rev = "6b55e4aa3895924e31bcd151f2f0ab840836fa07"
|
||||
|
||||
@ -2,12 +2,11 @@
|
||||
|
||||
pub use embedded_hal as ehal;
|
||||
pub use esp32c3 as pac;
|
||||
pub use esp_hal_common::Timer;
|
||||
|
||||
pub mod prelude;
|
||||
pub mod rtc_cntl;
|
||||
pub mod serial;
|
||||
pub mod timer;
|
||||
|
||||
pub use rtc_cntl::RtcCntl;
|
||||
pub use serial::Serial;
|
||||
pub use timer::Timer;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user