Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract embassy support into esp-hal-embassy package #1595

Merged
merged 8 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ exclude = [
"esp-backtrace",
"esp-build",
"esp-hal",
"esp-hal-embassy",
"esp-hal-procmacros",
"esp-hal-smartled",
"esp-ieee802154",
Expand Down
48 changes: 48 additions & 0 deletions esp-hal-embassy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 changes: 35 additions & 0 deletions esp-hal-embassy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# esp-hal-embassy

[![Crates.io](https://img.shields.io/crates/v/esp-hal-embassy?labelColor=1C2C2E&color=C96329&logo=Rust&style=flat-square)](https://crates.io/crates/esp-hal-embassy)
[![docs.rs](https://img.shields.io/docsrs/esp-hal-embassy?labelColor=1C2C2E&color=C96329&logo=rust&style=flat-square)](https://docs.rs/esp-hal-embassy)
![MSRV](https://img.shields.io/badge/MSRV-1.76-blue?labelColor=1C2C2E&style=flat-square)
![Crates.io](https://img.shields.io/crates/l/esp-hal-embassy?labelColor=1C2C2E&style=flat-square)
[![Matrix](https://img.shields.io/matrix/esp-rs:matrix.org?label=join%20matrix&labelColor=1C2C2E&color=BEC5C9&logo=matrix&style=flat-square)](https://matrix.to/#/#esp-rs:matrix.org)

[Embassy] support for `esp-hal`.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README.md could definitely use some expansion, however I'm not really sure what should be included here and what belongs in documentation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we add some links to the embassy book or to website? They are just 1 click further from the repo, but it might be useful.


[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 changes: 53 additions & 0 deletions esp-hal-embassy/build.rs
Original file line number Diff line number Diff line change
@@ -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(())
}
Original file line number Diff line number Diff line change
@@ -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(),
Expand Down Expand Up @@ -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) {
Expand All @@ -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();
}
}
Expand Down Expand Up @@ -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()
}
}
Original file line number Diff line number Diff line change
@@ -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();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
//! Multicore-aware thread-mode embassy executor.
use core::marker::PhantomData;

use embassy_executor::{raw, Spawner};
use portable_atomic::{AtomicBool, Ordering};
use esp_hal::get_core;
#[cfg(multi_core)]
use procmacros::handler;

use crate::get_core;
use esp_hal::macros::handler;
#[cfg(multi_core)]
use crate::peripherals::SYSTEM;
use esp_hal::peripherals::SYSTEM;
use portable_atomic::{AtomicBool, Ordering};

pub(crate) const THREAD_MODE_CONTEXT: u8 = 16;

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
}

Expand Down Expand Up @@ -179,3 +179,9 @@ impl Executor {
// here
}
}

impl Default for Executor {
fn default() -> Self {
Self::new()
}
}
Loading
Loading