Extract embassy support into esp-hal-embassy package (#1595)
* Extract embassy support into `esp-hal-embassy` package * Update relevant packages/examples/tests to get CI green again * Add back `defmt` support * Re-export `Executor` and `InterruptExecutor` rather than making `executor` module public * Document the `esp-hal-embassy` package * Update `CHANGELOG.md` * Hack together a "fix" for the `SYSTIMER` time driver * Make `clippy` shut up
This commit is contained in:
parent
cb91828e5e
commit
48e3e912f3
@ -6,6 +6,7 @@ exclude = [
|
||||
"esp-backtrace",
|
||||
"esp-build",
|
||||
"esp-hal",
|
||||
"esp-hal-embassy",
|
||||
"esp-hal-procmacros",
|
||||
"esp-hal-smartled",
|
||||
"esp-ieee802154",
|
||||
|
||||
48
esp-hal-embassy/Cargo.toml
Normal file
48
esp-hal-embassy/Cargo.toml
Normal file
@ -0,0 +1,48 @@
|
||||
[package]
|
||||
name = "esp-hal-embassy"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.76.0"
|
||||
description = "Embassy support for esp-hal"
|
||||
repository = "https://github.com/esp-rs/esp-hal"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
default-target = "riscv32imac-unknown-none-elf"
|
||||
features = ["esp32c6", "time-timg0"]
|
||||
|
||||
[dependencies]
|
||||
critical-section = "1.1.2"
|
||||
defmt = { version = "0.3.8", optional = true }
|
||||
document-features = "0.2.8"
|
||||
embassy-executor = "0.5.0"
|
||||
embassy-time-driver = "0.1.0"
|
||||
esp-hal = { version = "0.17.0", path = "../esp-hal" }
|
||||
portable-atomic = "1.6.0"
|
||||
|
||||
[build-dependencies]
|
||||
cfg-if = "1.0.0"
|
||||
esp-build = { version = "0.1.0", path = "../esp-build" }
|
||||
esp-metadata = { version = "0.1.0", path = "../esp-metadata" }
|
||||
|
||||
[features]
|
||||
esp32 = ["esp-hal/esp32"]
|
||||
esp32c2 = ["esp-hal/esp32c2"]
|
||||
esp32c3 = ["esp-hal/esp32c3"]
|
||||
esp32c6 = ["esp-hal/esp32c6"]
|
||||
esp32h2 = ["esp-hal/esp32h2"]
|
||||
esp32s2 = ["esp-hal/esp32s2"]
|
||||
esp32s3 = ["esp-hal/esp32s3"]
|
||||
|
||||
## Implement `defmt::Format` on certain types.
|
||||
defmt = ["dep:defmt", "embassy-executor/defmt", "esp-hal/defmt"]
|
||||
## Use the executor-integrated `embassy-time` timer queue.
|
||||
integrated-timers = ["embassy-executor/integrated-timers"]
|
||||
|
||||
#! ### Time Driver Feature Flags
|
||||
## SYSTIMER (16MHz)
|
||||
time-systimer-16mhz = ["embassy-time-driver/tick-hz-16_000_000"]
|
||||
## SYSTIMER (80MHz)
|
||||
time-systimer-80mhz = ["embassy-time-driver/tick-hz-80_000_000"]
|
||||
## TIMG0 (1MHz)
|
||||
time-timg0 = ["embassy-time-driver/tick-hz-1_000_000"]
|
||||
35
esp-hal-embassy/README.md
Normal file
35
esp-hal-embassy/README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# esp-hal-embassy
|
||||
|
||||
[](https://crates.io/crates/esp-hal-embassy)
|
||||
[](https://docs.rs/esp-hal-embassy)
|
||||

|
||||

|
||||
[](https://matrix.to/#/#esp-rs:matrix.org)
|
||||
|
||||
[Embassy] support for `esp-hal`.
|
||||
|
||||
[embassy]: https://github.com/embassy-rs/embassy
|
||||
|
||||
## [Documentation]
|
||||
|
||||
[documentation]: https://docs.rs/esp-hal-embassy/
|
||||
|
||||
## Minimum Supported Rust Version (MSRV)
|
||||
|
||||
This crate is guaranteed to compile on stable Rust 1.76 and up. It _might_
|
||||
compile with older versions but that may change in any new patch release.
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of:
|
||||
|
||||
- Apache License, Version 2.0 ([LICENSE-APACHE](../LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
- MIT license ([LICENSE-MIT](../LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in
|
||||
the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without
|
||||
any additional terms or conditions.
|
||||
53
esp-hal-embassy/build.rs
Normal file
53
esp-hal-embassy/build.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use std::{error::Error, str::FromStr};
|
||||
|
||||
use esp_build::assert_unique_used_features;
|
||||
use esp_metadata::{Chip, Config};
|
||||
|
||||
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!(
|
||||
"esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s2", "esp32s3"
|
||||
);
|
||||
|
||||
// If the `embassy` feature is enabled, ensure that a time driver implementation
|
||||
// is available:
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "esp32")] {
|
||||
assert_unique_used_features!("time-timg0");
|
||||
} else if #[cfg(feature = "esp32s2")] {
|
||||
assert_unique_used_features!("time-systimer-80mhz", "time-timg0");
|
||||
} else {
|
||||
assert_unique_used_features!("time-systimer-16mhz", "time-timg0");
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: update when adding new device support!
|
||||
// Determine the name of the configured device:
|
||||
let device_name = if cfg!(feature = "esp32") {
|
||||
"esp32"
|
||||
} else if cfg!(feature = "esp32c2") {
|
||||
"esp32c2"
|
||||
} else if cfg!(feature = "esp32c3") {
|
||||
"esp32c3"
|
||||
} else if cfg!(feature = "esp32c6") {
|
||||
"esp32c6"
|
||||
} else if cfg!(feature = "esp32h2") {
|
||||
"esp32h2"
|
||||
} else if cfg!(feature = "esp32s2") {
|
||||
"esp32s2"
|
||||
} else if cfg!(feature = "esp32s3") {
|
||||
"esp32s3"
|
||||
} else {
|
||||
unreachable!() // We've confirmed exactly one known device was selected
|
||||
};
|
||||
|
||||
// Load the configuration file for the configured device:
|
||||
let chip = Chip::from_str(device_name)?;
|
||||
let config = Config::for_chip(&chip);
|
||||
|
||||
// Define all necessary configuration symbols for the configured device:
|
||||
config.define_symbols();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -1,14 +1,14 @@
|
||||
//! Interrupt-mode executor.
|
||||
|
||||
use core::{cell::UnsafeCell, mem::MaybeUninit};
|
||||
|
||||
use embassy_executor::{raw, SendSpawner};
|
||||
use portable_atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use crate::{
|
||||
use esp_hal::{
|
||||
get_core,
|
||||
interrupt::{self, InterruptHandler},
|
||||
system::SoftwareInterrupt,
|
||||
};
|
||||
use portable_atomic::{AtomicUsize, Ordering};
|
||||
|
||||
static mut EXECUTORS: [CallbackContext; 4] = [
|
||||
CallbackContext::new(),
|
||||
@ -43,7 +43,7 @@ impl CallbackContext {
|
||||
}
|
||||
|
||||
fn get(&self) -> *mut raw::Executor {
|
||||
unsafe { (*self.raw_executor.get()) as *mut raw::Executor }
|
||||
unsafe { *self.raw_executor.get() }
|
||||
}
|
||||
|
||||
fn set(&self, executor: *mut raw::Executor) {
|
||||
@ -58,7 +58,7 @@ fn handle_interrupt<const NUM: u8>() {
|
||||
swi.reset();
|
||||
|
||||
unsafe {
|
||||
let executor = EXECUTORS[NUM as usize].get().as_mut().unwrap();
|
||||
let executor = unwrap!(EXECUTORS[NUM as usize].get().as_mut());
|
||||
executor.poll();
|
||||
}
|
||||
}
|
||||
@ -151,7 +151,7 @@ impl<const SWI: u8> InterruptExecutor<SWI> {
|
||||
if self.core.load(Ordering::Acquire) == usize::MAX {
|
||||
panic!("InterruptExecutor::spawner() called on uninitialized executor.");
|
||||
}
|
||||
let executor = unsafe { (&*self.executor.get()).assume_init_ref() };
|
||||
let executor = unsafe { (*self.executor.get()).assume_init_ref() };
|
||||
executor.spawner().make_send()
|
||||
}
|
||||
}
|
||||
@ -1,12 +1,11 @@
|
||||
pub use self::{interrupt::*, thread::*};
|
||||
|
||||
mod interrupt;
|
||||
mod thread;
|
||||
|
||||
pub use interrupt::*;
|
||||
pub use thread::*;
|
||||
|
||||
#[export_name = "__pender"]
|
||||
fn __pender(context: *mut ()) {
|
||||
use crate::system::SoftwareInterrupt;
|
||||
use esp_hal::system::SoftwareInterrupt;
|
||||
|
||||
let context = (context as usize).to_le_bytes();
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
//! Multicore-aware thread-mode embassy executor.
|
||||
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy_executor::{raw, Spawner};
|
||||
use esp_hal::get_core;
|
||||
#[cfg(multi_core)]
|
||||
use esp_hal::macros::handler;
|
||||
#[cfg(multi_core)]
|
||||
use esp_hal::peripherals::SYSTEM;
|
||||
use portable_atomic::{AtomicBool, Ordering};
|
||||
#[cfg(multi_core)]
|
||||
use procmacros::handler;
|
||||
|
||||
use crate::get_core;
|
||||
#[cfg(multi_core)]
|
||||
use crate::peripherals::SYSTEM;
|
||||
|
||||
pub(crate) const THREAD_MODE_CONTEXT: u8 = 16;
|
||||
|
||||
@ -39,7 +39,7 @@ pub(crate) fn pend_thread_mode(core: usize) {
|
||||
// If we are pending a task on the current core, we're done. Otherwise, we
|
||||
// need to make sure the other core wakes up.
|
||||
#[cfg(multi_core)]
|
||||
if core != crate::get_core() as usize {
|
||||
if core != get_core() as usize {
|
||||
// We need to clear the interrupt from software. We don't actually
|
||||
// need it to trigger and run the interrupt handler, we just need to
|
||||
// kick waiti to return.
|
||||
@ -78,7 +78,7 @@ impl Executor {
|
||||
pub fn new() -> Self {
|
||||
#[cfg(multi_core)]
|
||||
unsafe {
|
||||
crate::system::SoftwareInterrupt::<3>::steal()
|
||||
esp_hal::system::SoftwareInterrupt::<3>::steal()
|
||||
.set_interrupt_handler(software3_interrupt)
|
||||
}
|
||||
|
||||
@ -179,3 +179,9 @@ impl Executor {
|
||||
// here
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Executor {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
226
esp-hal-embassy/src/fmt.rs
Normal file
226
esp-hal-embassy/src/fmt.rs
Normal file
@ -0,0 +1,226 @@
|
||||
#![macro_use]
|
||||
#![allow(unused_macros)]
|
||||
|
||||
#[cfg(all(feature = "defmt", feature = "log"))]
|
||||
compile_error!("You may not enable both `defmt` and `log` features.");
|
||||
|
||||
macro_rules! assert {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::assert!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::assert!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! assert_eq {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::assert_eq!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::assert_eq!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! assert_ne {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::assert_ne!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::assert_ne!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! debug_assert {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::debug_assert!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug_assert!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! debug_assert_eq {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::debug_assert_eq!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug_assert_eq!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! debug_assert_ne {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::debug_assert_ne!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug_assert_ne!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! todo {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::todo!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::todo!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! unreachable {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::unreachable!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::unreachable!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! panic {
|
||||
($($x:tt)*) => {
|
||||
{
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
::core::panic!($($x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::panic!($($x)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! trace {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::trace!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::trace!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! debug {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::debug!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::debug!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! info {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::info!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::info!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! warn {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::warn!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::warn!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! error {
|
||||
($s:literal $(, $x:expr)* $(,)?) => {
|
||||
{
|
||||
#[cfg(feature = "log")]
|
||||
::log::error!($s $(, $x)*);
|
||||
#[cfg(feature = "defmt")]
|
||||
::defmt::error!($s $(, $x)*);
|
||||
#[cfg(not(any(feature = "log", feature="defmt")))]
|
||||
let _ = ($( & $x ),*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "defmt")]
|
||||
macro_rules! unwrap {
|
||||
($($x:tt)*) => {
|
||||
::defmt::unwrap!($($x)*)
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "defmt"))]
|
||||
macro_rules! unwrap {
|
||||
($arg:expr) => {
|
||||
match $crate::fmt::Try::into_result($arg) {
|
||||
::core::result::Result::Ok(t) => t,
|
||||
::core::result::Result::Err(e) => {
|
||||
::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
|
||||
}
|
||||
}
|
||||
};
|
||||
($arg:expr, $($msg:expr),+ $(,)? ) => {
|
||||
match $crate::fmt::Try::into_result($arg) {
|
||||
::core::result::Result::Ok(t) => t,
|
||||
::core::result::Result::Err(e) => {
|
||||
::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub struct NoneError;
|
||||
|
||||
pub trait Try {
|
||||
type Ok;
|
||||
type Error;
|
||||
#[allow(unused)]
|
||||
fn into_result(self) -> Result<Self::Ok, Self::Error>;
|
||||
}
|
||||
|
||||
impl<T> Try for Option<T> {
|
||||
type Ok = T;
|
||||
type Error = NoneError;
|
||||
|
||||
#[inline]
|
||||
fn into_result(self) -> Result<T, NoneError> {
|
||||
self.ok_or(NoneError)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, E> Try for Result<T, E> {
|
||||
type Ok = T;
|
||||
type Error = E;
|
||||
|
||||
#[inline]
|
||||
fn into_result(self) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
102
esp-hal-embassy/src/lib.rs
Normal file
102
esp-hal-embassy/src/lib.rs
Normal file
@ -0,0 +1,102 @@
|
||||
//! Embassy support for [esp-hal].
|
||||
//!
|
||||
//! [Embassy] is a modern asynchronous framework intended for use with embedded
|
||||
//! systems. This package provides support for building applications using
|
||||
//! Embassy with [esp-hal].
|
||||
//!
|
||||
//! [esp-hal]: https://github.com/esp-rs/esp-hal
|
||||
//! [embassy]: https://github.com/embassy-rs/embassy
|
||||
//!
|
||||
//! ## Executors
|
||||
//!
|
||||
//! Two types of executors are provided:
|
||||
//!
|
||||
//! - [Executor]: A thread-mode executor
|
||||
//! - [InterruptExecutor]: An interrupt-mode executor
|
||||
//!
|
||||
//! [InterruptExecutor] can be used to achieve preemptive multitasking in
|
||||
//! asynchronous applications, which is typically something reserved for more
|
||||
//! traditional RTOS. More information can be found in the [Embassy
|
||||
//! documentation].
|
||||
//!
|
||||
//! [embassy documentation]: https://embassy.dev/book/dev/runtime.html
|
||||
//!
|
||||
//! ## Initialization
|
||||
//!
|
||||
//! Embassy **must** be initialized by calling the [init] function. This
|
||||
//! initialization must be performed *prior* to spawning any tasks.
|
||||
//!
|
||||
//! ## Feature Flags
|
||||
#![doc = document_features::document_features!()]
|
||||
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/46717278")]
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(xtensa, feature(asm_experimental_arch))]
|
||||
#![no_std]
|
||||
|
||||
// MUST be the first module
|
||||
mod fmt;
|
||||
|
||||
use core::cell::Cell;
|
||||
|
||||
use embassy_time_driver::{AlarmHandle, Driver};
|
||||
use esp_hal::clock::Clocks;
|
||||
|
||||
pub use self::executor::{Executor, InterruptExecutor};
|
||||
use self::time_driver::{EmbassyTimer, TimerType};
|
||||
|
||||
mod executor;
|
||||
mod time_driver;
|
||||
|
||||
/// Initialize embassy
|
||||
pub fn init(clocks: &Clocks, time_driver: TimerType) {
|
||||
EmbassyTimer::init(clocks, time_driver)
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(crate) struct AlarmState {
|
||||
pub callback: Cell<Option<(fn(*mut ()), *mut ())>>,
|
||||
pub allocated: Cell<bool>,
|
||||
}
|
||||
|
||||
unsafe impl Send for AlarmState {}
|
||||
|
||||
impl AlarmState {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
callback: Cell::new(None),
|
||||
allocated: Cell::new(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for EmbassyTimer {
|
||||
fn now(&self) -> u64 {
|
||||
EmbassyTimer::now()
|
||||
}
|
||||
|
||||
unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
|
||||
critical_section::with(|cs| {
|
||||
for (i, alarm) in self.alarms.borrow(cs).iter().enumerate() {
|
||||
if !alarm.allocated.get() {
|
||||
// set alarm so it is not overwritten
|
||||
alarm.allocated.set(true);
|
||||
self.on_alarm_allocated(i);
|
||||
return Some(AlarmHandle::new(i as u8));
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
fn set_alarm_callback(&self, alarm: AlarmHandle, callback: fn(*mut ()), ctx: *mut ()) {
|
||||
let n = alarm.id() as usize;
|
||||
critical_section::with(|cs| {
|
||||
let alarm = &self.alarms.borrow(cs)[n];
|
||||
alarm.callback.set(Some((callback, ctx)));
|
||||
})
|
||||
}
|
||||
|
||||
fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool {
|
||||
self.set_alarm(alarm, timestamp)
|
||||
}
|
||||
}
|
||||
9
esp-hal-embassy/src/time_driver/mod.rs
Normal file
9
esp-hal-embassy/src/time_driver/mod.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#[cfg(any(feature = "time-systimer-16mhz", feature = "time-systimer-80mhz"))]
|
||||
pub use self::systimer::*;
|
||||
#[cfg(feature = "time-timg0")]
|
||||
pub use self::timg::*;
|
||||
|
||||
#[cfg(any(feature = "time-systimer-16mhz", feature = "time-systimer-80mhz"))]
|
||||
mod systimer;
|
||||
#[cfg(feature = "time-timg0")]
|
||||
mod timg;
|
||||
@ -1,35 +1,35 @@
|
||||
use critical_section::{CriticalSection, Mutex};
|
||||
use procmacros::handler;
|
||||
|
||||
use super::AlarmState;
|
||||
use crate::{
|
||||
use embassy_time_driver::AlarmHandle;
|
||||
use esp_hal::{
|
||||
clock::Clocks,
|
||||
peripherals,
|
||||
interrupt,
|
||||
peripherals::Interrupt,
|
||||
prelude::*,
|
||||
timer::{
|
||||
systimer::{Alarm, SystemTimer, Target},
|
||||
Timer as _,
|
||||
},
|
||||
timer::systimer::{Alarm, SystemTimer, Target},
|
||||
Async,
|
||||
};
|
||||
|
||||
use crate::AlarmState;
|
||||
|
||||
pub const ALARM_COUNT: usize = 3;
|
||||
|
||||
pub type TimerType = SystemTimer<'static, crate::Async>;
|
||||
pub type TimerType = SystemTimer<'static, Async>;
|
||||
|
||||
pub struct EmbassyTimer {
|
||||
pub(crate) alarms: Mutex<[AlarmState; ALARM_COUNT]>,
|
||||
pub(crate) alarm0: Alarm<Target, crate::Async, 0>,
|
||||
pub(crate) alarm1: Alarm<Target, crate::Async, 1>,
|
||||
pub(crate) alarm2: Alarm<Target, crate::Async, 2>,
|
||||
pub(crate) alarm0: Alarm<Target, Async, 0>,
|
||||
pub(crate) alarm1: Alarm<Target, Async, 1>,
|
||||
pub(crate) alarm2: Alarm<Target, Async, 2>,
|
||||
}
|
||||
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const ALARM_STATE_NONE: AlarmState = AlarmState::new();
|
||||
|
||||
embassy_time_driver::time_driver_impl!(static DRIVER: EmbassyTimer = EmbassyTimer {
|
||||
alarms: Mutex::new([ALARM_STATE_NONE; ALARM_COUNT]),
|
||||
alarm0: unsafe { Alarm::<_, crate::Async, 0>::conjure() },
|
||||
alarm1: unsafe { Alarm::<_, crate::Async, 1>::conjure() },
|
||||
alarm2: unsafe { Alarm::<_, crate::Async, 2>::conjure() },
|
||||
alarm0: unsafe { Alarm::<_, Async, 0>::conjure() },
|
||||
alarm1: unsafe { Alarm::<_, Async, 1>::conjure() },
|
||||
alarm2: unsafe { Alarm::<_, Async, 2>::conjure() },
|
||||
});
|
||||
|
||||
impl EmbassyTimer {
|
||||
@ -45,7 +45,7 @@ impl EmbassyTimer {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn on_alarm_allocated(&self, n: usize) {
|
||||
pub(crate) fn on_alarm_allocated(&self, n: usize) {
|
||||
match n {
|
||||
0 => self.alarm0.enable_interrupt(true),
|
||||
1 => self.alarm1.enable_interrupt(true),
|
||||
@ -63,30 +63,21 @@ impl EmbassyTimer {
|
||||
|
||||
pub fn init(_clocks: &Clocks, _systimer: TimerType) {
|
||||
unsafe {
|
||||
crate::interrupt::bind_interrupt(
|
||||
peripherals::Interrupt::SYSTIMER_TARGET0,
|
||||
target0_handler.handler(),
|
||||
);
|
||||
unwrap!(crate::interrupt::enable(
|
||||
peripherals::Interrupt::SYSTIMER_TARGET0,
|
||||
interrupt::bind_interrupt(Interrupt::SYSTIMER_TARGET0, target0_handler.handler());
|
||||
unwrap!(interrupt::enable(
|
||||
Interrupt::SYSTIMER_TARGET0,
|
||||
target0_handler.priority()
|
||||
));
|
||||
|
||||
crate::interrupt::bind_interrupt(
|
||||
peripherals::Interrupt::SYSTIMER_TARGET1,
|
||||
target1_handler.handler(),
|
||||
);
|
||||
unwrap!(crate::interrupt::enable(
|
||||
peripherals::Interrupt::SYSTIMER_TARGET1,
|
||||
interrupt::bind_interrupt(Interrupt::SYSTIMER_TARGET1, target1_handler.handler());
|
||||
unwrap!(interrupt::enable(
|
||||
Interrupt::SYSTIMER_TARGET1,
|
||||
target1_handler.priority()
|
||||
));
|
||||
|
||||
crate::interrupt::bind_interrupt(
|
||||
peripherals::Interrupt::SYSTIMER_TARGET2,
|
||||
target2_handler.handler(),
|
||||
);
|
||||
unwrap!(crate::interrupt::enable(
|
||||
peripherals::Interrupt::SYSTIMER_TARGET2,
|
||||
interrupt::bind_interrupt(Interrupt::SYSTIMER_TARGET2, target2_handler.handler());
|
||||
unwrap!(interrupt::enable(
|
||||
Interrupt::SYSTIMER_TARGET2,
|
||||
target2_handler.priority()
|
||||
));
|
||||
}
|
||||
@ -107,11 +98,7 @@ impl EmbassyTimer {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_alarm(
|
||||
&self,
|
||||
alarm: embassy_time_driver::AlarmHandle,
|
||||
timestamp: u64,
|
||||
) -> bool {
|
||||
pub(crate) fn set_alarm(&self, alarm: AlarmHandle, timestamp: u64) -> bool {
|
||||
critical_section::with(|_cs| {
|
||||
let n = alarm.id() as usize;
|
||||
|
||||
@ -139,9 +126,9 @@ impl EmbassyTimer {
|
||||
|
||||
fn arm(&self, id: usize, timestamp: u64) {
|
||||
match id {
|
||||
0 => self.alarm0.load_value(timestamp.micros()).unwrap(),
|
||||
1 => self.alarm1.load_value(timestamp.micros()).unwrap(),
|
||||
2 => self.alarm2.load_value(timestamp.micros()).unwrap(),
|
||||
0 => self.alarm0.set_target(timestamp),
|
||||
1 => self.alarm1.set_target(timestamp),
|
||||
2 => self.alarm2.set_target(timestamp),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@ -1,27 +1,30 @@
|
||||
use critical_section::{CriticalSection, Mutex};
|
||||
use peripherals::TIMG0;
|
||||
|
||||
use super::AlarmState;
|
||||
use embassy_time_driver::AlarmHandle;
|
||||
#[cfg(any(esp32, esp32s2, esp32s3))]
|
||||
use crate::timer::timg::Timer1;
|
||||
use crate::{
|
||||
use esp_hal::timer::timg::Timer1;
|
||||
use esp_hal::{
|
||||
clock::Clocks,
|
||||
peripherals,
|
||||
interrupt::{self, Priority},
|
||||
peripherals::{Interrupt, TIMG0},
|
||||
prelude::*,
|
||||
timer::timg::{Instance, Timer0, TimerGroup},
|
||||
Async,
|
||||
};
|
||||
|
||||
use crate::AlarmState;
|
||||
|
||||
#[cfg(not(any(esp32, esp32s2, esp32s3)))]
|
||||
pub const ALARM_COUNT: usize = 1;
|
||||
#[cfg(any(esp32, esp32s2, esp32s3))]
|
||||
pub const ALARM_COUNT: usize = 2;
|
||||
|
||||
pub type TimerType = TimerGroup<'static, TIMG0, crate::Async>;
|
||||
pub type TimerType = TimerGroup<'static, TIMG0, Async>;
|
||||
|
||||
pub struct EmbassyTimer {
|
||||
pub(crate) alarms: Mutex<[AlarmState; ALARM_COUNT]>,
|
||||
}
|
||||
|
||||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const ALARM_STATE_NONE: AlarmState = AlarmState::new();
|
||||
|
||||
embassy_time_driver::time_driver_impl!(static DRIVER: EmbassyTimer = EmbassyTimer {
|
||||
@ -41,7 +44,7 @@ impl EmbassyTimer {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn on_alarm_allocated(&self, _n: usize) {}
|
||||
pub(crate) fn on_alarm_allocated(&self, _n: usize) {}
|
||||
|
||||
fn on_interrupt<Timer: Instance>(&self, id: u8, timer: Timer) {
|
||||
critical_section::with(|cs| {
|
||||
@ -62,48 +65,36 @@ impl EmbassyTimer {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
crate::interrupt::bind_interrupt(
|
||||
crate::peripherals::Interrupt::TG0_T0_LEVEL,
|
||||
tg0_t0_level.handler(),
|
||||
);
|
||||
crate::interrupt::enable(
|
||||
crate::peripherals::Interrupt::TG0_T0_LEVEL,
|
||||
tg0_t0_level.priority(),
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::bind_interrupt(Interrupt::TG0_T0_LEVEL, tg0_t0_level.handler());
|
||||
unwrap!(interrupt::enable(
|
||||
Interrupt::TG0_T0_LEVEL,
|
||||
tg0_t0_level.priority()
|
||||
));
|
||||
}
|
||||
#[cfg(any(esp32, esp32s2, esp32s3))]
|
||||
unsafe {
|
||||
crate::interrupt::bind_interrupt(
|
||||
crate::peripherals::Interrupt::TG0_T1_LEVEL,
|
||||
tg0_t1_level.handler(),
|
||||
);
|
||||
crate::interrupt::enable(
|
||||
crate::peripherals::Interrupt::TG0_T1_LEVEL,
|
||||
tg0_t1_level.priority(),
|
||||
)
|
||||
.unwrap();
|
||||
interrupt::bind_interrupt(Interrupt::TG0_T1_LEVEL, tg0_t1_level.handler());
|
||||
unwrap!(interrupt::enable(
|
||||
Interrupt::TG0_T1_LEVEL,
|
||||
tg0_t1_level.priority()
|
||||
));
|
||||
}
|
||||
|
||||
#[handler(priority = crate::interrupt::Priority::max())]
|
||||
#[handler(priority = Priority::max())]
|
||||
fn tg0_t0_level() {
|
||||
let timer = unsafe { Timer0::<TIMG0>::steal() };
|
||||
DRIVER.on_interrupt(0, timer);
|
||||
}
|
||||
|
||||
#[cfg(any(esp32, esp32s2, esp32s3))]
|
||||
#[handler(priority = crate::interrupt::Priority::max())]
|
||||
#[handler(priority = Priority::max())]
|
||||
fn tg0_t1_level() {
|
||||
let timer = unsafe { Timer1::<TIMG0>::steal() };
|
||||
DRIVER.on_interrupt(1, timer);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn set_alarm(
|
||||
&self,
|
||||
_alarm: embassy_time_driver::AlarmHandle,
|
||||
timestamp: u64,
|
||||
) -> bool {
|
||||
pub(crate) fn set_alarm(&self, _alarm: AlarmHandle, timestamp: u64) -> bool {
|
||||
critical_section::with(|_cs| {
|
||||
// The hardware fires the alarm even if timestamp is lower than the current
|
||||
// time. In this case the interrupt handler will pend a wakeup when we exit the
|
||||
@ -122,7 +113,10 @@ impl EmbassyTimer {
|
||||
true
|
||||
}
|
||||
|
||||
fn arm<Timer: Instance>(tg: &mut Timer, timestamp: u64) {
|
||||
fn arm<T>(tg: &mut T, timestamp: u64)
|
||||
where
|
||||
T: Instance,
|
||||
{
|
||||
tg.load_alarm_value(timestamp);
|
||||
tg.listen();
|
||||
tg.set_counter_decrementing(false);
|
||||
@ -22,8 +22,7 @@ pub(crate) mod main {
|
||||
use std::{cell::RefCell, fmt::Display, thread};
|
||||
|
||||
use darling::{export::NestedMeta, FromMeta};
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use proc_macro_crate::{crate_name, FoundCrate};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::{ReturnType, Type};
|
||||
|
||||
@ -157,23 +156,10 @@ pub(crate) mod main {
|
||||
}
|
||||
|
||||
pub fn main() -> TokenStream {
|
||||
let hal_crate = if cfg!(any(feature = "is-lp-core", feature = "is-ulp-core")) {
|
||||
crate_name("esp-lp-hal")
|
||||
} else {
|
||||
crate_name("esp-hal")
|
||||
};
|
||||
|
||||
let executor = if let Ok(FoundCrate::Name(ref name)) = hal_crate {
|
||||
let ident = Ident::new(&name, Span::call_site().into());
|
||||
quote!( #ident::embassy::executor::Executor )
|
||||
} else {
|
||||
quote!(crate::embassy::executor::Executor)
|
||||
};
|
||||
|
||||
quote! {
|
||||
#[entry]
|
||||
fn main() -> ! {
|
||||
let mut executor = #executor::new();
|
||||
let mut executor = ::esp_hal_embassy::Executor::new();
|
||||
let executor = unsafe { __make_static(&mut executor) };
|
||||
executor.run(|spawner| {
|
||||
spawner.must_spawn(__embassy_main(spawner));
|
||||
|
||||
@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Removed the `SystemExt` trait (#1495)
|
||||
- Removed the `GpioExt` trait (#1496)
|
||||
- Embassy support (and all related features) has been removed, now available in the `esp-hal-embassy` package instead (#1595)
|
||||
|
||||
## [0.17.0] - 2024-04-18
|
||||
|
||||
|
||||
@ -22,10 +22,8 @@ critical-section = "1.1.2"
|
||||
defmt = { version = "0.3.6", optional = true }
|
||||
delegate = "0.12.0"
|
||||
document-features = "0.2.8"
|
||||
embassy-executor = { version = "0.5.0", optional = true }
|
||||
embassy-futures = { version = "0.1.1", optional = true }
|
||||
embassy-sync = { version = "0.5.0", optional = true }
|
||||
embassy-time-driver = { version = "0.1.0", optional = true }
|
||||
embassy-usb-driver = { version = "0.1.0", optional = true }
|
||||
embassy-usb-synopsys-otg = { version = "0.1.0", optional = true }
|
||||
embedded-can = { version = "0.4.1", optional = true }
|
||||
@ -43,7 +41,7 @@ log = { version = "0.4.21", optional = true }
|
||||
nb = "1.1.0"
|
||||
paste = "1.0.14"
|
||||
portable-atomic = { version = "1.6.0", default-features = false }
|
||||
procmacros = { version = "0.10.0", features = ["enum-dispatch", "interrupt", "ram"], package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
|
||||
procmacros = { version = "0.10.0", features = ["embassy", "enum-dispatch", "interrupt", "ram"], package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
|
||||
riscv = { version = "0.11.1", optional = true }
|
||||
strum = { version = "0.26.2", default-features = false, features = ["derive"] }
|
||||
void = { version = "1.0.2", default-features = false }
|
||||
@ -145,7 +143,6 @@ async = [
|
||||
## Implement `defmt::Format` on certain types.
|
||||
defmt = [
|
||||
"dep:defmt",
|
||||
"embassy-executor?/defmt",
|
||||
"embassy-futures?/defmt",
|
||||
"embassy-sync?/defmt",
|
||||
"embedded-hal?/defmt-03",
|
||||
@ -169,25 +166,6 @@ embedded-io = ["dep:embedded-io"]
|
||||
## Implement the `ufmt_write::uWrite` trait for certain peripherals.
|
||||
ufmt = ["dep:ufmt-write"]
|
||||
|
||||
#! ### Embassy Feature Flags
|
||||
## Enable support for `embassy`, a modern asynchronous embedded framework.
|
||||
embassy = ["embassy-time-driver", "procmacros/embassy", "embassy-executor"]
|
||||
## Uses hardware timers as alarms for the executors. Using this feature
|
||||
## limits the number of executors to the number of hardware alarms provided
|
||||
## by the time driver.
|
||||
embassy-integrated-timers = ["embassy-executor?/integrated-timers"]
|
||||
## Enable the embassy time driver using the `SYSTIMER` peripheral. The
|
||||
## `SYSTIMER` peripheral has three alarams available for use. Do **not**
|
||||
## use when targeting an `esp32s2`.
|
||||
embassy-time-systick-16mhz = ["embassy-time-driver/tick-hz-16_000_000"]
|
||||
## Enable the embassy time driver using the `SYSTIMER` peripheral. The
|
||||
## `SYSTIMER` peripheral has three alarams available for use. Must only
|
||||
## be used when targeting an `esp32s2`.
|
||||
embassy-time-systick-80mhz = ["embassy-time-driver/tick-hz-80_000_000"]
|
||||
## Enable the embassy time driver using the `TIMG0` peripheral. The `TIMG0`
|
||||
## peripheral has two alarms available for use.
|
||||
embassy-time-timg0 = ["embassy-time-driver/tick-hz-1_000_000"]
|
||||
|
||||
#! ### PSRAM Feature Flags
|
||||
## Use externally connected PSRAM (2MB).
|
||||
psram-2m = []
|
||||
@ -209,15 +187,7 @@ opsram-8m = []
|
||||
opsram-16m = []
|
||||
|
||||
# This feature is intended for testing; you probably don't want to enable it:
|
||||
ci = [
|
||||
"default",
|
||||
"embedded-hal-02",
|
||||
"ufmt",
|
||||
"async",
|
||||
"embassy",
|
||||
"embassy-time-timg0",
|
||||
"embedded-io"
|
||||
]
|
||||
ci = ["async", "embedded-hal-02", "embedded-io", "ufmt"]
|
||||
|
||||
[lints.clippy]
|
||||
mixed_attributes_style = "allow"
|
||||
|
||||
@ -26,19 +26,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
"esp32", "esp32c2", "esp32c3", "esp32c6", "esp32h2", "esp32s2", "esp32s3"
|
||||
);
|
||||
|
||||
// If the `embassy` feature is enabled, ensure that a time driver implementation
|
||||
// is available:
|
||||
#[cfg(feature = "embassy")]
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "esp32")] {
|
||||
assert_unique_used_features!("embassy-time-timg0");
|
||||
} else if #[cfg(feature = "esp32s2")] {
|
||||
assert_unique_used_features!("embassy-time-systick-80mhz", "embassy-time-timg0");
|
||||
} else {
|
||||
assert_unique_used_features!("embassy-time-systick-16mhz", "embassy-time-timg0");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
feature = "flip-link",
|
||||
not(any(feature = "esp32c6", feature = "esp32h2"))
|
||||
|
||||
@ -1,107 +0,0 @@
|
||||
//! # Embassy
|
||||
//!
|
||||
//! The [embassy](https://github.com/embassy-rs/embassy) project is a toolkit to leverage async Rust
|
||||
//! in embedded applications. This module adds the required
|
||||
//! support to use embassy on Espressif chips.
|
||||
//!
|
||||
//! ## Initialization
|
||||
//!
|
||||
//! Embassy **must** be initialized by calling [`init`], before beginning any
|
||||
//! async operations.
|
||||
//!
|
||||
//! [`init`] installs a [global time driver](https://github.com/embassy-rs/embassy/tree/main/embassy-time#global-time-driver)
|
||||
//! allowing users to use [embassy-time](https://docs.rs/embassy-time/latest/embassy_time/) APIs in any async context
|
||||
//! within their application. A time driver must be chosen by enabling the
|
||||
//! correct feature on esp-hal, see the crate level documentation for more
|
||||
//! details.
|
||||
//!
|
||||
//! ## Executors
|
||||
//!
|
||||
//! We offer two executor types, a thread mode [`Executor`](executor::Executor)
|
||||
//! and [`InterruptExecutor`](executor::InterruptExecutor).
|
||||
//! An [`InterruptExecutor`](executor::InterruptExecutor) can be used to achieve
|
||||
//! preemptive multitasking in async applications, which is usually something reserved for more traditional RTOS systems, read more about it in [the embassy documentation](https://embassy.dev/book/dev/runtime.html).
|
||||
|
||||
pub mod executor;
|
||||
|
||||
use core::cell::Cell;
|
||||
|
||||
use embassy_time_driver::{AlarmHandle, Driver};
|
||||
|
||||
#[cfg_attr(
|
||||
all(
|
||||
systimer,
|
||||
any(
|
||||
feature = "embassy-time-systick-16mhz",
|
||||
feature = "embassy-time-systick-80mhz"
|
||||
)
|
||||
),
|
||||
path = "time_driver_systimer.rs"
|
||||
)]
|
||||
#[cfg_attr(
|
||||
all(timg0, feature = "embassy-time-timg0"),
|
||||
path = "time_driver_timg.rs"
|
||||
)]
|
||||
mod time_driver;
|
||||
|
||||
use time_driver::EmbassyTimer;
|
||||
|
||||
use crate::clock::Clocks;
|
||||
|
||||
/// Initialize embassy
|
||||
pub fn init(clocks: &Clocks, time_driver: time_driver::TimerType) {
|
||||
EmbassyTimer::init(clocks, time_driver)
|
||||
}
|
||||
|
||||
pub(crate) struct AlarmState {
|
||||
pub callback: Cell<Option<(fn(*mut ()), *mut ())>>,
|
||||
pub allocated: Cell<bool>,
|
||||
}
|
||||
|
||||
unsafe impl Send for AlarmState {}
|
||||
|
||||
impl AlarmState {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
callback: Cell::new(None),
|
||||
allocated: Cell::new(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for EmbassyTimer {
|
||||
fn now(&self) -> u64 {
|
||||
EmbassyTimer::now()
|
||||
}
|
||||
|
||||
unsafe fn allocate_alarm(&self) -> Option<AlarmHandle> {
|
||||
critical_section::with(|cs| {
|
||||
for (i, alarm) in self.alarms.borrow(cs).iter().enumerate() {
|
||||
if !alarm.allocated.get() {
|
||||
// set alarm so it is not overwritten
|
||||
alarm.allocated.set(true);
|
||||
self.on_alarm_allocated(i);
|
||||
return Some(AlarmHandle::new(i as u8));
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
fn set_alarm_callback(
|
||||
&self,
|
||||
alarm: embassy_time_driver::AlarmHandle,
|
||||
callback: fn(*mut ()),
|
||||
ctx: *mut (),
|
||||
) {
|
||||
let n = alarm.id() as usize;
|
||||
critical_section::with(|cs| {
|
||||
let alarm = &self.alarms.borrow(cs)[n];
|
||||
alarm.callback.set(Some((callback, ctx)));
|
||||
})
|
||||
}
|
||||
|
||||
fn set_alarm(&self, alarm: embassy_time_driver::AlarmHandle, timestamp: u64) -> bool {
|
||||
self.set_alarm(alarm, timestamp)
|
||||
}
|
||||
}
|
||||
@ -104,8 +104,6 @@ pub mod delay;
|
||||
pub mod dma;
|
||||
#[cfg(ecc)]
|
||||
pub mod ecc;
|
||||
#[cfg(feature = "embassy")]
|
||||
pub mod embassy;
|
||||
#[cfg(soc_etm)]
|
||||
pub mod etm;
|
||||
#[cfg(gpio)]
|
||||
|
||||
@ -227,7 +227,7 @@ where
|
||||
DM: Mode,
|
||||
{
|
||||
/// Set the target value of this [Alarm]
|
||||
pub fn set_target(&mut self, timestamp: u64) {
|
||||
pub fn set_target(&self, timestamp: u64) {
|
||||
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));
|
||||
@ -238,7 +238,7 @@ where
|
||||
}
|
||||
|
||||
/// Block waiting until the timer reaches the `timestamp`
|
||||
pub fn wait_until(&mut self, timestamp: u64) {
|
||||
pub fn wait_until(&self, timestamp: u64) {
|
||||
self.clear_interrupt();
|
||||
self.set_target(timestamp);
|
||||
|
||||
@ -261,7 +261,7 @@ where
|
||||
DM: Mode,
|
||||
{
|
||||
/// Set the period of this [Alarm]
|
||||
pub fn set_period(&mut self, period: MicrosDurationU32) {
|
||||
pub fn set_period(&self, period: MicrosDurationU32) {
|
||||
let us = period.ticks();
|
||||
let ticks = us * (SystemTimer::TICKS_PER_SECOND / 1_000_000) as u32;
|
||||
|
||||
|
||||
@ -611,8 +611,14 @@ impl<TG, const T: u8> TimerX<TG, T>
|
||||
where
|
||||
TG: TimerGroupInstance,
|
||||
{
|
||||
/// Unsafely create an instance of this peripheral out of thin air.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// You must ensure that you're only using one instance of this type at a
|
||||
/// time.
|
||||
#[allow(unused)]
|
||||
pub(crate) unsafe fn steal() -> Self {
|
||||
pub unsafe fn steal() -> Self {
|
||||
Self {
|
||||
phantom: PhantomData,
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ categories = ["embedded", "hardware-support", "no-std"]
|
||||
[dependencies]
|
||||
defmt = { version = "0.3.6", optional = true }
|
||||
esp-hal = { version = "0.17.0", path = "../esp-hal", default-features = false }
|
||||
esp-hal-embassy = { version = "0.1.0", path = "../esp-hal-embassy", optional = true }
|
||||
smoltcp = { version = "0.11.0", default-features = false, features = [
|
||||
"medium-ethernet",
|
||||
"socket-raw",
|
||||
@ -61,30 +62,37 @@ default = ["log"]
|
||||
# chip features
|
||||
esp32c2 = [
|
||||
"esp-hal/esp32c2",
|
||||
"esp-hal-embassy?/esp32c2",
|
||||
"esp-wifi-sys/esp32c2",
|
||||
]
|
||||
esp32c3 = [
|
||||
"esp-hal/esp32c3",
|
||||
"esp-hal-embassy?/esp32c3",
|
||||
"esp-wifi-sys/esp32c3",
|
||||
]
|
||||
esp32c6 = [
|
||||
"esp-hal/esp32c6",
|
||||
"esp-hal-embassy?/esp32c6",
|
||||
"esp-wifi-sys/esp32c6",
|
||||
]
|
||||
esp32h2 = [
|
||||
"esp-hal/esp32h2",
|
||||
"esp-hal-embassy?/esp32h2",
|
||||
"esp-wifi-sys/esp32h2",
|
||||
]
|
||||
esp32 = [
|
||||
"esp-hal/esp32",
|
||||
"esp-hal-embassy?/esp32",
|
||||
"esp-wifi-sys/esp32",
|
||||
]
|
||||
esp32s2 = [
|
||||
"esp-hal/esp32s2",
|
||||
"esp-hal-embassy?/esp32s2",
|
||||
"esp-wifi-sys/esp32s2",
|
||||
]
|
||||
esp32s3 = [
|
||||
"esp-hal/esp32s3",
|
||||
"esp-hal-embassy?/esp32s3",
|
||||
"esp-wifi-sys/esp32s3",
|
||||
]
|
||||
|
||||
@ -93,6 +101,8 @@ async = [
|
||||
"dep:embassy-sync",
|
||||
"dep:embassy-futures",
|
||||
"dep:embedded-io-async",
|
||||
"dep:esp-hal-embassy",
|
||||
"esp-hal/async",
|
||||
]
|
||||
|
||||
embassy-net = ["dep:embassy-net-driver", "async"]
|
||||
@ -131,7 +141,7 @@ features = [
|
||||
"coex",
|
||||
"async",
|
||||
"embassy-net",
|
||||
"esp-hal/embassy-time-timg0",
|
||||
"esp-hal-embassy/time-timg0",
|
||||
"esp-hal/default",
|
||||
]
|
||||
default-target = "riscv32imc-unknown-none-elf"
|
||||
|
||||
@ -30,7 +30,7 @@ pub fn setup_timer(systimer: TimeBase) -> Result<(), esp_hal::timer::Error> {
|
||||
// make sure the scheduling won't start before everything is setup
|
||||
riscv::interrupt::disable();
|
||||
|
||||
let mut alarm0 = systimer.into_periodic();
|
||||
let alarm0 = systimer.into_periodic();
|
||||
alarm0.set_period(TIMESLICE_FREQUENCY.into_duration());
|
||||
alarm0.clear_interrupt();
|
||||
alarm0.enable_interrupt(true);
|
||||
@ -83,8 +83,8 @@ extern "C" fn FROM_CPU_INTR3(trap_frame: &mut TrapFrame) {
|
||||
}
|
||||
|
||||
critical_section::with(|cs| {
|
||||
let mut alarm0 = ALARM0.borrow_ref_mut(cs);
|
||||
let alarm0 = unwrap!(alarm0.as_mut());
|
||||
let alarm0 = ALARM0.borrow_ref(cs);
|
||||
let alarm0 = unwrap!(alarm0.as_ref());
|
||||
|
||||
alarm0.set_period(TIMESLICE_FREQUENCY.into_duration());
|
||||
alarm0.clear_interrupt();
|
||||
|
||||
@ -28,6 +28,11 @@ rustflags = [
|
||||
|
||||
[env]
|
||||
ESP_LOGLEVEL = "info"
|
||||
SSID = "SSID"
|
||||
PASSWORD = "PASSWORD"
|
||||
STATIC_IP = "1.1.1.1 "
|
||||
GATEWAY_IP = "1.1.1.1"
|
||||
HOST_IP = "1.1.1.1"
|
||||
|
||||
[unstable]
|
||||
build-std = ["alloc", "core"]
|
||||
|
||||
@ -31,6 +31,7 @@ embedded-storage = "0.3.0"
|
||||
esp-alloc = { path = "../esp-alloc" }
|
||||
esp-backtrace = { path = "../esp-backtrace", features = ["exception-handler", "panic-handler", "println"] }
|
||||
esp-hal = { path = "../esp-hal", features = ["log"] }
|
||||
esp-hal-embassy = { path = "../esp-hal-embassy", optional = true }
|
||||
esp-hal-smartled = { path = "../esp-hal-smartled", optional = true }
|
||||
esp-ieee802154 = { path = "../esp-ieee802154", optional = true }
|
||||
esp-println = { path = "../esp-println", features = ["log"] }
|
||||
@ -56,13 +57,13 @@ usb-device = "0.3.2"
|
||||
usbd-serial = "0.2.1"
|
||||
|
||||
[features]
|
||||
esp32 = ["esp-hal/esp32", "esp-backtrace/esp32", "esp-println/esp32", "esp-hal-smartled/esp32", "esp-wifi?/esp32", "esp-storage?/esp32"]
|
||||
esp32c2 = ["esp-hal/esp32c2", "esp-backtrace/esp32c2", "esp-println/esp32c2", "esp-wifi?/esp32c2", "esp-storage?/esp32c2"]
|
||||
esp32c3 = ["esp-hal/esp32c3", "esp-backtrace/esp32c3", "esp-println/esp32c3", "esp-hal-smartled/esp32c3", "esp-wifi?/esp32c3", "esp-storage?/esp32c3"]
|
||||
esp32c6 = ["esp-hal/esp32c6", "esp-backtrace/esp32c6", "esp-println/esp32c6", "esp-hal-smartled/esp32c6", "esp-ieee802154/esp32c6", "esp-wifi?/esp32c6", "esp-storage?/esp32c6"]
|
||||
esp32h2 = ["esp-hal/esp32h2", "esp-backtrace/esp32h2", "esp-println/esp32h2", "esp-hal-smartled/esp32h2", "esp-ieee802154/esp32h2", "esp-wifi?/esp32h2", "esp-storage?/esp32h2"]
|
||||
esp32s2 = ["esp-hal/esp32s2", "esp-backtrace/esp32s2", "esp-println/esp32s2", "esp-hal-smartled/esp32s2", "esp-wifi?/esp32s2", "esp-storage?/esp32s2"]
|
||||
esp32s3 = ["esp-hal/esp32s3", "esp-backtrace/esp32s3", "esp-println/esp32s3", "esp-hal-smartled/esp32s3", "esp-wifi?/esp32s3", "esp-storage?/esp32s3"]
|
||||
esp32 = ["esp-hal/esp32", "esp-backtrace/esp32", "esp-hal-embassy?/esp32", "esp-println/esp32", "esp-storage?/esp32", "esp-wifi?/esp32", "esp-hal-smartled/esp32"]
|
||||
esp32c2 = ["esp-hal/esp32c2", "esp-backtrace/esp32c2", "esp-hal-embassy?/esp32c2", "esp-println/esp32c2", "esp-storage?/esp32c2", "esp-wifi?/esp32c2", ]
|
||||
esp32c3 = ["esp-hal/esp32c3", "esp-backtrace/esp32c3", "esp-hal-embassy?/esp32c3", "esp-println/esp32c3", "esp-storage?/esp32c3", "esp-wifi?/esp32c3", "esp-hal-smartled/esp32c3"]
|
||||
esp32c6 = ["esp-hal/esp32c6", "esp-backtrace/esp32c6", "esp-hal-embassy?/esp32c6", "esp-println/esp32c6", "esp-storage?/esp32c6", "esp-wifi?/esp32c6", "esp-hal-smartled/esp32c6", "esp-ieee802154/esp32c6"]
|
||||
esp32h2 = ["esp-hal/esp32h2", "esp-backtrace/esp32h2", "esp-hal-embassy?/esp32h2", "esp-println/esp32h2", "esp-storage?/esp32h2", "esp-wifi?/esp32h2", "esp-hal-smartled/esp32h2", "esp-ieee802154/esp32h2"]
|
||||
esp32s2 = ["esp-hal/esp32s2", "esp-backtrace/esp32s2", "esp-hal-embassy?/esp32s2", "esp-println/esp32s2", "esp-storage?/esp32s2", "esp-wifi?/esp32s2", "esp-hal-smartled/esp32s2"]
|
||||
esp32s3 = ["esp-hal/esp32s3", "esp-backtrace/esp32s3", "esp-hal-embassy?/esp32s3", "esp-println/esp32s3", "esp-storage?/esp32s3", "esp-wifi?/esp32s3", "esp-hal-smartled/esp32s3"]
|
||||
|
||||
esp-wifi = ["dep:esp-wifi"]
|
||||
|
||||
@ -71,10 +72,10 @@ async = ["esp-hal/async", "embassy-usb"]
|
||||
embedded-hal-02 = ["esp-hal/embedded-hal-02"]
|
||||
embedded-hal = ["esp-hal/embedded-hal"]
|
||||
|
||||
embassy = ["esp-hal/embassy"]
|
||||
embassy = ["dep:esp-hal-embassy"]
|
||||
|
||||
embassy-time-systick-16mhz = ["esp-hal/embassy-time-systick-16mhz"]
|
||||
embassy-time-timg0 = ["esp-hal/embassy-time-timg0"]
|
||||
embassy-time-systimer-16mhz = ["esp-hal-embassy/time-systimer-16mhz"]
|
||||
embassy-time-timg0 = ["esp-hal-embassy/time-timg0"]
|
||||
embassy-generic-timers = ["embassy-time/generic-queue-8"]
|
||||
|
||||
opsram-2m = ["esp-hal/opsram-2m"]
|
||||
|
||||
@ -14,7 +14,6 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy::{self},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
system::SystemControl,
|
||||
@ -37,7 +36,7 @@ async fn main(spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
spawner.spawn(run()).ok();
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy::{self},
|
||||
gpio::Io,
|
||||
i2c::I2C,
|
||||
peripherals::Peripherals,
|
||||
@ -38,7 +37,7 @@ async fn main(_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy::{self},
|
||||
gpio::Io,
|
||||
i2c::I2C,
|
||||
peripherals::Peripherals,
|
||||
@ -38,7 +37,7 @@ async fn main(_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
|
||||
@ -23,7 +23,6 @@ use esp_hal::{
|
||||
clock::ClockControl,
|
||||
dma::{Dma, DmaPriority},
|
||||
dma_buffers,
|
||||
embassy,
|
||||
gpio::Io,
|
||||
i2s::{asynch::*, DataFormat, I2s, Standard},
|
||||
peripherals::Peripherals,
|
||||
@ -41,7 +40,7 @@ async fn main(_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
|
||||
@ -38,7 +38,6 @@ use esp_hal::{
|
||||
clock::ClockControl,
|
||||
dma::{Dma, DmaPriority},
|
||||
dma_buffers,
|
||||
embassy::{self},
|
||||
gpio::Io,
|
||||
i2s::{asynch::*, DataFormat, I2s, Standard},
|
||||
peripherals::Peripherals,
|
||||
@ -64,7 +63,7 @@ async fn main(_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
|
||||
@ -18,7 +18,6 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
cpu_control::{CpuControl, Stack},
|
||||
embassy::{self, executor::Executor},
|
||||
get_core,
|
||||
gpio::{AnyOutput, Io, Level},
|
||||
peripherals::Peripherals,
|
||||
@ -26,6 +25,7 @@ use esp_hal::{
|
||||
system::SystemControl,
|
||||
timer::timg::TimerGroup,
|
||||
};
|
||||
use esp_hal_embassy::Executor;
|
||||
use esp_println::println;
|
||||
use static_cell::StaticCell;
|
||||
|
||||
@ -59,7 +59,7 @@ async fn main(_spawner: Spawner) {
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
|
||||
|
||||
|
||||
@ -17,7 +17,6 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
cpu_control::{CpuControl, Stack},
|
||||
embassy::{self, executor::InterruptExecutor},
|
||||
get_core,
|
||||
gpio::{AnyOutput, Io, Level},
|
||||
interrupt::Priority,
|
||||
@ -26,6 +25,7 @@ use esp_hal::{
|
||||
system::SystemControl,
|
||||
timer::timg::TimerGroup,
|
||||
};
|
||||
use esp_hal_embassy::InterruptExecutor;
|
||||
use esp_println::println;
|
||||
use static_cell::StaticCell;
|
||||
|
||||
@ -78,7 +78,7 @@ fn main() -> ! {
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let mut cpu_control = CpuControl::new(peripherals.CPU_CTRL);
|
||||
|
||||
|
||||
@ -25,13 +25,13 @@ use embassy_time::{Duration, Instant, Ticker, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy::{self, executor::InterruptExecutor},
|
||||
interrupt::Priority,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
system::SystemControl,
|
||||
timer::timg::TimerGroup,
|
||||
};
|
||||
use esp_hal_embassy::InterruptExecutor;
|
||||
use esp_println::println;
|
||||
use static_cell::StaticCell;
|
||||
|
||||
@ -79,7 +79,7 @@ async fn main(low_prio_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
static EXECUTOR: StaticCell<InterruptExecutor<2>> = StaticCell::new();
|
||||
let executor = InterruptExecutor::new(system.software_interrupt_control.software_interrupt2);
|
||||
|
||||
@ -16,7 +16,6 @@ use esp_hal::{
|
||||
clock::ClockControl,
|
||||
dma::{Dma, DmaPriority},
|
||||
dma_buffers,
|
||||
embassy,
|
||||
gpio::Io,
|
||||
parl_io::{no_clk_pin, BitPackOrder, ParlIoRxOnly, RxFourBits},
|
||||
peripherals::Peripherals,
|
||||
@ -34,7 +33,7 @@ async fn main(_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
|
||||
@ -20,7 +20,6 @@ use esp_hal::{
|
||||
clock::ClockControl,
|
||||
dma::{Dma, DmaPriority},
|
||||
dma_buffers,
|
||||
embassy,
|
||||
gpio::Io,
|
||||
parl_io::{
|
||||
BitPackOrder,
|
||||
@ -45,7 +44,7 @@ async fn main(_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy::{self},
|
||||
gpio::{Gpio5, Io, Level, Output},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
@ -45,7 +44,7 @@ async fn main(spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timer_group0 = esp_hal::timer::timg::TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timer_group0);
|
||||
esp_hal_embassy::init(&clocks, timer_group0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
|
||||
@ -13,7 +13,6 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
gpio::Io,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
@ -31,7 +30,7 @@ async fn main(_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@ use embassy_sync::{blocking_mutex::raw::NoopRawMutex, signal::Signal};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
peripherals::{Peripherals, UART0},
|
||||
prelude::*,
|
||||
system::SystemControl,
|
||||
@ -81,7 +80,7 @@ async fn main(spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let mut uart0 = Uart::new_async(peripherals.UART0, &clocks);
|
||||
uart0.set_at_cmd(AtCmdConfig::new(None, None, None, AT_CMD, None));
|
||||
|
||||
@ -27,7 +27,6 @@ use esp_hal::{
|
||||
clock::ClockControl,
|
||||
dma::*,
|
||||
dma_descriptors,
|
||||
embassy::{self},
|
||||
gpio::Io,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
@ -47,7 +46,7 @@ async fn main(_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
let sclk = io.pins.gpio0;
|
||||
|
||||
@ -22,7 +22,6 @@ use embedded_can::{Frame, Id};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy::{self},
|
||||
gpio::Io,
|
||||
interrupt,
|
||||
peripherals::{self, Peripherals, TWAI0},
|
||||
@ -87,7 +86,7 @@ async fn main(spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
|
||||
@ -18,7 +18,6 @@ use embassy_usb::{
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
gpio::Io,
|
||||
otg_fs::{
|
||||
asynch::{Config, Driver},
|
||||
@ -37,7 +36,7 @@ async fn main(_spawner: Spawner) -> () {
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
embassy::init(&clocks, TimerGroup::new_async(peripherals.TIMG0, &clocks));
|
||||
esp_hal_embassy::init(&clocks, TimerGroup::new_async(peripherals.TIMG0, &clocks));
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
|
||||
let usb = Usb::new(peripherals.USB0, io.pins.gpio19, io.pins.gpio20);
|
||||
|
||||
@ -13,7 +13,6 @@ use embassy_sync::{blocking_mutex::raw::NoopRawMutex, signal::Signal};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
system::SystemControl,
|
||||
@ -71,7 +70,7 @@ async fn main(spawner: Spawner) -> () {
|
||||
let system = SystemControl::new(peripherals.SYSTEM);
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
embassy::init(&clocks, TimerGroup::new_async(peripherals.TIMG0, &clocks));
|
||||
esp_hal_embassy::init(&clocks, TimerGroup::new_async(peripherals.TIMG0, &clocks));
|
||||
|
||||
let (tx, rx) = UsbSerialJtag::new_async(peripherals.USB_DEVICE).split();
|
||||
|
||||
|
||||
@ -13,7 +13,6 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
gpio::{Input, Io, Pull},
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
@ -29,7 +28,7 @@ async fn main(_spawner: Spawner) {
|
||||
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
let io = Io::new(peripherals.GPIO, peripherals.IO_MUX);
|
||||
#[cfg(any(feature = "esp32", feature = "esp32s2", feature = "esp32s3"))]
|
||||
|
||||
@ -29,7 +29,6 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rng::Rng,
|
||||
@ -87,7 +86,7 @@ async fn main(spawner: Spawner) -> ! {
|
||||
esp_wifi::wifi::new_with_mode(&init, wifi, WifiApDevice).unwrap();
|
||||
|
||||
let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timer_group0);
|
||||
esp_hal_embassy::init(&clocks, timer_group0);
|
||||
|
||||
let config = Config::ipv4_static(StaticConfigV4 {
|
||||
address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 2, 1), 24),
|
||||
|
||||
@ -32,7 +32,6 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rng::Rng,
|
||||
@ -95,7 +94,7 @@ async fn main(spawner: Spawner) -> ! {
|
||||
esp_wifi::wifi::new_ap_sta(&init, wifi).unwrap();
|
||||
|
||||
let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timer_group0);
|
||||
esp_hal_embassy::init(&clocks, timer_group0);
|
||||
|
||||
let ap_config = Config::ipv4_static(StaticConfigV4 {
|
||||
address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 2, 1), 24),
|
||||
|
||||
@ -23,7 +23,6 @@ use embassy_time::{with_timeout, Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rng::Rng,
|
||||
@ -99,7 +98,7 @@ async fn main(spawner: Spawner) -> ! {
|
||||
esp_wifi::wifi::new_with_mode(&init, wifi, WifiStaDevice).unwrap();
|
||||
|
||||
let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timer_group0);
|
||||
esp_hal_embassy::init(&clocks, timer_group0);
|
||||
|
||||
let config = Config::dhcpv4(Default::default());
|
||||
|
||||
|
||||
@ -28,7 +28,6 @@ use embassy_executor::Spawner;
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
gpio::{Input, Io, Pull},
|
||||
peripherals::*,
|
||||
prelude::*,
|
||||
@ -73,7 +72,7 @@ async fn main(_spawner: Spawner) -> ! {
|
||||
let button = Input::new(io.pins.gpio9, Pull::Down);
|
||||
|
||||
let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timer_group0);
|
||||
esp_hal_embassy::init(&clocks, timer_group0);
|
||||
|
||||
let mut bluetooth = peripherals.BT;
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ use embassy_time::{Duration, Timer};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rng::Rng,
|
||||
@ -80,7 +79,7 @@ async fn main(spawner: Spawner) -> ! {
|
||||
esp_wifi::wifi::new_with_mode(&init, wifi, WifiStaDevice).unwrap();
|
||||
|
||||
let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timer_group0);
|
||||
esp_hal_embassy::init(&clocks, timer_group0);
|
||||
|
||||
let config = Config::dhcpv4(Default::default());
|
||||
|
||||
|
||||
@ -16,7 +16,6 @@ use embassy_time::{Duration, Ticker};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rng::Rng,
|
||||
@ -57,7 +56,7 @@ async fn main(_spawner: Spawner) -> ! {
|
||||
println!("esp-now version {}", esp_now.get_version().unwrap());
|
||||
|
||||
let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timer_group0);
|
||||
esp_hal_embassy::init(&clocks, timer_group0);
|
||||
|
||||
let mut ticker = Ticker::every(Duration::from_secs(5));
|
||||
loop {
|
||||
|
||||
@ -16,7 +16,6 @@ use embassy_time::{Duration, Ticker};
|
||||
use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
embassy,
|
||||
peripherals::Peripherals,
|
||||
prelude::*,
|
||||
rng::Rng,
|
||||
@ -66,7 +65,7 @@ async fn main(spawner: Spawner) -> ! {
|
||||
println!("esp-now version {}", esp_now.get_version().unwrap());
|
||||
|
||||
let timer_group0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timer_group0);
|
||||
esp_hal_embassy::init(&clocks, timer_group0);
|
||||
|
||||
let (manager, sender, receiver) = esp_now.split();
|
||||
let manager = mk_static!(EspNowManager<'static>, manager);
|
||||
|
||||
@ -82,6 +82,7 @@ embedded-hal-async = { version = "1.0.0", optional = true }
|
||||
embedded-hal-nb = { version = "1.0.0", optional = true }
|
||||
esp-backtrace = { path = "../esp-backtrace", default-features = false, features = ["exception-handler", "panic-handler", "defmt", "semihosting"] }
|
||||
esp-hal = { path = "../esp-hal", features = ["defmt", "embedded-hal", "embedded-hal-02"], optional = true }
|
||||
esp-hal-embassy = { path = "../esp-hal-embassy", optional = true }
|
||||
portable-atomic = "1.6.0"
|
||||
|
||||
[dev-dependencies]
|
||||
@ -103,31 +104,34 @@ esp32 = [
|
||||
"embedded-test/xtensa-semihosting",
|
||||
"esp-backtrace/esp32",
|
||||
"esp-hal/esp32",
|
||||
"esp-hal-embassy/esp32",
|
||||
]
|
||||
esp32c2 = ["esp-backtrace/esp32c2", "esp-hal/esp32c2"]
|
||||
esp32c3 = ["esp-backtrace/esp32c3", "esp-hal/esp32c3"]
|
||||
esp32c6 = ["esp-backtrace/esp32c6", "esp-hal/esp32c6"]
|
||||
esp32h2 = ["esp-backtrace/esp32h2", "esp-hal/esp32h2"]
|
||||
esp32c2 = ["esp-backtrace/esp32c2", "esp-hal/esp32c2", "esp-hal-embassy/esp32c2"]
|
||||
esp32c3 = ["esp-backtrace/esp32c3", "esp-hal/esp32c3", "esp-hal-embassy/esp32c3"]
|
||||
esp32c6 = ["esp-backtrace/esp32c6", "esp-hal/esp32c6", "esp-hal-embassy/esp32c6"]
|
||||
esp32h2 = ["esp-backtrace/esp32h2", "esp-hal/esp32h2", "esp-hal-embassy/esp32h2"]
|
||||
esp32s2 = [
|
||||
"embedded-test/xtensa-semihosting",
|
||||
"esp-backtrace/esp32s2",
|
||||
"esp-hal/esp32s2",
|
||||
"esp-hal-embassy/esp32s2",
|
||||
]
|
||||
esp32s3 = [
|
||||
"embedded-test/xtensa-semihosting",
|
||||
"esp-backtrace/esp32s3",
|
||||
"esp-hal/esp32s3",
|
||||
"esp-hal-embassy/esp32s3",
|
||||
]
|
||||
# Async & Embassy:
|
||||
async = ["dep:embedded-hal-async", "esp-hal?/async"]
|
||||
embassy = [
|
||||
"embedded-test/embassy",
|
||||
"embedded-test/external-executor",
|
||||
"esp-hal?/embassy",
|
||||
"dep:esp-hal-embassy",
|
||||
]
|
||||
embassy-time-systick-16mhz = ["esp-hal?/embassy-time-systick-16mhz"]
|
||||
embassy-time-systick-80mhz = ["esp-hal?/embassy-time-systick-80mhz"]
|
||||
embassy-time-timg0 = ["esp-hal?/embassy-time-timg0"]
|
||||
embassy-time-systimer-16mhz = ["esp-hal-embassy/time-systimer-16mhz"]
|
||||
embassy-time-systimer-80mhz = ["esp-hal-embassy/time-systimer-80mhz"]
|
||||
embassy-time-timg0 = ["esp-hal-embassy/time-timg0"]
|
||||
|
||||
# https://doc.rust-lang.org/cargo/reference/profiles.html#test
|
||||
# Test and bench profiles inherit from dev and release respectively.
|
||||
|
||||
@ -17,7 +17,6 @@ use esp_backtrace as _;
|
||||
use esp_hal::{
|
||||
clock::ClockControl,
|
||||
delay::Delay,
|
||||
embassy,
|
||||
gpio::{Gpio2, Gpio4, GpioPin, Input, Io, Level, Output, Pull},
|
||||
macros::handler,
|
||||
peripherals::Peripherals,
|
||||
@ -46,7 +45,7 @@ impl<'d> Context<'d> {
|
||||
let delay = Delay::new(&clocks);
|
||||
|
||||
let timg0 = TimerGroup::new_async(peripherals.TIMG0, &clocks);
|
||||
embassy::init(&clocks, timg0);
|
||||
esp_hal_embassy::init(&clocks, timg0);
|
||||
|
||||
Context {
|
||||
io2: Input::new(io.pins.gpio2, Pull::Down),
|
||||
@ -68,7 +67,7 @@ pub fn interrupt_handler() {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[embedded_test::tests(executor = esp_hal::embassy::executor::Executor::new())]
|
||||
#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())]
|
||||
mod tests {
|
||||
use defmt::assert_eq;
|
||||
use embassy_time::{Duration, Timer};
|
||||
|
||||
@ -44,7 +44,7 @@ impl Context {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[embedded_test::tests(executor = esp_hal::embassy::executor::Executor::new())]
|
||||
#[embedded_test::tests(executor = esp_hal_embassy::Executor::new())]
|
||||
mod tests {
|
||||
use defmt::assert_eq;
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ pub enum Package {
|
||||
EspBacktrace,
|
||||
EspBuild,
|
||||
EspHal,
|
||||
EspHalEmbassy,
|
||||
EspHalProcmacros,
|
||||
EspHalSmartled,
|
||||
EspIeee802154,
|
||||
|
||||
@ -467,6 +467,21 @@ fn lint_packages(workspace: &Path, _args: LintPackagesArgs) -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
Package::EspHalEmbassy => {
|
||||
// We need to specify a time driver, so we will check all
|
||||
// options here (as the modules themselves are feature-gated):
|
||||
for feature in ["time-systimer-16mhz", "time-timg0"] {
|
||||
lint_package(
|
||||
&path,
|
||||
&[
|
||||
"-Zbuild-std=core",
|
||||
"--target=riscv32imac-unknown-none-elf",
|
||||
&format!("--features=esp32c6,{feature}"),
|
||||
],
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
Package::EspHalProcmacros | Package::EspRiscvRt => lint_package(
|
||||
&path,
|
||||
&["-Zbuild-std=core", "--target=riscv32imc-unknown-none-elf"],
|
||||
@ -504,7 +519,7 @@ fn lint_packages(workspace: &Path, _args: LintPackagesArgs) -> Result<()> {
|
||||
&[
|
||||
"-Zbuild-std=core",
|
||||
"--target=riscv32imc-unknown-none-elf",
|
||||
"--features=esp32c3,wifi-default,ble,esp-now,async,embassy-net",
|
||||
"--features=esp32c3,wifi-default,ble,esp-now,async,embassy-net,esp-hal-embassy/time-timg0",
|
||||
],
|
||||
)?,
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user