Add embassy-cortex-m crate.

- Move Interrupt and InterruptExecutor from `embassy` to `embassy-cortex-m`.
- Move Unborrow from `embassy` to `embassy-hal-common` (nothing in `embassy` requires it anymore)
- Move PeripheralMutex from `embassy-hal-common` to `embassy-cortex-m`.
This commit is contained in:
Dario Nieuwenhuis 2022-06-11 05:08:57 +02:00
parent db344c2bda
commit 5085100df2
104 changed files with 814 additions and 460 deletions

View File

@ -0,0 +1,47 @@
[package]
name = "embassy-cortex-m"
version = "0.1.0"
authors = ["Dario Nieuwenhuis <dirbaio@dirbaio.net>"]
edition = "2018"
resolver = "2"
[package.metadata.embassy_docs]
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-cortex-m-v$VERSION/embassy-cortex-m/src/"
src_base_git = "https://github.com/embassy-rs/embassy/blob/master/embassy-cortex-m/src/"
features = []
flavors = [
{ name = "thumbv6m-none-eabi", target = "thumbv6m-none-eabi", features = [] },
{ name = "thumbv7m-none-eabi", target = "thumbv7m-none-eabi", features = [] },
{ name = "thumbv7em-none-eabi", target = "thumbv7em-none-eabi", features = [] },
{ name = "thumbv7em-none-eabihf", target = "thumbv7em-none-eabihf", features = [] },
{ name = "thumbv8m.base-none-eabi", target = "thumbv8m.base-none-eabi", features = [] },
{ name = "thumbv8m.main-none-eabi", target = "thumbv8m.main-none-eabi", features = [] },
{ name = "thumbv8m.main-none-eabihf", target = "thumbv8m.main-none-eabihf", features = [] },
]
[features]
default = []
# Define the number of NVIC priority bits.
prio-bits-0 = []
prio-bits-1 = []
prio-bits-2 = []
prio-bits-3 = []
prio-bits-4 = []
prio-bits-5 = []
prio-bits-6 = []
prio-bits-7 = []
prio-bits-8 = []
[dependencies]
defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
embassy = { version = "0.1.0", path = "../embassy"}
embassy-macros = { version = "0.1.0", path = "../embassy-macros"}
embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common"}
atomic-polyfill = "0.1.5"
critical-section = "0.2.5"
cfg-if = "1.0.0"
cortex-m = "0.7.3"

29
embassy-cortex-m/build.rs Normal file
View File

@ -0,0 +1,29 @@
use std::env;
fn main() {
let target = env::var("TARGET").unwrap();
if target.starts_with("thumbv6m-") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv6m");
} else if target.starts_with("thumbv7m-") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv7m");
} else if target.starts_with("thumbv7em-") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv7m");
println!("cargo:rustc-cfg=armv7em"); // (not currently used)
} else if target.starts_with("thumbv8m.base") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv8m");
println!("cargo:rustc-cfg=armv8m_base");
} else if target.starts_with("thumbv8m.main") {
println!("cargo:rustc-cfg=cortex_m");
println!("cargo:rustc-cfg=armv8m");
println!("cargo:rustc-cfg=armv8m_main");
}
if target.ends_with("-eabihf") {
println!("cargo:rustc-cfg=has_fpu");
}
}

View File

@ -0,0 +1,89 @@
use core::marker::PhantomData;
use crate::interrupt::{Interrupt, InterruptExt};
use embassy::executor::{raw, SendSpawner};
pub use embassy::executor::Executor;
fn pend_by_number(n: u16) {
#[derive(Clone, Copy)]
struct N(u16);
unsafe impl cortex_m::interrupt::InterruptNumber for N {
fn number(self) -> u16 {
self.0
}
}
cortex_m::peripheral::NVIC::pend(N(n))
}
/// Interrupt mode executor.
///
/// This executor runs tasks in interrupt mode. The interrupt handler is set up
/// to poll tasks, and when a task is woken the interrupt is pended from software.
///
/// This allows running async tasks at a priority higher than thread mode. One
/// use case is to leave thread mode free for non-async tasks. Another use case is
/// to run multiple executors: one in thread mode for low priority tasks and another in
/// interrupt mode for higher priority tasks. Higher priority tasks will preempt lower
/// priority ones.
///
/// It is even possible to run multiple interrupt mode executors at different priorities,
/// by assigning different priorities to the interrupts. For an example on how to do this,
/// See the 'multiprio' example for 'embassy-nrf'.
///
/// To use it, you have to pick an interrupt that won't be used by the hardware.
/// Some chips reserve some interrupts for this purpose, sometimes named "software interrupts" (SWI).
/// If this is not the case, you may use an interrupt from any unused peripheral.
///
/// It is somewhat more complex to use, it's recommended to use the thread-mode
/// [`Executor`] instead, if it works for your use case.
pub struct InterruptExecutor<I: Interrupt> {
irq: I,
inner: raw::Executor,
not_send: PhantomData<*mut ()>,
}
impl<I: Interrupt> InterruptExecutor<I> {
/// Create a new Executor.
pub fn new(irq: I) -> Self {
let ctx = irq.number() as *mut ();
Self {
irq,
inner: raw::Executor::new(|ctx| pend_by_number(ctx as u16), ctx),
not_send: PhantomData,
}
}
/// Start the executor.
///
/// This initializes the executor, configures and enables the interrupt, and returns.
/// The executor keeps running in the background through the interrupt.
///
/// This returns a [`SendSpawner`] you can use to spawn tasks on it. A [`SendSpawner`]
/// is returned instead of a [`Spawner`] because the executor effectively runs in a
/// different "thread" (the interrupt), so spawning tasks on it is effectively
/// sending them.
///
/// To obtain a [`Spawner`] for this executor, use [`Spawner::for_current_executor`] from
/// a task running in it.
///
/// This function requires `&'static mut self`. This means you have to store the
/// Executor instance in a place where it'll live forever and grants you mutable
/// access. There's a few ways to do this:
///
/// - a [Forever](crate::util::Forever) (safe)
/// - a `static mut` (unsafe)
/// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
pub fn start(&'static mut self) -> SendSpawner {
self.irq.disable();
self.irq.set_handler(|ctx| unsafe {
let executor = &*(ctx as *const raw::Executor);
executor.poll();
});
self.irq.set_handler_context(&self.inner as *const _ as _);
self.irq.enable();
self.inner.spawner().make_send()
}
}

228
embassy-cortex-m/src/fmt.rs Normal file
View File

@ -0,0 +1,228 @@
#![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);
}
}
}
}
#[cfg(feature = "defmt-timestamp-uptime")]
defmt::timestamp! {"{=u64:us}", crate::time::Instant::now().as_micros() }
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct NoneError;
pub trait Try {
type Ok;
type Error;
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
}
}

View File

@ -1,49 +1,198 @@
use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering};
use core::mem;
use core::ptr;
use cortex_m::peripheral::NVIC;
use embassy_hal_common::Unborrow;
macro_rules! prio {
($name:ident, $mask:expr, ($($k:ident = $v:expr,)*)) => {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum $name {
$($k = $v),*
pub use embassy_macros::cortex_m_interrupt_take as take;
/// Implementation detail, do not use outside embassy crates.
#[doc(hidden)]
pub struct Handler {
pub func: AtomicPtr<()>,
pub ctx: AtomicPtr<()>,
}
impl From<u8> for $name {
impl Handler {
pub const fn new() -> Self {
Self {
func: AtomicPtr::new(ptr::null_mut()),
ctx: AtomicPtr::new(ptr::null_mut()),
}
}
}
#[derive(Clone, Copy)]
pub(crate) struct NrWrap(pub(crate) u16);
unsafe impl cortex_m::interrupt::InterruptNumber for NrWrap {
fn number(self) -> u16 {
self.0
}
}
pub unsafe trait Interrupt: Unborrow<Target = Self> {
fn number(&self) -> u16;
unsafe fn steal() -> Self;
/// Implementation detail, do not use outside embassy crates.
#[doc(hidden)]
unsafe fn __handler(&self) -> &'static Handler;
}
pub trait InterruptExt: Interrupt {
fn set_handler(&self, func: unsafe fn(*mut ()));
fn remove_handler(&self);
fn set_handler_context(&self, ctx: *mut ());
fn enable(&self);
fn disable(&self);
#[cfg(not(armv6m))]
fn is_active(&self) -> bool;
fn is_enabled(&self) -> bool;
fn is_pending(&self) -> bool;
fn pend(&self);
fn unpend(&self);
fn get_priority(&self) -> Priority;
fn set_priority(&self, prio: Priority);
}
impl<T: Interrupt + ?Sized> InterruptExt for T {
fn set_handler(&self, func: unsafe fn(*mut ())) {
compiler_fence(Ordering::SeqCst);
let handler = unsafe { self.__handler() };
handler.func.store(func as *mut (), Ordering::Relaxed);
compiler_fence(Ordering::SeqCst);
}
fn remove_handler(&self) {
compiler_fence(Ordering::SeqCst);
let handler = unsafe { self.__handler() };
handler.func.store(ptr::null_mut(), Ordering::Relaxed);
compiler_fence(Ordering::SeqCst);
}
fn set_handler_context(&self, ctx: *mut ()) {
let handler = unsafe { self.__handler() };
handler.ctx.store(ctx, Ordering::Relaxed);
}
#[inline]
fn enable(&self) {
compiler_fence(Ordering::SeqCst);
unsafe {
NVIC::unmask(NrWrap(self.number()));
}
}
#[inline]
fn disable(&self) {
NVIC::mask(NrWrap(self.number()));
compiler_fence(Ordering::SeqCst);
}
#[inline]
#[cfg(not(armv6m))]
fn is_active(&self) -> bool {
NVIC::is_active(NrWrap(self.number()))
}
#[inline]
fn is_enabled(&self) -> bool {
NVIC::is_enabled(NrWrap(self.number()))
}
#[inline]
fn is_pending(&self) -> bool {
NVIC::is_pending(NrWrap(self.number()))
}
#[inline]
fn pend(&self) {
NVIC::pend(NrWrap(self.number()))
}
#[inline]
fn unpend(&self) {
NVIC::unpend(NrWrap(self.number()))
}
#[inline]
fn get_priority(&self) -> Priority {
Priority::from(NVIC::get_priority(NrWrap(self.number())))
}
#[inline]
fn set_priority(&self, prio: Priority) {
unsafe {
let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
nvic.set_priority(NrWrap(self.number()), prio.into())
}
}
}
impl From<u8> for Priority {
fn from(priority: u8) -> Self {
unsafe { mem::transmute(priority & $mask) }
unsafe { mem::transmute(priority & PRIO_MASK) }
}
}
impl From<$name> for u8 {
fn from(p: $name) -> Self {
impl From<Priority> for u8 {
fn from(p: Priority) -> Self {
p as u8
}
}
};
#[cfg(feature = "prio-bits-0")]
const PRIO_MASK: u8 = 0x00;
#[cfg(feature = "prio-bits-1")]
const PRIO_MASK: u8 = 0x80;
#[cfg(feature = "prio-bits-2")]
const PRIO_MASK: u8 = 0xc0;
#[cfg(feature = "prio-bits-3")]
const PRIO_MASK: u8 = 0xe0;
#[cfg(feature = "prio-bits-4")]
const PRIO_MASK: u8 = 0xf0;
#[cfg(feature = "prio-bits-5")]
const PRIO_MASK: u8 = 0xf8;
#[cfg(feature = "prio-bits-6")]
const PRIO_MASK: u8 = 0xfc;
#[cfg(feature = "prio-bits-7")]
const PRIO_MASK: u8 = 0xfe;
#[cfg(feature = "prio-bits-8")]
const PRIO_MASK: u8 = 0xff;
#[cfg(feature = "prio-bits-0")]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
P0 = 0x0,
}
#[rustfmt::skip]
prio!(Priority0, 0x00, (
P0 = 0x0,
));
#[rustfmt::skip]
prio!(Priority1, 0x80, (
#[cfg(feature = "prio-bits-1")]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
P0 = 0x0,
P1 = 0x80,
));
}
#[rustfmt::skip]
prio!(Priority2, 0xc0, (
#[cfg(feature = "prio-bits-2")]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
P0 = 0x0,
P1 = 0x40,
P2 = 0x80,
P3 = 0xc0,
));
}
#[rustfmt::skip]
prio!(Priority3, 0xe0, (
#[cfg(feature = "prio-bits-3")]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
P0 = 0x0,
P1 = 0x20,
P2 = 0x40,
@ -52,10 +201,13 @@ prio!(Priority3, 0xe0, (
P5 = 0xa0,
P6 = 0xc0,
P7 = 0xe0,
));
}
#[rustfmt::skip]
prio!(Priority4, 0xf0, (
#[cfg(feature = "prio-bits-4")]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
P0 = 0x0,
P1 = 0x10,
P2 = 0x20,
@ -72,10 +224,13 @@ prio!(Priority4, 0xf0, (
P13 = 0xd0,
P14 = 0xe0,
P15 = 0xf0,
));
}
#[rustfmt::skip]
prio!(Priority5, 0xf8, (
#[cfg(feature = "prio-bits-5")]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
P0 = 0x0,
P1 = 0x8,
P2 = 0x10,
@ -108,10 +263,13 @@ prio!(Priority5, 0xf8, (
P29 = 0xe8,
P30 = 0xf0,
P31 = 0xf8,
));
}
#[rustfmt::skip]
prio!(Priority6, 0xfc, (
#[cfg(feature = "prio-bits-6")]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
P0 = 0x0,
P1 = 0x4,
P2 = 0x8,
@ -176,10 +334,13 @@ prio!(Priority6, 0xfc, (
P61 = 0xf4,
P62 = 0xf8,
P63 = 0xfc,
));
}
#[rustfmt::skip]
prio!(Priority7, 0xfe, (
#[cfg(feature = "prio-bits-7")]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
P0 = 0x0,
P1 = 0x2,
P2 = 0x4,
@ -308,10 +469,13 @@ prio!(Priority7, 0xfe, (
P125 = 0xfa,
P126 = 0xfc,
P127 = 0xfe,
));
}
#[rustfmt::skip]
prio!(Priority8, 0xff, (
#[cfg(feature = "prio-bits-8")]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(u8)]
pub enum Priority {
P0 = 0x0,
P1 = 0x1,
P2 = 0x2,
@ -568,4 +732,4 @@ prio!(Priority8, 0xff, (
P253 = 0xfd,
P254 = 0xfe,
P255 = 0xff,
));
}

View File

@ -0,0 +1,8 @@
#![no_std]
// This mod MUST go first, so that the others see its macros.
pub(crate) mod fmt;
pub mod executor;
pub mod interrupt;
pub mod peripheral;

View File

@ -1,9 +1,9 @@
use core::marker::PhantomData;
use core::mem::MaybeUninit;
use cortex_m::peripheral::scb::VectActive;
use cortex_m::peripheral::{NVIC, SCB};
use embassy::interrupt::{Interrupt, InterruptExt};
use crate::interrupt::{Interrupt, InterruptExt, Priority};
/// A type which can be used as state with `PeripheralMutex`.
///
@ -116,7 +116,7 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> {
}
/// Gets the priority of the wrapped interrupt.
pub fn priority(&self) -> <S::Interrupt as Interrupt>::Priority {
pub fn priority(&self) -> Priority {
self.irq.get_priority()
}
}

View File

@ -5,11 +5,11 @@
pub(crate) mod fmt;
pub mod drop;
pub mod interrupt;
mod macros;
pub mod peripheral;
pub mod ratio;
pub mod ring_buffer;
mod unborrow;
pub use unborrow::Unborrow;
/// Low power blocking wait loop using WFE/SEV.
pub fn low_power_wait_until(mut condition: impl FnMut() -> bool) {

View File

@ -16,7 +16,7 @@ macro_rules! peripherals {
}
$(#[$cfg])?
unsafe impl embassy::util::Unborrow for $name {
unsafe impl $crate::Unborrow for $name {
type Target = $name;
#[inline]
unsafe fn unborrow(self) -> $name {
@ -80,7 +80,7 @@ macro_rules! unborrow {
#[macro_export]
macro_rules! unsafe_impl_unborrow {
($type:ident) => {
unsafe impl ::embassy::util::Unborrow for $type {
unsafe impl $crate::Unborrow for $type {
type Target = $type;
#[inline]
unsafe fn unborrow(self) -> Self::Target {

View File

@ -2,9 +2,9 @@
use core::future::Future;
use core::mem::MaybeUninit;
use embassy::channel::signal::Signal;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use embassy_stm32::interrupt::InterruptExt;
use embassy_stm32::Unborrow;
use embassy_stm32::{
dma::NoDma,
gpio::{AnyPin, Output},

View File

@ -22,16 +22,20 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
}
#[proc_macro_attribute]
pub fn interrupt(args: TokenStream, item: TokenStream) -> TokenStream {
pub fn cortex_m_interrupt(args: TokenStream, item: TokenStream) -> TokenStream {
let args = syn::parse_macro_input!(args as syn::AttributeArgs);
let f = syn::parse_macro_input!(item as syn::ItemFn);
interrupt::run(args, f).unwrap_or_else(|x| x).into()
cortex_m_interrupt::run(args, f)
.unwrap_or_else(|x| x)
.into()
}
#[proc_macro]
pub fn interrupt_declare(item: TokenStream) -> TokenStream {
pub fn cortex_m_interrupt_declare(item: TokenStream) -> TokenStream {
let name = syn::parse_macro_input!(item as syn::Ident);
interrupt_declare::run(name).unwrap_or_else(|x| x).into()
cortex_m_interrupt_declare::run(name)
.unwrap_or_else(|x| x)
.into()
}
/// # interrupt_take procedural macro
@ -40,7 +44,9 @@ pub fn interrupt_declare(item: TokenStream) -> TokenStream {
/// We are aware that this brings bloat in the form of core::fmt, but the bloat is already included with e.g. array indexing panics.
/// To get rid of this bloat, use the compiler flags `-Zbuild-std=core -Zbuild-std-features=panic_immediate_abort`.
#[proc_macro]
pub fn interrupt_take(item: TokenStream) -> TokenStream {
pub fn cortex_m_interrupt_take(item: TokenStream) -> TokenStream {
let name = syn::parse_macro_input!(item as syn::Ident);
interrupt_take::run(name).unwrap_or_else(|x| x).into()
cortex_m_interrupt_take::run(name)
.unwrap_or_else(|x| x)
.into()
}

View File

@ -9,8 +9,7 @@ pub fn run(name: syn::Ident) -> Result<TokenStream, TokenStream> {
let result = quote! {
#[allow(non_camel_case_types)]
pub struct #name_interrupt(());
unsafe impl ::embassy::interrupt::Interrupt for #name_interrupt {
type Priority = crate::interrupt::Priority;
unsafe impl ::embassy_cortex_m::interrupt::Interrupt for #name_interrupt {
fn number(&self) -> u16 {
use cortex_m::interrupt::InterruptNumber;
let irq = InterruptEnum::#name;
@ -19,14 +18,14 @@ pub fn run(name: syn::Ident) -> Result<TokenStream, TokenStream> {
unsafe fn steal() -> Self {
Self(())
}
unsafe fn __handler(&self) -> &'static ::embassy::interrupt::Handler {
unsafe fn __handler(&self) -> &'static ::embassy_cortex_m::interrupt::Handler {
#[export_name = #name_handler]
static HANDLER: ::embassy::interrupt::Handler = ::embassy::interrupt::Handler::new();
static HANDLER: ::embassy_cortex_m::interrupt::Handler = ::embassy_cortex_m::interrupt::Handler::new();
&HANDLER
}
}
unsafe impl ::embassy::util::Unborrow for #name_interrupt {
unsafe impl ::embassy_hal_common::Unborrow for #name_interrupt {
type Target = #name_interrupt;
unsafe fn unborrow(self) -> #name_interrupt {
self

View File

@ -13,7 +13,7 @@ pub fn run(name: syn::Ident) -> Result<TokenStream, TokenStream> {
pub unsafe extern "C" fn trampoline() {
extern "C" {
#[link_name = #name_handler]
static HANDLER: ::embassy::interrupt::Handler;
static HANDLER: interrupt::Handler;
}
let func = HANDLER.func.load(::embassy::export::atomic::Ordering::Relaxed);

View File

@ -1,5 +1,5 @@
pub mod interrupt;
pub mod interrupt_declare;
pub mod interrupt_take;
pub mod cortex_m_interrupt;
pub mod cortex_m_interrupt_declare;
pub mod cortex_m_interrupt_take;
pub mod main;
pub mod task;

View File

@ -66,6 +66,7 @@ _gpio-p1 = []
[dependencies]
embassy = { version = "0.1.0", path = "../embassy" }
embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-3"]}
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["nrf"]}
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
embassy-usb = {version = "0.1.0", path = "../embassy-usb", optional=true }

View File

@ -13,15 +13,15 @@
//!
//! Please also see [crate::uarte] to understand when [BufferedUarte] should be used.
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use core::cmp::min;
use core::future::Future;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use embassy::waitqueue::WakerRegistration;
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_hal_common::ring_buffer::RingBuffer;
use embassy_hal_common::{low_power_wait_until, unborrow};
use futures::future::poll_fn;

View File

@ -198,7 +198,7 @@ impl_saadc_input!(P0_05, ANALOGINPUT3);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(POWER_CLOCK);
declare!(RADIO);

View File

@ -219,7 +219,7 @@ impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(POWER_CLOCK);
declare!(RADIO);

View File

@ -220,7 +220,7 @@ impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(POWER_CLOCK);
declare!(RADIO);

View File

@ -212,7 +212,7 @@ impl_ppi_channel!(PPI_CH31, 31 => static);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(POWER_CLOCK);
declare!(RADIO);

View File

@ -236,7 +236,7 @@ impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(POWER_CLOCK);
declare!(RADIO);

View File

@ -279,7 +279,7 @@ impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(POWER_CLOCK);
declare!(RADIO);

View File

@ -284,7 +284,7 @@ impl_saadc_input!(P0_31, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(POWER_CLOCK);
declare!(RADIO);

View File

@ -469,7 +469,7 @@ impl_saadc_input!(P0_20, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(FPU);
declare!(CACHE);

View File

@ -329,7 +329,7 @@ impl_ppi_channel!(PPI_CH31, 31 => configurable);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(CLOCK_POWER);
declare!(RADIO);

View File

@ -347,7 +347,7 @@ impl_saadc_input!(P0_20, ANALOGINPUT7);
pub mod irqs {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::interrupt_declare as declare;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(SPU);
declare!(CLOCK_POWER);

View File

@ -4,8 +4,8 @@ use core::convert::Infallible;
use core::hint::unreachable_unchecked;
use core::marker::PhantomData;
use crate::Unborrow;
use cfg_if::cfg_if;
use embassy::util::Unborrow;
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
use crate::pac;

View File

@ -1,8 +1,8 @@
use crate::interrupt::{Interrupt, InterruptExt};
use core::convert::Infallible;
use core::future::Future;
use core::marker::PhantomData;
use core::task::{Context, Poll};
use embassy::interrupt::{Interrupt, InterruptExt};
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unsafe_impl_unborrow;
use futures::future::poll_fn;

View File

@ -114,23 +114,23 @@ mod chip;
pub use chip::EASY_DMA_SIZE;
pub mod interrupt {
pub use crate::chip::irqs::*;
pub use cortex_m::interrupt::{CriticalSection, Mutex};
pub use embassy_cortex_m::interrupt::*;
}
// Reexports
#[cfg(feature = "unstable-pac")]
pub use chip::pac;
#[cfg(not(feature = "unstable-pac"))]
pub(crate) use chip::pac;
pub use embassy::util::Unborrow;
pub use embassy_hal_common::unborrow;
pub use chip::{peripherals, Peripherals};
pub mod interrupt {
pub use crate::chip::irqs::*;
pub use cortex_m::interrupt::{CriticalSection, Mutex};
pub use embassy::interrupt::{declare, take, Interrupt};
pub use embassy_hal_common::interrupt::Priority3 as Priority;
}
pub use embassy_macros::interrupt;
pub use embassy_cortex_m::executor;
pub use embassy_hal_common::{unborrow, Unborrow};
pub use embassy_macros::cortex_m_interrupt as interrupt;
pub mod config {
pub enum HfclkSource {

View File

@ -3,10 +3,10 @@
use crate::pac;
use crate::peripherals::NVMC;
use crate::Unborrow;
use core::marker::PhantomData;
use core::ptr;
use core::slice;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use embedded_storage::nor_flash::{
ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,

View File

@ -1,6 +1,6 @@
use core::marker::PhantomData;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy_hal_common::unborrow;
use crate::pac;

View File

@ -16,9 +16,9 @@
//!
use crate::peripherals;
use crate::Unborrow;
use core::marker::PhantomData;
use core::ptr::NonNull;
use embassy::util::Unborrow;
use embassy_hal_common::unsafe_impl_unborrow;
#[cfg(feature = "_dppi")]

View File

@ -1,6 +1,6 @@
use core::marker::PhantomData;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy_hal_common::unborrow;
use super::{Channel, ConfigurableChannel, Event, Ppi, StaticChannel, Task};

View File

@ -1,8 +1,8 @@
#![macro_use]
use crate::Unborrow;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use crate::gpio::sealed::Pin as _;

View File

@ -6,10 +6,10 @@ use crate::interrupt;
use crate::pac;
use crate::peripherals::QDEC;
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use core::marker::PhantomData;
use core::task::Poll;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow;
use futures::future::poll_fn;

View File

@ -1,10 +1,10 @@
#![macro_use]
use crate::interrupt::{Interrupt, InterruptExt};
use crate::Unborrow;
use core::marker::PhantomData;
use core::ptr;
use core::task::Poll;
use embassy::interrupt::{Interrupt, InterruptExt};
use embassy::util::Unborrow;
use embassy_hal_common::drop::DropBomb;
use embassy_hal_common::unborrow;
use futures::future::poll_fn;

View File

@ -4,8 +4,8 @@ use core::sync::atomic::AtomicPtr;
use core::sync::atomic::Ordering;
use core::task::Poll;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::unborrow;

View File

@ -1,10 +1,10 @@
#![macro_use]
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow;
use futures::future::poll_fn;

View File

@ -1,10 +1,10 @@
#![macro_use]
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use futures::future::poll_fn;

View File

@ -4,10 +4,10 @@ use crate::interrupt;
use crate::pac;
use crate::peripherals::TEMP;
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use core::marker::PhantomData;
use core::task::Poll;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::{drop::OnDrop, unborrow};
use fixed::types::I30F2;

View File

@ -1,10 +1,10 @@
use crate::interrupt::{Interrupt, InterruptExt};
use core::cell::Cell;
use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering};
use core::{mem, ptr};
use critical_section::CriticalSection;
use embassy::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy::blocking_mutex::CriticalSectionMutex as Mutex;
use embassy::interrupt::{Interrupt, InterruptExt};
use embassy::time::driver::{AlarmHandle, Driver};
use crate::interrupt;

View File

@ -3,9 +3,9 @@
use core::marker::PhantomData;
use core::task::Poll;
use embassy::interrupt::Interrupt;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use crate::interrupt::Interrupt;
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::unborrow;

View File

@ -6,14 +6,14 @@
//!
//! - nRF52832: Section 33
//! - nRF52840: Section 6.31
use crate::interrupt::{Interrupt, InterruptExt};
use crate::Unborrow;
use core::future::Future;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering::SeqCst};
use core::task::Poll;
use embassy::interrupt::{Interrupt, InterruptExt};
#[cfg(feature = "time")]
use embassy::time::{Duration, Instant};
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow;
use futures::future::poll_fn;

View File

@ -13,11 +13,11 @@
//! memory may be used given that buffers are passed in directly to its read and write
//! methods.
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::unborrow;
use futures::future::poll_fn;

View File

@ -1,12 +1,12 @@
#![macro_use]
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use core::marker::PhantomData;
use core::mem::MaybeUninit;
use core::sync::atomic::{compiler_fence, AtomicU32, Ordering};
use core::task::Poll;
use cortex_m::peripheral::NVIC;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow;
use embassy_usb::driver::{self, EndpointError, Event, Unsupported};

View File

@ -29,6 +29,7 @@ unstable-traits = ["embedded-hal-1"]
[dependencies]
embassy = { version = "0.1.0", path = "../embassy", features = [ "time-tick-1mhz", "nightly"] }
embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-3"]}
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["rp"]}
atomic-polyfill = "0.1.5"

View File

@ -6,7 +6,7 @@ use crate::pac::common::{Reg, RW};
use crate::pac::SIO;
use crate::peripherals;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
/// Represents a digital input or output level.

View File

@ -4,13 +4,10 @@
//! nrf_softdevice::interrupt. Intended for switching between the two at compile-time.
// Re-exports
pub use embassy::interrupt::{declare, take, Interrupt};
pub use embassy_hal_common::interrupt::Priority3 as Priority;
pub use embassy_cortex_m::interrupt::*;
mod irqs {
use super::*;
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::cortex_m_interrupt_declare as declare;
declare!(TIMER_IRQ_0);
declare!(TIMER_IRQ_1);
declare!(TIMER_IRQ_2);
@ -37,6 +34,3 @@ mod irqs {
declare!(I2C0_IRQ);
declare!(I2C1_IRQ);
declare!(RTC_IRQ);
}
pub use irqs::*;

View File

@ -2,22 +2,12 @@
#![feature(generic_associated_types)]
#![feature(type_alias_impl_trait)]
#[cfg(feature = "unstable-pac")]
pub use rp2040_pac2 as pac;
#[cfg(not(feature = "unstable-pac"))]
pub(crate) use rp2040_pac2 as pac;
pub use embassy::util::Unborrow;
pub use embassy_hal_common::unborrow;
// This mod MUST go first, so that the others see its macros.
pub(crate) mod fmt;
pub mod interrupt;
pub use embassy_macros::interrupt;
pub mod dma;
pub mod gpio;
pub mod interrupt;
pub mod spi;
pub mod timer;
pub mod uart;
@ -25,6 +15,17 @@ pub mod uart;
mod clocks;
mod reset;
// Reexports
#[cfg(feature = "unstable-pac")]
pub use rp2040_pac2 as pac;
#[cfg(not(feature = "unstable-pac"))]
pub(crate) use rp2040_pac2 as pac;
pub use embassy_cortex_m::executor;
pub use embassy_hal_common::{unborrow, Unborrow};
pub use embassy_macros::cortex_m_interrupt as interrupt;
embassy_hal_common::peripherals! {
PIN_0,
PIN_1,

View File

@ -1,6 +1,6 @@
use core::marker::PhantomData;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy_hal_common::unborrow;
use crate::gpio::sealed::Pin as _;

View File

@ -1,9 +1,9 @@
use crate::interrupt::{Interrupt, InterruptExt};
use atomic_polyfill::{AtomicU8, Ordering};
use core::cell::Cell;
use critical_section::CriticalSection;
use embassy::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy::blocking_mutex::Mutex;
use embassy::interrupt::{Interrupt, InterruptExt};
use embassy::time::driver::{AlarmHandle, Driver};
use crate::{interrupt, pac};

View File

@ -1,6 +1,6 @@
use core::marker::PhantomData;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy_hal_common::unborrow;
use gpio::Pin;

View File

@ -34,6 +34,7 @@ flavors = [
[dependencies]
embassy = { version = "0.1.0", path = "../embassy" }
embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-4"]}
embassy-macros = { version = "0.1.0", path = "../embassy-macros", features = ["stm32"] }
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
embassy-net = { version = "0.1.0", path = "../embassy-net", optional = true }

View File

@ -96,8 +96,9 @@ fn main() {
g.extend(quote! {
pub mod interrupt {
use crate::pac::Interrupt as InterruptEnum;
use embassy_macros::cortex_m_interrupt_declare as declare;
#(
embassy::interrupt::declare!(#irqs);
declare!(#irqs);
)*
}
});

View File

@ -1,8 +1,8 @@
use crate::adc::{AdcPin, Instance};
use crate::rcc::get_freqs;
use crate::time::Hertz;
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use embedded_hal_02::blocking::delay::DelayUs;

View File

@ -1,7 +1,7 @@
use crate::adc::{AdcPin, Instance};
use crate::time::Hertz;
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use embedded_hal_02::blocking::delay::DelayUs;

View File

@ -1,6 +1,6 @@
use crate::adc::{AdcPin, Instance};
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use embedded_hal_02::blocking::delay::DelayUs;

View File

@ -1,9 +1,9 @@
use core::marker::PhantomData;
use crate::time::{Hertz, U32Ext};
use crate::Unborrow;
use atomic_polyfill::AtomicU8;
use atomic_polyfill::Ordering;
use embassy::util::Unborrow;
use embedded_hal_02::blocking::delay::DelayUs;
use pac::adc::vals::{Adcaldif, Boost, Difsel, Exten, Pcsel};
use pac::adccommon::vals::Presc;

View File

@ -1,7 +1,7 @@
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy_hal_common::unborrow;
use crate::gpio::sealed::AFType;

View File

@ -3,7 +3,7 @@ use core::marker::PhantomData;
use crate::pac::CRC as PAC_CRC;
use crate::peripherals::CRC;
use crate::rcc::sealed::RccPeripheral;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy_hal_common::unborrow;
pub struct Crc<'d> {

View File

@ -4,7 +4,7 @@ use crate::pac::crc::vals;
use crate::pac::CRC as PAC_CRC;
use crate::peripherals::CRC;
use crate::rcc::sealed::RccPeripheral;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy_hal_common::unborrow;
pub struct Crc<'d> {

View File

@ -1,7 +1,7 @@
use crate::dac::{DacPin, Instance};
use crate::pac::dac;
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]

View File

@ -1,8 +1,8 @@
use core::marker::PhantomData;
use core::task::Poll;
use embassy::interrupt::{Interrupt, InterruptExt};
use embassy::util::Unborrow;
use crate::interrupt::{Interrupt, InterruptExt};
use crate::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow;
use futures::future::poll_fn;

View File

@ -3,7 +3,7 @@
use core::sync::atomic::{fence, Ordering};
use core::task::Waker;
use embassy::interrupt::{Interrupt, InterruptExt};
use crate::interrupt::{Interrupt, InterruptExt};
use embassy::waitqueue::AtomicWaker;
use crate::_generated::BDMA_CHANNEL_COUNT;

View File

@ -1,7 +1,7 @@
use core::sync::atomic::{fence, Ordering};
use core::task::Waker;
use embassy::interrupt::{Interrupt, InterruptExt};
use crate::interrupt::{Interrupt, InterruptExt};
use embassy::waitqueue::AtomicWaker;
use crate::_generated::DMA_CHANNEL_COUNT;

View File

@ -1,7 +1,7 @@
use core::sync::atomic::{fence, Ordering};
use core::task::Waker;
use embassy::interrupt::{Interrupt, InterruptExt};
use crate::interrupt::{Interrupt, InterruptExt};
use embassy::waitqueue::AtomicWaker;
use crate::_generated::GPDMA_CHANNEL_COUNT;

View File

@ -10,13 +10,13 @@ mod gpdma;
#[cfg(dmamux)]
pub use dmamux::*;
use crate::Unborrow;
use core::future::Future;
use core::marker::PhantomData;
use core::mem;
use core::pin::Pin;
use core::task::Waker;
use core::task::{Context, Poll};
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
#[cfg(feature = "unstable-pac")]

View File

@ -4,9 +4,9 @@ use core::marker::PhantomData;
use core::sync::atomic::{fence, Ordering};
use core::task::Waker;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_hal_common::unborrow;
use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};

View File

@ -2,9 +2,9 @@ use core::marker::PhantomData;
use core::sync::atomic::{fence, Ordering};
use core::task::Waker;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_hal_common::unborrow;
use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};

View File

@ -1,8 +1,8 @@
use crate::Unborrow;
use core::future::Future;
use core::marker::PhantomData;
use core::pin::Pin;
use core::task::{Context, Poll};
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unsafe_impl_unborrow;
@ -366,8 +366,8 @@ macro_rules! enable_irq {
/// safety: must be called only once
pub(crate) unsafe fn init() {
use embassy::interrupt::Interrupt;
use embassy::interrupt::InterruptExt;
use crate::interrupt::Interrupt;
use crate::interrupt::InterruptExt;
foreach_exti_irq!(enable_irq);

View File

@ -1,6 +1,6 @@
use crate::peripherals::FLASH;
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use embedded_storage::nor_flash::{

View File

@ -1,5 +1,5 @@
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use crate::gpio::sealed::AFType;

View File

@ -1,7 +1,7 @@
#![macro_use]
use crate::Unborrow;
use core::convert::Infallible;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
use crate::pac;

View File

@ -1,6 +1,6 @@
#![macro_use]
use embassy::interrupt::Interrupt;
use crate::interrupt::Interrupt;
#[cfg_attr(i2c_v1, path = "v1.rs")]
#[cfg_attr(i2c_v2, path = "v2.rs")]

View File

@ -1,5 +1,5 @@
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use crate::gpio::sealed::AFType;

View File

@ -2,9 +2,9 @@ use core::cmp;
use core::marker::PhantomData;
use core::task::Poll;
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use atomic_polyfill::{AtomicUsize, Ordering};
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::unborrow;

View File

@ -1,6 +1,5 @@
pub use bare_metal::Mutex;
pub use critical_section::CriticalSection;
pub use embassy::interrupt::{take, Interrupt};
pub use embassy_hal_common::interrupt::Priority4 as Priority;
pub use embassy_cortex_m::interrupt::*;
pub use crate::_generated::interrupt::*;

View File

@ -4,14 +4,6 @@
feature(generic_associated_types, type_alias_impl_trait)
)]
#[cfg(feature = "unstable-pac")]
pub use stm32_metapac as pac;
#[cfg(not(feature = "unstable-pac"))]
pub(crate) use stm32_metapac as pac;
pub use embassy::util::Unborrow;
pub use embassy_hal_common::unborrow;
// This must go FIRST so that all the other modules see its macros.
pub mod fmt;
include!(concat!(env!("OUT_DIR"), "/_macros.rs"));
@ -79,8 +71,17 @@ pub(crate) mod _generated {
include!(concat!(env!("OUT_DIR"), "/_generated.rs"));
}
// Reexports
pub use _generated::{peripherals, Peripherals};
pub use embassy_macros::interrupt;
pub use embassy_cortex_m::executor;
pub use embassy_hal_common::{unborrow, Unborrow};
pub use embassy_macros::cortex_m_interrupt as interrupt;
#[cfg(feature = "unstable-pac")]
pub use stm32_metapac as pac;
#[cfg(not(feature = "unstable-pac"))]
pub(crate) use stm32_metapac as pac;
#[non_exhaustive]
pub struct Config {

View File

@ -1,5 +1,5 @@
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use super::*;

View File

@ -1,6 +1,6 @@
use core::marker::PhantomData;
use embassy::util::Unborrow;
use crate::Unborrow;
use embassy_hal_common::unborrow;
use stm32_metapac::rcc::vals::{Mco1, Mco2};

View File

@ -1,3 +1,5 @@
use stm32_metapac::PWR;
use crate::pac::rcc::vals::{Hpre, Msirange, Pllsrc, Ppre, Sw};
use crate::pac::{FLASH, RCC};
use crate::rcc::{set_freqs, Clocks};
@ -295,6 +297,8 @@ impl Default for Config {
}
pub(crate) unsafe fn init(config: Config) {
PWR.cr1()
.modify(|w| w.set_vos(stm32_metapac::pwr::vals::Vos::RANGE0));
let (sys_clk, sw) = match config.mux {
ClockSrc::MSI(range) => {
// Enable MSI

View File

@ -1,8 +1,8 @@
#![macro_use]
use crate::Unborrow;
use core::marker::PhantomData;
use core::task::Poll;
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow;
use futures::future::poll_fn;

View File

@ -4,8 +4,8 @@ use core::default::Default;
use core::marker::PhantomData;
use core::task::Poll;
use embassy::interrupt::InterruptExt;
use embassy::util::Unborrow;
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::unborrow;

View File

@ -1,8 +1,8 @@
#![macro_use]
use crate::Unborrow;
use core::marker::PhantomData;
use core::ptr;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use futures::future::join;

View File

@ -77,6 +77,7 @@ pub use value_error::ValueError;
use embassy_hal_common::ratio::Ratio;
use crate::Unborrow;
use crate::{
dma::NoDma,
pac,
@ -85,7 +86,6 @@ use crate::{
spi::{BitOrder, Config as SpiConfig, MisoPin, MosiPin, SckPin, Spi, MODE_0},
time::Hertz,
};
use embassy::util::Unborrow;
/// Passthrough for SPI errors (for now)
pub type Error = crate::spi::Error;

View File

@ -1,3 +1,4 @@
use crate::interrupt::InterruptExt;
use atomic_polyfill::{AtomicU32, AtomicU8};
use core::cell::Cell;
use core::convert::TryInto;
@ -5,7 +6,6 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::{mem, ptr};
use embassy::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy::blocking_mutex::Mutex;
use embassy::interrupt::InterruptExt;
use embassy::time::driver::{AlarmHandle, Driver};
use embassy::time::TICKS_PER_SECOND;
use stm32_metapac::timer::regs;

View File

@ -1,4 +1,4 @@
use embassy::interrupt::Interrupt;
use crate::interrupt::Interrupt;
use crate::rcc::{sealed::RccPeripheral as __RccPeri, RccPeripheral};
use crate::time::Hertz;

View File

@ -2,7 +2,7 @@ use atomic_polyfill::{compiler_fence, Ordering};
use core::future::Future;
use core::task::Poll;
use embassy::waitqueue::WakerRegistration;
use embassy_hal_common::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
use embassy_hal_common::ring_buffer::RingBuffer;
use futures::future::poll_fn;

View File

@ -1,8 +1,8 @@
#![macro_use]
use crate::interrupt::Interrupt;
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::interrupt::Interrupt;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use crate::dma::NoDma;

View File

@ -1,4 +1,4 @@
use embassy::interrupt::Interrupt;
use crate::interrupt::Interrupt;
use crate::rcc::RccPeripheral;

View File

@ -1,12 +1,12 @@
#![macro_use]
use crate::interrupt::InterruptExt;
use crate::Unborrow;
use atomic_polyfill::{AtomicBool, AtomicU8};
use core::marker::PhantomData;
use core::sync::atomic::Ordering;
use core::task::Poll;
use embassy::interrupt::InterruptExt;
use embassy::time::{block_for, Duration};
use embassy::util::Unborrow;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::unborrow;
use embassy_usb::driver::{self, EndpointAllocError, EndpointError, Event, Unsupported};

View File

@ -1,5 +1,5 @@
use crate::Unborrow;
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use crate::gpio::sealed::AFType;

View File

@ -1,8 +1,7 @@
use core::marker::PhantomData;
use core::ptr;
use super::{raw, SendSpawner, Spawner};
use crate::interrupt::{Interrupt, InterruptExt};
use super::{raw, Spawner};
/// Thread mode executor, using WFE/SEV.
///
@ -55,86 +54,3 @@ impl Executor {
}
}
}
fn pend_by_number(n: u16) {
#[derive(Clone, Copy)]
struct N(u16);
unsafe impl cortex_m::interrupt::InterruptNumber for N {
fn number(self) -> u16 {
self.0
}
}
cortex_m::peripheral::NVIC::pend(N(n))
}
/// Interrupt mode executor.
///
/// This executor runs tasks in interrupt mode. The interrupt handler is set up
/// to poll tasks, and when a task is woken the interrupt is pended from software.
///
/// This allows running async tasks at a priority higher than thread mode. One
/// use case is to leave thread mode free for non-async tasks. Another use case is
/// to run multiple executors: one in thread mode for low priority tasks and another in
/// interrupt mode for higher priority tasks. Higher priority tasks will preempt lower
/// priority ones.
///
/// It is even possible to run multiple interrupt mode executors at different priorities,
/// by assigning different priorities to the interrupts. For an example on how to do this,
/// See the 'multiprio' example for 'embassy-nrf'.
///
/// To use it, you have to pick an interrupt that won't be used by the hardware.
/// Some chips reserve some interrupts for this purpose, sometimes named "software interrupts" (SWI).
/// If this is not the case, you may use an interrupt from any unused peripheral.
///
/// It is somewhat more complex to use, it's recommended to use the thread-mode
/// [`Executor`] instead, if it works for your use case.
pub struct InterruptExecutor<I: Interrupt> {
irq: I,
inner: raw::Executor,
not_send: PhantomData<*mut ()>,
}
impl<I: Interrupt> InterruptExecutor<I> {
/// Create a new Executor.
pub fn new(irq: I) -> Self {
let ctx = irq.number() as *mut ();
Self {
irq,
inner: raw::Executor::new(|ctx| pend_by_number(ctx as u16), ctx),
not_send: PhantomData,
}
}
/// Start the executor.
///
/// This initializes the executor, configures and enables the interrupt, and returns.
/// The executor keeps running in the background through the interrupt.
///
/// This returns a [`SendSpawner`] you can use to spawn tasks on it. A [`SendSpawner`]
/// is returned instead of a [`Spawner`] because the executor effectively runs in a
/// different "thread" (the interrupt), so spawning tasks on it is effectively
/// sending them.
///
/// To obtain a [`Spawner`] for this executor, use [`Spawner::for_current_executor`] from
/// a task running in it.
///
/// This function requires `&'static mut self`. This means you have to store the
/// Executor instance in a place where it'll live forever and grants you mutable
/// access. There's a few ways to do this:
///
/// - a [Forever](crate::util::Forever) (safe)
/// - a `static mut` (unsafe)
/// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
pub fn start(&'static mut self) -> SendSpawner {
self.irq.disable();
self.irq.set_handler(|ctx| unsafe {
let executor = &*(ctx as *const raw::Executor);
executor.poll();
});
self.irq.set_handler_context(&self.inner as *const _ as _);
self.irq.enable();
self.inner.spawner().make_send()
}
}

View File

@ -1,131 +0,0 @@
use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering};
use core::mem;
use core::ptr;
use cortex_m::peripheral::NVIC;
pub use embassy_macros::interrupt_declare as declare;
pub use embassy_macros::interrupt_take as take;
/// Implementation detail, do not use outside embassy crates.
#[doc(hidden)]
pub struct Handler {
pub func: AtomicPtr<()>,
pub ctx: AtomicPtr<()>,
}
impl Handler {
pub const fn new() -> Self {
Self {
func: AtomicPtr::new(ptr::null_mut()),
ctx: AtomicPtr::new(ptr::null_mut()),
}
}
}
#[derive(Clone, Copy)]
pub(crate) struct NrWrap(pub(crate) u16);
unsafe impl cortex_m::interrupt::InterruptNumber for NrWrap {
fn number(self) -> u16 {
self.0
}
}
pub unsafe trait Interrupt: crate::util::Unborrow<Target = Self> {
type Priority: From<u8> + Into<u8> + Copy;
fn number(&self) -> u16;
unsafe fn steal() -> Self;
/// Implementation detail, do not use outside embassy crates.
#[doc(hidden)]
unsafe fn __handler(&self) -> &'static Handler;
}
pub trait InterruptExt: Interrupt {
fn set_handler(&self, func: unsafe fn(*mut ()));
fn remove_handler(&self);
fn set_handler_context(&self, ctx: *mut ());
fn enable(&self);
fn disable(&self);
#[cfg(not(armv6m))]
fn is_active(&self) -> bool;
fn is_enabled(&self) -> bool;
fn is_pending(&self) -> bool;
fn pend(&self);
fn unpend(&self);
fn get_priority(&self) -> Self::Priority;
fn set_priority(&self, prio: Self::Priority);
}
impl<T: Interrupt + ?Sized> InterruptExt for T {
fn set_handler(&self, func: unsafe fn(*mut ())) {
compiler_fence(Ordering::SeqCst);
let handler = unsafe { self.__handler() };
handler.func.store(func as *mut (), Ordering::Relaxed);
compiler_fence(Ordering::SeqCst);
}
fn remove_handler(&self) {
compiler_fence(Ordering::SeqCst);
let handler = unsafe { self.__handler() };
handler.func.store(ptr::null_mut(), Ordering::Relaxed);
compiler_fence(Ordering::SeqCst);
}
fn set_handler_context(&self, ctx: *mut ()) {
let handler = unsafe { self.__handler() };
handler.ctx.store(ctx, Ordering::Relaxed);
}
#[inline]
fn enable(&self) {
compiler_fence(Ordering::SeqCst);
unsafe {
NVIC::unmask(NrWrap(self.number()));
}
}
#[inline]
fn disable(&self) {
NVIC::mask(NrWrap(self.number()));
compiler_fence(Ordering::SeqCst);
}
#[inline]
#[cfg(not(armv6m))]
fn is_active(&self) -> bool {
NVIC::is_active(NrWrap(self.number()))
}
#[inline]
fn is_enabled(&self) -> bool {
NVIC::is_enabled(NrWrap(self.number()))
}
#[inline]
fn is_pending(&self) -> bool {
NVIC::is_pending(NrWrap(self.number()))
}
#[inline]
fn pend(&self) {
NVIC::pend(NrWrap(self.number()))
}
#[inline]
fn unpend(&self) {
NVIC::unpend(NrWrap(self.number()))
}
#[inline]
fn get_priority(&self) -> Self::Priority {
Self::Priority::from(NVIC::get_priority(NrWrap(self.number())))
}
#[inline]
fn set_priority(&self, prio: Self::Priority) {
unsafe {
let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
nvic.set_priority(NrWrap(self.number()), prio.into())
}
}
}

View File

@ -11,8 +11,6 @@ pub(crate) mod fmt;
pub mod blocking_mutex;
pub mod channel;
pub mod executor;
#[cfg(cortex_m)]
pub mod interrupt;
pub mod mutex;
#[cfg(feature = "time")]
pub mod time;

View File

@ -3,11 +3,9 @@
mod forever;
mod select;
mod steal;
mod unborrow;
mod yield_now;
pub use forever::*;
pub use select::*;
pub use steal::*;
pub use unborrow::*;
pub use yield_now::*;

View File

@ -59,11 +59,11 @@
use cortex_m_rt::entry;
use defmt::{info, unwrap};
use embassy::executor::{Executor, InterruptExecutor};
use embassy::interrupt::InterruptExt;
use embassy::time::{Duration, Instant, Timer};
use embassy::util::Forever;
use embassy_nrf::executor::{Executor, InterruptExecutor};
use embassy_nrf::interrupt;
use embassy_nrf::interrupt::InterruptExt;
use defmt_rtt as _; // global logger
use panic_probe as _;

View File

@ -8,11 +8,11 @@ use core::sync::atomic::{AtomicBool, Ordering};
use defmt::*;
use embassy::channel::Signal;
use embassy::executor::Spawner;
use embassy::interrupt::InterruptExt;
use embassy::time::Duration;
use embassy::util::{select, select3, Either, Either3};
use embassy_nrf::gpio::{Input, Pin, Pull};
use embassy_nrf::interrupt;
use embassy_nrf::interrupt::InterruptExt;
use embassy_nrf::pac;
use embassy_nrf::usb::Driver;
use embassy_nrf::Peripherals;

Some files were not shown because too many files have changed in this diff Show More