Merge #806
806: Add embassy-cortex-m crate. r=Dirbaio a=Dirbaio - 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`. Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
commit
fff0a03fe0
47
embassy-cortex-m/Cargo.toml
Normal file
47
embassy-cortex-m/Cargo.toml
Normal 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
29
embassy-cortex-m/build.rs
Normal 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");
|
||||
}
|
||||
}
|
89
embassy-cortex-m/src/executor.rs
Normal file
89
embassy-cortex-m/src/executor.rs
Normal 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
228
embassy-cortex-m/src/fmt.rs
Normal 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
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
impl From<u8> for $name {
|
||||
fn from(priority: u8) -> Self {
|
||||
unsafe { mem::transmute(priority & $mask) }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$name> for u8 {
|
||||
fn from(p: $name) -> Self {
|
||||
p as u8
|
||||
}
|
||||
}
|
||||
};
|
||||
/// Implementation detail, do not use outside embassy crates.
|
||||
#[doc(hidden)]
|
||||
pub struct Handler {
|
||||
pub func: AtomicPtr<()>,
|
||||
pub ctx: AtomicPtr<()>,
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
prio!(Priority0, 0x00, (
|
||||
P0 = 0x0,
|
||||
));
|
||||
impl Handler {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
func: AtomicPtr::new(ptr::null_mut()),
|
||||
ctx: AtomicPtr::new(ptr::null_mut()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
prio!(Priority1, 0x80, (
|
||||
#[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 & PRIO_MASK) }
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
#[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,
|
||||
));
|
||||
}
|
8
embassy-cortex-m/src/lib.rs
Normal file
8
embassy-cortex-m/src/lib.rs
Normal 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;
|
@ -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()
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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},
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
@ -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);
|
@ -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;
|
||||
|
@ -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 }
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy::util::Unborrow;
|
||||
use crate::Unborrow;
|
||||
use embassy_hal_common::unborrow;
|
||||
|
||||
use crate::pac;
|
||||
|
@ -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")]
|
||||
|
@ -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};
|
||||
|
@ -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 _;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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};
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
|
@ -4,39 +4,33 @@
|
||||
//! 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;
|
||||
|
||||
declare!(TIMER_IRQ_0);
|
||||
declare!(TIMER_IRQ_1);
|
||||
declare!(TIMER_IRQ_2);
|
||||
declare!(TIMER_IRQ_3);
|
||||
declare!(PWM_IRQ_WRAP);
|
||||
declare!(USBCTRL_IRQ);
|
||||
declare!(XIP_IRQ);
|
||||
declare!(PIO0_IRQ_0);
|
||||
declare!(PIO0_IRQ_1);
|
||||
declare!(PIO1_IRQ_0);
|
||||
declare!(PIO1_IRQ_1);
|
||||
declare!(DMA_IRQ_0);
|
||||
declare!(DMA_IRQ_1);
|
||||
declare!(IO_IRQ_BANK0);
|
||||
declare!(IO_IRQ_QSPI);
|
||||
declare!(SIO_IRQ_PROC0);
|
||||
declare!(SIO_IRQ_PROC1);
|
||||
declare!(CLOCKS_IRQ);
|
||||
declare!(SPI0_IRQ);
|
||||
declare!(SPI1_IRQ);
|
||||
declare!(UART0_IRQ);
|
||||
declare!(UART1_IRQ);
|
||||
declare!(ADC_IRQ_FIFO);
|
||||
declare!(I2C0_IRQ);
|
||||
declare!(I2C1_IRQ);
|
||||
declare!(RTC_IRQ);
|
||||
}
|
||||
|
||||
pub use irqs::*;
|
||||
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);
|
||||
declare!(TIMER_IRQ_3);
|
||||
declare!(PWM_IRQ_WRAP);
|
||||
declare!(USBCTRL_IRQ);
|
||||
declare!(XIP_IRQ);
|
||||
declare!(PIO0_IRQ_0);
|
||||
declare!(PIO0_IRQ_1);
|
||||
declare!(PIO1_IRQ_0);
|
||||
declare!(PIO1_IRQ_1);
|
||||
declare!(DMA_IRQ_0);
|
||||
declare!(DMA_IRQ_1);
|
||||
declare!(IO_IRQ_BANK0);
|
||||
declare!(IO_IRQ_QSPI);
|
||||
declare!(SIO_IRQ_PROC0);
|
||||
declare!(SIO_IRQ_PROC1);
|
||||
declare!(CLOCKS_IRQ);
|
||||
declare!(SPI0_IRQ);
|
||||
declare!(SPI1_IRQ);
|
||||
declare!(UART0_IRQ);
|
||||
declare!(UART1_IRQ);
|
||||
declare!(ADC_IRQ_FIFO);
|
||||
declare!(I2C0_IRQ);
|
||||
declare!(I2C1_IRQ);
|
||||
declare!(RTC_IRQ);
|
||||
|
@ -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,
|
||||
|
@ -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 _;
|
||||
|
@ -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};
|
||||
|
@ -1,6 +1,6 @@
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use embassy::util::Unborrow;
|
||||
use crate::Unborrow;
|
||||
use embassy_hal_common::unborrow;
|
||||
use gpio::Pin;
|
||||
|
||||
|
@ -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 }
|
||||
|
@ -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);
|
||||
)*
|
||||
}
|
||||
});
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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> {
|
||||
|
@ -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> {
|
||||
|
@ -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)]
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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")]
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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::{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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")]
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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::*;
|
||||
|
@ -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 {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::Unborrow;
|
||||
use core::marker::PhantomData;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_hal_common::unborrow;
|
||||
|
||||
use super::*;
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy::interrupt::Interrupt;
|
||||
use crate::interrupt::Interrupt;
|
||||
|
||||
use crate::rcc::{sealed::RccPeripheral as __RccPeri, RccPeripheral};
|
||||
use crate::time::Hertz;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,4 @@
|
||||
use embassy::interrupt::Interrupt;
|
||||
use crate::interrupt::Interrupt;
|
||||
|
||||
use crate::rcc::RccPeripheral;
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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::*;
|
||||
|
@ -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 _;
|
||||
|
@ -8,11 +8,11 @@ use core::sync::atomic::{AtomicBool, Ordering};
|
||||
use defmt::*;
|
||||
use embassy::channel::signal::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
Loading…
Reference in New Issue
Block a user