Merge pull request #3 from OueslatiGhaith/master

fix merge conflicts
This commit is contained in:
Ghaith Oueslati 2023-06-12 14:28:23 +01:00 committed by GitHub
commit cf83f6820c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
146 changed files with 1591 additions and 1390 deletions

1
.github/ci/doc.sh vendored
View File

@ -14,7 +14,6 @@ docserver-builder -i ./embassy-boot/boot -o crates/embassy-boot/git.zup
docserver-builder -i ./embassy-boot/nrf -o crates/embassy-boot-nrf/git.zup docserver-builder -i ./embassy-boot/nrf -o crates/embassy-boot-nrf/git.zup
docserver-builder -i ./embassy-boot/rp -o crates/embassy-boot-rp/git.zup docserver-builder -i ./embassy-boot/rp -o crates/embassy-boot-rp/git.zup
docserver-builder -i ./embassy-boot/stm32 -o crates/embassy-boot-stm32/git.zup docserver-builder -i ./embassy-boot/stm32 -o crates/embassy-boot-stm32/git.zup
docserver-builder -i ./embassy-cortex-m -o crates/embassy-cortex-m/git.zup
docserver-builder -i ./embassy-embedded-hal -o crates/embassy-embedded-hal/git.zup docserver-builder -i ./embassy-embedded-hal -o crates/embassy-embedded-hal/git.zup
docserver-builder -i ./embassy-executor -o crates/embassy-executor/git.zup docserver-builder -i ./embassy-executor -o crates/embassy-executor/git.zup
docserver-builder -i ./embassy-futures -o crates/embassy-futures/git.zup docserver-builder -i ./embassy-futures -o crates/embassy-futures/git.zup

11
ci.sh
View File

@ -25,11 +25,19 @@ cargo batch \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \ --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \
--- build --release --manifest-path embassy-sync/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \ --- build --release --manifest-path embassy-sync/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \
--- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits,defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \ --- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features nightly,unstable-traits,defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits,nightly \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,unstable-traits \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,unstable-traits,nightly \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52805,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52805,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52810,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52810,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52811,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52811,gpiote,time-driver-rtc1 \
@ -104,6 +112,7 @@ cargo batch \
--- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-irq/Cargo.toml --target thumbv7em-none-eabi \ --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-irq/Cargo.toml --target thumbv7em-none-eabi \
--- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml --target thumbv7em-none-eabi \ --- build --release --manifest-path docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml --target thumbv7em-none-eabi \
--- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840 \ --- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840 \
--- build --release --manifest-path examples/nrf52840-rtic/Cargo.toml --target thumbv7em-none-eabi --out-dir out/examples/nrf52840-rtic \
--- build --release --manifest-path examples/nrf5340/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf5340 \ --- build --release --manifest-path examples/nrf5340/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/nrf5340 \
--- build --release --manifest-path examples/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/rp \ --- build --release --manifest-path examples/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/rp \
--- build --release --manifest-path examples/stm32f0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32f0 \ --- build --release --manifest-path examples/stm32f0/Cargo.toml --target thumbv6m-none-eabi --out-dir out/examples/stm32f0 \

View File

@ -14,9 +14,11 @@ cargo batch \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features log \ --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features log \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features defmt \ --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features defmt \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features defmt \ --- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features defmt \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,unstable-traits \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,unstable-traits \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52805,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52805,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52810,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52810,gpiote,time-driver-rtc1 \
--- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52811,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nrf52811,gpiote,time-driver-rtc1 \

View File

@ -381,10 +381,7 @@ impl<'a> Control<'a> {
} }
let ioctl = CancelOnDrop(self.ioctl_state); let ioctl = CancelOnDrop(self.ioctl_state);
let resp_len = ioctl.0.do_ioctl(kind, cmd, iface, buf).await;
ioctl.0.do_ioctl(kind, cmd, iface, buf).await;
let resp_len = ioctl.0.wait_complete().await;
ioctl.defuse(); ioctl.defuse();
resp_len resp_len

View File

@ -197,9 +197,6 @@ macro_rules! unwrap {
} }
} }
#[cfg(feature = "defmt-timestamp-uptime")]
defmt::timestamp! {"{=u64:us}", crate::time::Instant::now().as_micros() }
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct NoneError; pub struct NoneError;

View File

@ -1,45 +0,0 @@
[package]
name = "embassy-cortex-m"
version = "0.1.0"
edition = "2021"
license = "MIT OR Apache-2.0"
[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/$COMMIT/embassy-cortex-m/src/"
features = ["prio-bits-3"]
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.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-sync = { version = "0.2.0", path = "../embassy-sync" }
embassy-executor = { version = "0.2.0", path = "../embassy-executor"}
embassy-macros = { version = "0.2.0", path = "../embassy-macros"}
embassy-hal-common = { version = "0.1.0", path = "../embassy-hal-common"}
atomic-polyfill = "1.0.1"
critical-section = "1.1"
cfg-if = "1.0.0"
cortex-m = "0.7.6"

View File

@ -1,228 +0,0 @@
#![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,9 +0,0 @@
//! Embassy executor and interrupt handling specific to cortex-m devices.
#![no_std]
#![warn(missing_docs)]
// This mod MUST go first, so that the others see its macros.
pub(crate) mod fmt;
pub use embassy_executor as executor;
pub mod interrupt;

View File

@ -195,9 +195,6 @@ macro_rules! unwrap {
} }
} }
#[cfg(feature = "defmt-timestamp-uptime")]
defmt::timestamp! {"{=u64:us}", crate::time::Instant::now().as_micros() }
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct NoneError; pub struct NoneError;

View File

@ -6,8 +6,24 @@ license = "MIT OR Apache-2.0"
[features] [features]
# 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 = []
cortex-m = ["dep:cortex-m", "dep:critical-section"]
[dependencies] [dependencies]
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true } log = { version = "0.4.14", optional = true }
num-traits = { version = "0.2.14", default-features = false } num-traits = { version = "0.2.14", default-features = false }
cortex-m = { version = "0.7.6", optional = true }
critical-section = { version = "1", optional = true }

View File

@ -2,21 +2,114 @@
use core::mem; use core::mem;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use cortex_m::interrupt::InterruptNumber;
use cortex_m::peripheral::NVIC; use cortex_m::peripheral::NVIC;
/// Do not use. Used for macros and HALs only. Not covered by semver guarantees. /// Generate a standard `mod interrupt` for a HAL.
#[doc(hidden)] #[macro_export]
pub mod _export { macro_rules! interrupt_mod {
pub use atomic_polyfill as atomic; ($($irqs:ident),* $(,)?) => {
pub use embassy_macros::{cortex_m_interrupt as interrupt, cortex_m_interrupt_declare as declare}; #[cfg(feature = "rt")]
} pub use cortex_m_rt::interrupt;
/// Interrupt handler trait. /// Interrupt definitions.
/// pub mod interrupt {
/// Drivers that need to handle interrupts implement this trait. pub use $crate::interrupt::{InterruptExt, Priority};
/// The user must ensure `on_interrupt()` is called every time the interrupt fires. pub use crate::pac::Interrupt::*;
/// Drivers must use use [`Binding`] to assert at compile time that the user has done so. pub use crate::pac::Interrupt;
pub trait Handler<I: Interrupt> {
/// Type-level interrupt infrastructure.
///
/// This module contains one *type* per interrupt. This is used for checking at compile time that
/// the interrupts are correctly bound to HAL drivers.
///
/// As an end user, you shouldn't need to use this module directly. Use the [`crate::bind_interrupts!`] macro
/// to bind interrupts, and the [`crate::interrupt`] module to manually register interrupt handlers and manipulate
/// interrupts directly (pending/unpending, enabling/disabling, setting the priority, etc...)
pub mod typelevel {
use super::InterruptExt;
mod sealed {
pub trait Interrupt {}
}
/// Type-level interrupt.
///
/// This trait is implemented for all typelevel interrupt types in this module.
pub trait Interrupt: sealed::Interrupt {
/// Interrupt enum variant.
///
/// This allows going from typelevel interrupts (one type per interrupt) to
/// non-typelevel interrupts (a single `Interrupt` enum type, with one variant per interrupt).
const IRQ: super::Interrupt;
/// Enable the interrupt.
#[inline]
unsafe fn enable() {
Self::IRQ.enable()
}
/// Disable the interrupt.
#[inline]
fn disable() {
Self::IRQ.disable()
}
/// Check if interrupt is enabled.
#[inline]
fn is_enabled() -> bool {
Self::IRQ.is_enabled()
}
/// Check if interrupt is pending.
#[inline]
fn is_pending() -> bool {
Self::IRQ.is_pending()
}
/// Set interrupt pending.
#[inline]
fn pend() {
Self::IRQ.pend()
}
/// Unset interrupt pending.
#[inline]
fn unpend() {
Self::IRQ.unpend()
}
/// Get the priority of the interrupt.
#[inline]
fn get_priority() -> crate::interrupt::Priority {
Self::IRQ.get_priority()
}
/// Set the interrupt priority.
#[inline]
fn set_priority(prio: crate::interrupt::Priority) {
Self::IRQ.set_priority(prio)
}
}
$(
#[allow(non_camel_case_types)]
#[doc=stringify!($irqs)]
#[doc=" typelevel interrupt."]
pub enum $irqs {}
impl sealed::Interrupt for $irqs{}
impl Interrupt for $irqs {
const IRQ: super::Interrupt = super::Interrupt::$irqs;
}
)*
/// Interrupt handler trait.
///
/// Drivers that need to handle interrupts implement this trait.
/// The user must ensure `on_interrupt()` is called every time the interrupt fires.
/// Drivers must use use [`Binding`] to assert at compile time that the user has done so.
pub trait Handler<I: Interrupt> {
/// Interrupt handler function. /// Interrupt handler function.
/// ///
/// Must be called every time the `I` interrupt fires, synchronously from /// Must be called every time the `I` interrupt fires, synchronously from
@ -26,96 +119,91 @@ pub trait Handler<I: Interrupt> {
/// ///
/// This function must ONLY be called from the interrupt handler for `I`. /// This function must ONLY be called from the interrupt handler for `I`.
unsafe fn on_interrupt(); unsafe fn on_interrupt();
}
/// Compile-time assertion that an interrupt has been bound to a handler.
///
/// For the vast majority of cases, you should use the `bind_interrupts!`
/// macro instead of writing `unsafe impl`s of this trait.
///
/// # Safety
///
/// By implementing this trait, you are asserting that you have arranged for `H::on_interrupt()`
/// to be called every time the `I` interrupt fires.
///
/// This allows drivers to check bindings at compile-time.
pub unsafe trait Binding<I: Interrupt, H: Handler<I>> {}
#[derive(Clone, Copy)]
pub(crate) struct NrWrap(pub(crate) u16);
unsafe impl cortex_m::interrupt::InterruptNumber for NrWrap {
fn number(self) -> u16 {
self.0
} }
/// Compile-time assertion that an interrupt has been bound to a handler.
///
/// For the vast majority of cases, you should use the `bind_interrupts!`
/// macro instead of writing `unsafe impl`s of this trait.
///
/// # Safety
///
/// By implementing this trait, you are asserting that you have arranged for `H::on_interrupt()`
/// to be called every time the `I` interrupt fires.
///
/// This allows drivers to check bindings at compile-time.
pub unsafe trait Binding<I: Interrupt, H: Handler<I>> {}
}
}
};
} }
/// Represents an interrupt type that can be configured by embassy to handle /// Represents an interrupt type that can be configured by embassy to handle
/// interrupts. /// interrupts.
pub unsafe trait Interrupt { pub unsafe trait InterruptExt: InterruptNumber + Copy {
/// Return the NVIC interrupt number for this interrupt.
fn number() -> u16;
/// Enable the interrupt. /// Enable the interrupt.
#[inline] #[inline]
unsafe fn enable() { unsafe fn enable(self) {
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
NVIC::unmask(NrWrap(Self::number())) NVIC::unmask(self)
} }
/// Disable the interrupt. /// Disable the interrupt.
#[inline] #[inline]
fn disable() { fn disable(self) {
NVIC::mask(NrWrap(Self::number())); NVIC::mask(self);
compiler_fence(Ordering::SeqCst); compiler_fence(Ordering::SeqCst);
} }
/// Check if interrupt is being handled. /// Check if interrupt is being handled.
#[inline] #[inline]
#[cfg(not(armv6m))] #[cfg(not(armv6m))]
fn is_active() -> bool { fn is_active(self) -> bool {
NVIC::is_active(NrWrap(Self::number())) NVIC::is_active(self)
} }
/// Check if interrupt is enabled. /// Check if interrupt is enabled.
#[inline] #[inline]
fn is_enabled() -> bool { fn is_enabled(self) -> bool {
NVIC::is_enabled(NrWrap(Self::number())) NVIC::is_enabled(self)
} }
/// Check if interrupt is pending. /// Check if interrupt is pending.
#[inline] #[inline]
fn is_pending() -> bool { fn is_pending(self) -> bool {
NVIC::is_pending(NrWrap(Self::number())) NVIC::is_pending(self)
} }
/// Set interrupt pending. /// Set interrupt pending.
#[inline] #[inline]
fn pend() { fn pend(self) {
NVIC::pend(NrWrap(Self::number())) NVIC::pend(self)
} }
/// Unset interrupt pending. /// Unset interrupt pending.
#[inline] #[inline]
fn unpend() { fn unpend(self) {
NVIC::unpend(NrWrap(Self::number())) NVIC::unpend(self)
} }
/// Get the priority of the interrupt. /// Get the priority of the interrupt.
#[inline] #[inline]
fn get_priority() -> Priority { fn get_priority(self) -> Priority {
Priority::from(NVIC::get_priority(NrWrap(Self::number()))) Priority::from(NVIC::get_priority(self))
} }
/// Set the interrupt priority. /// Set the interrupt priority.
#[inline] #[inline]
fn set_priority(prio: Priority) { fn set_priority(self, prio: Priority) {
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(()); let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
nvic.set_priority(NrWrap(Self::number()), prio.into()) nvic.set_priority(self, prio.into())
}) })
} }
} }
unsafe impl<T: InterruptNumber + Copy> InterruptExt for T {}
impl From<u8> for Priority { impl From<u8> for Priority {
fn from(priority: u8) -> Self { fn from(priority: u8) -> Self {
unsafe { mem::transmute(priority & PRIO_MASK) } unsafe { mem::transmute(priority & PRIO_MASK) }

View File

@ -11,3 +11,6 @@ mod peripheral;
pub mod ratio; pub mod ratio;
pub mod ring_buffer; pub mod ring_buffer;
pub use peripheral::{Peripheral, PeripheralRef}; pub use peripheral::{Peripheral, PeripheralRef};
#[cfg(feature = "cortex-m")]
pub mod interrupt;

View File

@ -1,7 +1,7 @@
#[cfg(feature = "stm32wl")] #[cfg(feature = "stm32wl")]
use embassy_stm32::interrupt; use embassy_stm32::interrupt;
#[cfg(feature = "stm32wl")] #[cfg(feature = "stm32wl")]
use embassy_stm32::interrupt::*; use embassy_stm32::interrupt::InterruptExt;
#[cfg(feature = "stm32wl")] #[cfg(feature = "stm32wl")]
use embassy_stm32::pac; use embassy_stm32::pac;
#[cfg(feature = "stm32wl")] #[cfg(feature = "stm32wl")]
@ -20,9 +20,9 @@ use lora_phy::mod_traits::InterfaceVariant;
pub struct InterruptHandler {} pub struct InterruptHandler {}
#[cfg(feature = "stm32wl")] #[cfg(feature = "stm32wl")]
impl interrupt::Handler<interrupt::SUBGHZ_RADIO> for InterruptHandler { impl interrupt::typelevel::Handler<interrupt::typelevel::SUBGHZ_RADIO> for InterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
interrupt::SUBGHZ_RADIO::disable(); interrupt::SUBGHZ_RADIO.disable();
IRQ_SIGNAL.signal(()); IRQ_SIGNAL.signal(());
} }
} }
@ -45,11 +45,11 @@ where
{ {
/// Create an InterfaceVariant instance for an stm32wl/sx1262 combination /// Create an InterfaceVariant instance for an stm32wl/sx1262 combination
pub fn new( pub fn new(
_irq: impl interrupt::Binding<interrupt::SUBGHZ_RADIO, InterruptHandler>, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::SUBGHZ_RADIO, InterruptHandler>,
rf_switch_rx: Option<CTRL>, rf_switch_rx: Option<CTRL>,
rf_switch_tx: Option<CTRL>, rf_switch_tx: Option<CTRL>,
) -> Result<Self, RadioError> { ) -> Result<Self, RadioError> {
interrupt::SUBGHZ_RADIO::disable(); interrupt::SUBGHZ_RADIO.disable();
Ok(Self { Ok(Self {
board_type: BoardType::Stm32wlSx1262, // updated when associated with a specific LoRa board board_type: BoardType::Stm32wlSx1262, // updated when associated with a specific LoRa board
rf_switch_rx, rf_switch_rx,
@ -95,7 +95,7 @@ where
} }
async fn await_irq(&mut self) -> Result<(), RadioError> { async fn await_irq(&mut self) -> Result<(), RadioError> {
unsafe { interrupt::SUBGHZ_RADIO::enable() }; unsafe { interrupt::SUBGHZ_RADIO.enable() };
IRQ_SIGNAL.wait().await; IRQ_SIGNAL.wait().await;
Ok(()) Ok(())
} }

View File

@ -156,16 +156,3 @@ pub fn main_wasm(args: TokenStream, item: TokenStream) -> TokenStream {
let f = syn::parse_macro_input!(item as syn::ItemFn); let f = syn::parse_macro_input!(item as syn::ItemFn);
main::run(args, f, main::wasm()).unwrap_or_else(|x| x).into() main::run(args, f, main::wasm()).unwrap_or_else(|x| x).into()
} }
#[proc_macro_attribute]
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);
cortex_m_interrupt::run(args, f).unwrap_or_else(|x| x).into()
}
#[proc_macro]
pub fn cortex_m_interrupt_declare(item: TokenStream) -> TokenStream {
let name = syn::parse_macro_input!(item as syn::Ident);
cortex_m_interrupt_declare::run(name).unwrap_or_else(|x| x).into()
}

View File

@ -1,66 +0,0 @@
use std::iter;
use darling::FromMeta;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{ReturnType, Type, Visibility};
use crate::util::ctxt::Ctxt;
#[derive(Debug, FromMeta)]
struct Args {}
pub fn run(args: syn::AttributeArgs, mut f: syn::ItemFn) -> Result<TokenStream, TokenStream> {
let _args = Args::from_list(&args).map_err(|e| e.write_errors())?;
let ident = f.sig.ident.clone();
let ident_s = ident.to_string();
// XXX should we blacklist other attributes?
let valid_signature = f.sig.constness.is_none()
&& f.vis == Visibility::Inherited
&& f.sig.abi.is_none()
&& f.sig.inputs.is_empty()
&& f.sig.generics.params.is_empty()
&& f.sig.generics.where_clause.is_none()
&& f.sig.variadic.is_none()
&& match f.sig.output {
ReturnType::Default => true,
ReturnType::Type(_, ref ty) => match **ty {
Type::Tuple(ref tuple) => tuple.elems.is_empty(),
Type::Never(..) => true,
_ => false,
},
};
let ctxt = Ctxt::new();
if !valid_signature {
ctxt.error_spanned_by(
&f.sig,
"`#[interrupt]` handlers must have signature `[unsafe] fn() [-> !]`",
);
}
ctxt.check()?;
f.block.stmts = iter::once(
syn::parse2(quote! {{
// Check that this interrupt actually exists
let __irq_exists_check: interrupt::#ident;
}})
.unwrap(),
)
.chain(f.block.stmts)
.collect();
let result = quote!(
#[doc(hidden)]
#[export_name = #ident_s]
#[allow(non_snake_case)]
#f
);
Ok(result)
}

View File

@ -1,21 +0,0 @@
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub fn run(name: syn::Ident) -> Result<TokenStream, TokenStream> {
let name = format_ident!("{}", name);
let doc = format!("{} interrupt.", name);
let result = quote! {
#[doc = #doc]
#[allow(non_camel_case_types)]
pub enum #name{}
unsafe impl ::embassy_cortex_m::interrupt::Interrupt for #name {
fn number() -> u16 {
use cortex_m::interrupt::InterruptNumber;
let irq = InterruptEnum::#name;
irq.number() as u16
}
}
};
Ok(result)
}

View File

@ -1,4 +1,2 @@
pub mod cortex_m_interrupt;
pub mod cortex_m_interrupt_declare;
pub mod main; pub mod main;
pub mod task; pub mod task;

View File

@ -26,7 +26,8 @@ unstable-traits = []
udp = ["smoltcp/socket-udp"] udp = ["smoltcp/socket-udp"]
tcp = ["smoltcp/socket-tcp"] tcp = ["smoltcp/socket-tcp"]
dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"] dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"]
dhcpv4 = ["medium-ethernet", "smoltcp/socket-dhcpv4"] dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"]
proto-ipv4 = ["smoltcp/proto-ipv4"]
proto-ipv6 = ["smoltcp/proto-ipv6"] proto-ipv6 = ["smoltcp/proto-ipv6"]
medium-ethernet = ["smoltcp/medium-ethernet"] medium-ethernet = ["smoltcp/medium-ethernet"]
medium-ip = ["smoltcp/medium-ip"] medium-ip = ["smoltcp/medium-ip"]
@ -38,7 +39,6 @@ defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true } log = { version = "0.4.14", optional = true }
smoltcp = { version = "0.9.0", default-features = false, features = [ smoltcp = { version = "0.9.0", default-features = false, features = [
"proto-ipv4",
"socket", "socket",
"async", "async",
]} ]}

View File

@ -59,7 +59,10 @@ where
smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4); smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4);
smolcaps.checksum.tcp = convert(caps.checksum.tcp); smolcaps.checksum.tcp = convert(caps.checksum.tcp);
smolcaps.checksum.udp = convert(caps.checksum.udp); smolcaps.checksum.udp = convert(caps.checksum.udp);
#[cfg(feature = "proto-ipv4")]
{
smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4); smolcaps.checksum.icmpv4 = convert(caps.checksum.icmpv4);
}
#[cfg(feature = "proto-ipv6")] #[cfg(feature = "proto-ipv6")]
{ {
smolcaps.checksum.icmpv6 = convert(caps.checksum.icmpv6); smolcaps.checksum.icmpv6 = convert(caps.checksum.icmpv6);

View File

@ -88,6 +88,7 @@ where
let addrs = self.query(host, qtype).await?; let addrs = self.query(host, qtype).await?;
if let Some(first) = addrs.get(0) { if let Some(first) = addrs.get(0) {
Ok(match first { Ok(match first {
#[cfg(feature = "proto-ipv4")]
IpAddress::Ipv4(addr) => IpAddr::V4(addr.0.into()), IpAddress::Ipv4(addr) => IpAddr::V4(addr.0.into()),
#[cfg(feature = "proto-ipv6")] #[cfg(feature = "proto-ipv6")]
IpAddress::Ipv6(addr) => IpAddr::V6(addr.0.into()), IpAddress::Ipv6(addr) => IpAddr::V6(addr.0.into()),

View File

@ -34,7 +34,9 @@ use smoltcp::socket::dhcpv4::{self, RetryConfig};
pub use smoltcp::wire::IpListenEndpoint; pub use smoltcp::wire::IpListenEndpoint;
#[cfg(feature = "medium-ethernet")] #[cfg(feature = "medium-ethernet")]
pub use smoltcp::wire::{EthernetAddress, HardwareAddress}; pub use smoltcp::wire::{EthernetAddress, HardwareAddress};
pub use smoltcp::wire::{IpAddress, IpCidr, Ipv4Address, Ipv4Cidr}; pub use smoltcp::wire::{IpAddress, IpCidr};
#[cfg(feature = "proto-ipv4")]
pub use smoltcp::wire::{Ipv4Address, Ipv4Cidr};
#[cfg(feature = "proto-ipv6")] #[cfg(feature = "proto-ipv6")]
pub use smoltcp::wire::{Ipv6Address, Ipv6Cidr}; pub use smoltcp::wire::{Ipv6Address, Ipv6Cidr};
@ -67,8 +69,9 @@ impl<const SOCK: usize> StackResources<SOCK> {
} }
/// Static IP address configuration. /// Static IP address configuration.
#[cfg(feature = "proto-ipv4")]
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct StaticConfig { pub struct StaticConfigV4 {
/// IP address and subnet mask. /// IP address and subnet mask.
pub address: Ipv4Cidr, pub address: Ipv4Cidr,
/// Default gateway. /// Default gateway.
@ -77,6 +80,18 @@ pub struct StaticConfig {
pub dns_servers: Vec<Ipv4Address, 3>, pub dns_servers: Vec<Ipv4Address, 3>,
} }
/// Static IPv6 address configuration
#[cfg(feature = "proto-ipv6")]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StaticConfigV6 {
/// IP address and subnet mask.
pub address: Ipv6Cidr,
/// Default gateway.
pub gateway: Option<Ipv6Address>,
/// DNS servers.
pub dns_servers: Vec<Ipv6Address, 3>,
}
/// DHCP configuration. /// DHCP configuration.
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@ -112,12 +127,71 @@ impl Default for DhcpConfig {
} }
/// Network stack configuration. /// Network stack configuration.
pub enum Config { pub struct Config {
/// Use a static IP address configuration. /// IPv4 configuration
Static(StaticConfig), #[cfg(feature = "proto-ipv4")]
pub ipv4: ConfigV4,
/// IPv6 configuration
#[cfg(feature = "proto-ipv6")]
pub ipv6: ConfigV6,
}
impl Config {
/// IPv4 configuration with static addressing.
#[cfg(feature = "proto-ipv4")]
pub fn ipv4_static(config: StaticConfigV4) -> Self {
Self {
ipv4: ConfigV4::Static(config),
#[cfg(feature = "proto-ipv6")]
ipv6: ConfigV6::None,
}
}
/// IPv6 configuration with static addressing.
#[cfg(feature = "proto-ipv6")]
pub fn ipv6_static(config: StaticConfigV6) -> Self {
Self {
#[cfg(feature = "proto-ipv4")]
ipv4: ConfigV4::None,
ipv6: ConfigV6::Static(config),
}
}
/// IPv6 configuration with dynamic addressing.
///
/// # Example
/// ```rust
/// let _cfg = Config::dhcpv4(Default::default());
/// ```
#[cfg(feature = "dhcpv4")]
pub fn dhcpv4(config: DhcpConfig) -> Self {
Self {
ipv4: ConfigV4::Dhcp(config),
#[cfg(feature = "proto-ipv6")]
ipv6: ConfigV6::None,
}
}
}
/// Network stack IPv4 configuration.
#[cfg(feature = "proto-ipv4")]
pub enum ConfigV4 {
/// Use a static IPv4 address configuration.
Static(StaticConfigV4),
/// Use DHCP to obtain an IP address configuration. /// Use DHCP to obtain an IP address configuration.
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
Dhcp(DhcpConfig), Dhcp(DhcpConfig),
/// Do not configure IPv6.
None,
}
/// Network stack IPv6 configuration.
#[cfg(feature = "proto-ipv6")]
pub enum ConfigV6 {
/// Use a static IPv6 address configuration.
Static(StaticConfigV6),
/// Do not configure IPv6.
None,
} }
/// A network stack. /// A network stack.
@ -131,7 +205,10 @@ pub struct Stack<D: Driver> {
struct Inner<D: Driver> { struct Inner<D: Driver> {
device: D, device: D,
link_up: bool, link_up: bool,
config: Option<StaticConfig>, #[cfg(feature = "proto-ipv4")]
static_v4: Option<StaticConfigV4>,
#[cfg(feature = "proto-ipv6")]
static_v6: Option<StaticConfigV6>,
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
dhcp_socket: Option<SocketHandle>, dhcp_socket: Option<SocketHandle>,
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
@ -187,7 +264,10 @@ impl<D: Driver + 'static> Stack<D> {
let mut inner = Inner { let mut inner = Inner {
device, device,
link_up: false, link_up: false,
config: None, #[cfg(feature = "proto-ipv4")]
static_v4: None,
#[cfg(feature = "proto-ipv6")]
static_v6: None,
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
dhcp_socket: None, dhcp_socket: None,
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
@ -199,17 +279,26 @@ impl<D: Driver + 'static> Stack<D> {
dns_waker: WakerRegistration::new(), dns_waker: WakerRegistration::new(),
}; };
match config { #[cfg(feature = "proto-ipv4")]
Config::Static(config) => { match config.ipv4 {
inner.apply_config(&mut socket, config); ConfigV4::Static(config) => {
inner.apply_config_v4(&mut socket, config);
} }
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
Config::Dhcp(config) => { ConfigV4::Dhcp(config) => {
let mut dhcp_socket = smoltcp::socket::dhcpv4::Socket::new(); let mut dhcp_socket = smoltcp::socket::dhcpv4::Socket::new();
inner.apply_dhcp_config(&mut dhcp_socket, config); inner.apply_dhcp_config(&mut dhcp_socket, config);
let handle = socket.sockets.add(dhcp_socket); let handle = socket.sockets.add(dhcp_socket);
inner.dhcp_socket = Some(handle); inner.dhcp_socket = Some(handle);
} }
ConfigV4::None => {}
}
#[cfg(feature = "proto-ipv6")]
match config.ipv6 {
ConfigV6::Static(config) => {
inner.apply_config_v6(&mut socket, config);
}
ConfigV6::None => {}
} }
Self { Self {
@ -239,12 +328,40 @@ impl<D: Driver + 'static> Stack<D> {
/// Get whether the network stack has a valid IP configuration. /// Get whether the network stack has a valid IP configuration.
/// This is true if the network stack has a static IP configuration or if DHCP has completed /// This is true if the network stack has a static IP configuration or if DHCP has completed
pub fn is_config_up(&self) -> bool { pub fn is_config_up(&self) -> bool {
self.with(|_s, i| i.config.is_some()) let v4_up;
let v6_up;
#[cfg(feature = "proto-ipv4")]
{
v4_up = self.config_v4().is_some();
}
#[cfg(not(feature = "proto-ipv4"))]
{
v4_up = false;
} }
/// Get the current IP configuration. #[cfg(feature = "proto-ipv6")]
pub fn config(&self) -> Option<StaticConfig> { {
self.with(|_s, i| i.config.clone()) v6_up = self.config_v6().is_some();
}
#[cfg(not(feature = "proto-ipv6"))]
{
v6_up = false;
}
v4_up || v6_up
}
/// Get the current IPv4 configuration.
#[cfg(feature = "proto-ipv4")]
pub fn config_v4(&self) -> Option<StaticConfigV4> {
self.with(|_s, i| i.static_v4.clone())
}
/// Get the current IPv6 configuration.
#[cfg(feature = "proto-ipv6")]
pub fn config_v6(&self) -> Option<StaticConfigV6> {
self.with(|_s, i| i.static_v6.clone())
} }
/// Run the network stack. /// Run the network stack.
@ -264,6 +381,7 @@ impl<D: Driver + 'static> Stack<D> {
pub async fn dns_query(&self, name: &str, qtype: dns::DnsQueryType) -> Result<Vec<IpAddress, 1>, dns::Error> { pub async fn dns_query(&self, name: &str, qtype: dns::DnsQueryType) -> Result<Vec<IpAddress, 1>, dns::Error> {
// For A and AAAA queries we try detect whether `name` is just an IP address // For A and AAAA queries we try detect whether `name` is just an IP address
match qtype { match qtype {
#[cfg(feature = "proto-ipv4")]
dns::DnsQueryType::A => { dns::DnsQueryType::A => {
if let Ok(ip) = name.parse().map(IpAddress::Ipv4) { if let Ok(ip) = name.parse().map(IpAddress::Ipv4) {
return Ok([ip].into_iter().collect()); return Ok([ip].into_iter().collect());
@ -374,7 +492,8 @@ impl SocketStack {
} }
impl<D: Driver + 'static> Inner<D> { impl<D: Driver + 'static> Inner<D> {
fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfig) { #[cfg(feature = "proto-ipv4")]
fn apply_config_v4(&mut self, s: &mut SocketStack, config: StaticConfigV4) {
#[cfg(feature = "medium-ethernet")] #[cfg(feature = "medium-ethernet")]
let medium = self.device.capabilities().medium; let medium = self.device.capabilities().medium;
@ -403,14 +522,86 @@ impl<D: Driver + 'static> Inner<D> {
debug!(" DNS server {}: {}", i, s); debug!(" DNS server {}: {}", i, s);
} }
self.static_v4 = Some(config);
#[cfg(feature = "dns")] #[cfg(feature = "dns")]
{ {
let socket = s.sockets.get_mut::<smoltcp::socket::dns::Socket>(self.dns_socket); self.update_dns_servers(s)
let servers: Vec<IpAddress, 3> = config.dns_servers.iter().map(|c| IpAddress::Ipv4(*c)).collect(); }
socket.update_servers(&servers[..]);
} }
self.config = Some(config) /// Replaces the current IPv6 static configuration with a newly supplied config.
#[cfg(feature = "proto-ipv6")]
fn apply_config_v6(&mut self, s: &mut SocketStack, config: StaticConfigV6) {
#[cfg(feature = "medium-ethernet")]
let medium = self.device.capabilities().medium;
debug!("Acquired IPv6 configuration:");
debug!(" IP address: {}", config.address);
s.iface.update_ip_addrs(|addrs| {
if addrs.is_empty() {
addrs.push(IpCidr::Ipv6(config.address)).unwrap();
} else {
addrs[0] = IpCidr::Ipv6(config.address);
}
});
#[cfg(feature = "medium-ethernet")]
if Medium::Ethernet == medium {
if let Some(gateway) = config.gateway {
debug!(" Default gateway: {}", gateway);
s.iface.routes_mut().add_default_ipv6_route(gateway).unwrap();
} else {
debug!(" Default gateway: None");
s.iface.routes_mut().remove_default_ipv6_route();
}
}
for (i, s) in config.dns_servers.iter().enumerate() {
debug!(" DNS server {}: {}", i, s);
}
self.static_v6 = Some(config);
#[cfg(feature = "dns")]
{
self.update_dns_servers(s)
}
}
#[cfg(feature = "dns")]
fn update_dns_servers(&mut self, s: &mut SocketStack) {
let socket = s.sockets.get_mut::<smoltcp::socket::dns::Socket>(self.dns_socket);
let servers_v4;
#[cfg(feature = "proto-ipv4")]
{
servers_v4 = self
.static_v4
.iter()
.flat_map(|cfg| cfg.dns_servers.iter().map(|c| IpAddress::Ipv4(*c)));
};
#[cfg(not(feature = "proto-ipv4"))]
{
servers_v4 = core::iter::empty();
}
let servers_v6;
#[cfg(feature = "proto-ipv6")]
{
servers_v6 = self
.static_v6
.iter()
.flat_map(|cfg| cfg.dns_servers.iter().map(|c| IpAddress::Ipv6(*c)));
}
#[cfg(not(feature = "proto-ipv6"))]
{
servers_v6 = core::iter::empty();
}
// Prefer the v6 DNS servers over the v4 servers
let servers: Vec<IpAddress, 6> = servers_v6.chain(servers_v4).collect();
socket.update_servers(&servers[..]);
} }
#[cfg(feature = "dhcpv4")] #[cfg(feature = "dhcpv4")]
@ -430,9 +621,15 @@ impl<D: Driver + 'static> Inner<D> {
s.iface.update_ip_addrs(|ip_addrs| ip_addrs.clear()); s.iface.update_ip_addrs(|ip_addrs| ip_addrs.clear());
#[cfg(feature = "medium-ethernet")] #[cfg(feature = "medium-ethernet")]
if medium == Medium::Ethernet { if medium == Medium::Ethernet {
#[cfg(feature = "proto-ipv4")]
{
s.iface.routes_mut().remove_default_ipv4_route(); s.iface.routes_mut().remove_default_ipv4_route();
} }
self.config = None }
#[cfg(feature = "proto-ipv4")]
{
self.static_v4 = None
}
} }
fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) {
@ -470,12 +667,12 @@ impl<D: Driver + 'static> Inner<D> {
None => {} None => {}
Some(dhcpv4::Event::Deconfigured) => self.unapply_config(s), Some(dhcpv4::Event::Deconfigured) => self.unapply_config(s),
Some(dhcpv4::Event::Configured(config)) => { Some(dhcpv4::Event::Configured(config)) => {
let config = StaticConfig { let config = StaticConfigV4 {
address: config.address, address: config.address,
gateway: config.router, gateway: config.router,
dns_servers: config.dns_servers, dns_servers: config.dns_servers,
}; };
self.apply_config(s, config) self.apply_config_v4(s, config)
} }
} }
} else if old_link_up { } else if old_link_up {

View File

@ -480,7 +480,10 @@ pub mod client {
Self: 'a, Self: 'a,
{ {
let addr: crate::IpAddress = match remote.ip() { let addr: crate::IpAddress = match remote.ip() {
#[cfg(feature = "proto-ipv4")]
IpAddr::V4(addr) => crate::IpAddress::Ipv4(crate::Ipv4Address::from_bytes(&addr.octets())), IpAddr::V4(addr) => crate::IpAddress::Ipv4(crate::Ipv4Address::from_bytes(&addr.octets())),
#[cfg(not(feature = "proto-ipv4"))]
IpAddr::V4(_) => panic!("ipv4 support not enabled"),
#[cfg(feature = "proto-ipv6")] #[cfg(feature = "proto-ipv6")]
IpAddr::V6(addr) => crate::IpAddress::Ipv6(crate::Ipv6Address::from_bytes(&addr.octets())), IpAddr::V6(addr) => crate::IpAddress::Ipv6(crate::Ipv6Address::from_bytes(&addr.octets())),
#[cfg(not(feature = "proto-ipv6"))] #[cfg(not(feature = "proto-ipv6"))]

View File

@ -16,7 +16,8 @@ flavors = [
] ]
[features] [features]
default = [ default = ["rt"]
rt = [
"nrf52805-pac?/rt", "nrf52805-pac?/rt",
"nrf52810-pac?/rt", "nrf52810-pac?/rt",
"nrf52811-pac?/rt", "nrf52811-pac?/rt",
@ -31,7 +32,7 @@ default = [
time = ["dep:embassy-time"] time = ["dep:embassy-time"]
defmt = ["dep:defmt", "embassy-executor/defmt", "embassy-sync/defmt", "embassy-usb-driver?/defmt", "embedded-io?/defmt", "embassy-embedded-hal/defmt"] defmt = ["dep:defmt", "embassy-sync/defmt", "embassy-usb-driver?/defmt", "embedded-io?/defmt", "embassy-embedded-hal/defmt"]
# Enable nightly-only features # Enable nightly-only features
nightly = ["embedded-hal-1", "embedded-hal-async", "dep:embassy-usb-driver", "embedded-storage-async", "dep:embedded-io", "embassy-embedded-hal/nightly"] nightly = ["embedded-hal-1", "embedded-hal-async", "dep:embassy-usb-driver", "embedded-storage-async", "dep:embedded-io", "embassy-embedded-hal/nightly"]
@ -90,11 +91,9 @@ _dppi = []
_gpio-p1 = [] _gpio-p1 = []
[dependencies] [dependencies]
embassy-executor = { version = "0.2.0", path = "../embassy-executor", optional = true }
embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true } embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.2.0", path = "../embassy-sync" } embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
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", features = ["cortex-m", "prio-bits-3"] }
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true }

View File

@ -15,7 +15,6 @@ use core::slice;
use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering}; use core::sync::atomic::{compiler_fence, AtomicU8, AtomicUsize, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::atomic_ring_buffer::RingBuffer; use embassy_hal_common::atomic_ring_buffer::RingBuffer;
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -24,13 +23,13 @@ pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Pari
use crate::gpio::sealed::Pin; use crate::gpio::sealed::Pin;
use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
use crate::interrupt::{self}; use crate::interrupt::typelevel::Interrupt;
use crate::ppi::{ use crate::ppi::{
self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task, self, AnyConfigurableChannel, AnyGroup, Channel, ConfigurableChannel, Event, Group, Ppi, PpiGroup, Task,
}; };
use crate::timer::{Instance as TimerInstance, Timer}; use crate::timer::{Instance as TimerInstance, Timer};
use crate::uarte::{apply_workaround_for_enable_anomaly, Config, Instance as UarteInstance}; use crate::uarte::{apply_workaround_for_enable_anomaly, Config, Instance as UarteInstance};
use crate::{pac, Peripheral}; use crate::{interrupt, pac, Peripheral};
mod sealed { mod sealed {
use super::*; use super::*;
@ -77,7 +76,7 @@ pub struct InterruptHandler<U: UarteInstance> {
_phantom: PhantomData<U>, _phantom: PhantomData<U>,
} }
impl<U: UarteInstance> interrupt::Handler<U::Interrupt> for InterruptHandler<U> { impl<U: UarteInstance> interrupt::typelevel::Handler<U::Interrupt> for InterruptHandler<U> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
//trace!("irq: start"); //trace!("irq: start");
let r = U::regs(); let r = U::regs();
@ -202,7 +201,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_group: impl Peripheral<P = impl Group> + 'd, ppi_group: impl Peripheral<P = impl Group> + 'd,
_irq: impl interrupt::Binding<U::Interrupt, InterruptHandler<U>> + 'd, _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: impl Peripheral<P = impl GpioPin> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -237,7 +236,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd, ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
ppi_group: impl Peripheral<P = impl Group> + 'd, ppi_group: impl Peripheral<P = impl Group> + 'd,
_irq: impl interrupt::Binding<U::Interrupt, InterruptHandler<U>> + 'd, _irq: impl interrupt::typelevel::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: impl Peripheral<P = impl GpioPin> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: impl Peripheral<P = impl GpioPin> + 'd,
cts: impl Peripheral<P = impl GpioPin> + 'd, cts: impl Peripheral<P = impl GpioPin> + 'd,

View File

@ -208,33 +208,29 @@ impl_ppi_channel!(PPI_CH31, 31 => static);
impl_saadc_input!(P0_04, ANALOG_INPUT2); impl_saadc_input!(P0_04, ANALOG_INPUT2);
impl_saadc_input!(P0_05, ANALOG_INPUT3); impl_saadc_input!(P0_05, ANALOG_INPUT3);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; POWER_CLOCK,
RADIO,
use crate::pac::Interrupt as InterruptEnum; UARTE0_UART0,
TWIM0_TWIS0_TWI0,
declare!(POWER_CLOCK); SPIM0_SPIS0_SPI0,
declare!(RADIO); GPIOTE,
declare!(UARTE0_UART0); SAADC,
declare!(TWIM0_TWIS0_TWI0); TIMER0,
declare!(SPIM0_SPIS0_SPI0); TIMER1,
declare!(GPIOTE); TIMER2,
declare!(SAADC); RTC0,
declare!(TIMER0); TEMP,
declare!(TIMER1); RNG,
declare!(TIMER2); ECB,
declare!(RTC0); CCM_AAR,
declare!(TEMP); WDT,
declare!(RNG); RTC1,
declare!(ECB); QDEC,
declare!(CCM_AAR); SWI0_EGU0,
declare!(WDT); SWI1_EGU1,
declare!(RTC1); SWI2,
declare!(QDEC); SWI3,
declare!(SWI0_EGU0); SWI4,
declare!(SWI1_EGU1); SWI5,
declare!(SWI2); );
declare!(SWI3);
declare!(SWI4);
declare!(SWI5);
}

View File

@ -234,36 +234,32 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5);
impl_saadc_input!(P0_30, ANALOG_INPUT6); impl_saadc_input!(P0_30, ANALOG_INPUT6);
impl_saadc_input!(P0_31, ANALOG_INPUT7); impl_saadc_input!(P0_31, ANALOG_INPUT7);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; POWER_CLOCK,
RADIO,
use crate::pac::Interrupt as InterruptEnum; UARTE0_UART0,
TWIM0_TWIS0_TWI0,
declare!(POWER_CLOCK); SPIM0_SPIS0_SPI0,
declare!(RADIO); GPIOTE,
declare!(UARTE0_UART0); SAADC,
declare!(TWIM0_TWIS0_TWI0); TIMER0,
declare!(SPIM0_SPIS0_SPI0); TIMER1,
declare!(GPIOTE); TIMER2,
declare!(SAADC); RTC0,
declare!(TIMER0); TEMP,
declare!(TIMER1); RNG,
declare!(TIMER2); ECB,
declare!(RTC0); CCM_AAR,
declare!(TEMP); WDT,
declare!(RNG); RTC1,
declare!(ECB); QDEC,
declare!(CCM_AAR); COMP,
declare!(WDT); SWI0_EGU0,
declare!(RTC1); SWI1_EGU1,
declare!(QDEC); SWI2,
declare!(COMP); SWI3,
declare!(SWI0_EGU0); SWI4,
declare!(SWI1_EGU1); SWI5,
declare!(SWI2); PWM0,
declare!(SWI3); PDM,
declare!(SWI4); );
declare!(SWI5);
declare!(PWM0);
declare!(PDM);
}

View File

@ -236,36 +236,32 @@ impl_saadc_input!(P0_29, ANALOG_INPUT5);
impl_saadc_input!(P0_30, ANALOG_INPUT6); impl_saadc_input!(P0_30, ANALOG_INPUT6);
impl_saadc_input!(P0_31, ANALOG_INPUT7); impl_saadc_input!(P0_31, ANALOG_INPUT7);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; POWER_CLOCK,
RADIO,
use crate::pac::Interrupt as InterruptEnum; UARTE0_UART0,
TWIM0_TWIS0_TWI0_SPIM0_SPIS0_SPI0,
declare!(POWER_CLOCK); SPIM1_SPIS1_SPI1,
declare!(RADIO); GPIOTE,
declare!(UARTE0_UART0); SAADC,
declare!(TWIM0_TWIS0_TWI0_SPIM0_SPIS0_SPI0); TIMER0,
declare!(SPIM1_SPIS1_SPI1); TIMER1,
declare!(GPIOTE); TIMER2,
declare!(SAADC); RTC0,
declare!(TIMER0); TEMP,
declare!(TIMER1); RNG,
declare!(TIMER2); ECB,
declare!(RTC0); CCM_AAR,
declare!(TEMP); WDT,
declare!(RNG); RTC1,
declare!(ECB); QDEC,
declare!(CCM_AAR); COMP,
declare!(WDT); SWI0_EGU0,
declare!(RTC1); SWI1_EGU1,
declare!(QDEC); SWI2,
declare!(COMP); SWI3,
declare!(SWI0_EGU0); SWI4,
declare!(SWI1_EGU1); SWI5,
declare!(SWI2); PWM0,
declare!(SWI3); PDM,
declare!(SWI4); );
declare!(SWI5);
declare!(PWM0);
declare!(PDM);
}

View File

@ -224,35 +224,31 @@ impl_ppi_channel!(PPI_CH29, 29 => static);
impl_ppi_channel!(PPI_CH30, 30 => static); impl_ppi_channel!(PPI_CH30, 30 => static);
impl_ppi_channel!(PPI_CH31, 31 => static); impl_ppi_channel!(PPI_CH31, 31 => static);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; POWER_CLOCK,
RADIO,
use crate::pac::Interrupt as InterruptEnum; UARTE0_UART0,
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0,
declare!(POWER_CLOCK); SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1,
declare!(RADIO); GPIOTE,
declare!(UARTE0_UART0); TIMER0,
declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); TIMER1,
declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); TIMER2,
declare!(GPIOTE); RTC0,
declare!(TIMER0); TEMP,
declare!(TIMER1); RNG,
declare!(TIMER2); ECB,
declare!(RTC0); CCM_AAR,
declare!(TEMP); WDT,
declare!(RNG); RTC1,
declare!(ECB); QDEC,
declare!(CCM_AAR); COMP,
declare!(WDT); SWI0_EGU0,
declare!(RTC1); SWI1_EGU1,
declare!(QDEC); SWI2_EGU2,
declare!(COMP); SWI3_EGU3,
declare!(SWI0_EGU0); SWI4_EGU4,
declare!(SWI1_EGU1); SWI5_EGU5,
declare!(SWI2_EGU2); TIMER3,
declare!(SWI3_EGU3); USBD,
declare!(SWI4_EGU4); );
declare!(SWI5_EGU5);
declare!(TIMER3);
declare!(USBD);
}

View File

@ -263,46 +263,42 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
impl_i2s!(I2S, I2S, I2S); impl_i2s!(I2S, I2S, I2S);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; POWER_CLOCK,
RADIO,
use crate::pac::Interrupt as InterruptEnum; UARTE0_UART0,
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0,
declare!(POWER_CLOCK); SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1,
declare!(RADIO); NFCT,
declare!(UARTE0_UART0); GPIOTE,
declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); SAADC,
declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); TIMER0,
declare!(NFCT); TIMER1,
declare!(GPIOTE); TIMER2,
declare!(SAADC); RTC0,
declare!(TIMER0); TEMP,
declare!(TIMER1); RNG,
declare!(TIMER2); ECB,
declare!(RTC0); CCM_AAR,
declare!(TEMP); WDT,
declare!(RNG); RTC1,
declare!(ECB); QDEC,
declare!(CCM_AAR); COMP_LPCOMP,
declare!(WDT); SWI0_EGU0,
declare!(RTC1); SWI1_EGU1,
declare!(QDEC); SWI2_EGU2,
declare!(COMP_LPCOMP); SWI3_EGU3,
declare!(SWI0_EGU0); SWI4_EGU4,
declare!(SWI1_EGU1); SWI5_EGU5,
declare!(SWI2_EGU2); TIMER3,
declare!(SWI3_EGU3); TIMER4,
declare!(SWI4_EGU4); PWM0,
declare!(SWI5_EGU5); PDM,
declare!(TIMER3); MWU,
declare!(TIMER4); PWM1,
declare!(PWM0); PWM2,
declare!(PDM); SPIM2_SPIS2_SPI2,
declare!(MWU); RTC2,
declare!(PWM1); FPU,
declare!(PWM2); I2S,
declare!(SPIM2_SPIS2_SPI2); );
declare!(RTC2);
declare!(FPU);
declare!(I2S);
}

View File

@ -306,50 +306,46 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
impl_i2s!(I2S, I2S, I2S); impl_i2s!(I2S, I2S, I2S);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; POWER_CLOCK,
RADIO,
use crate::pac::Interrupt as InterruptEnum; UARTE0_UART0,
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0,
declare!(POWER_CLOCK); SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1,
declare!(RADIO); NFCT,
declare!(UARTE0_UART0); GPIOTE,
declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); SAADC,
declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); TIMER0,
declare!(NFCT); TIMER1,
declare!(GPIOTE); TIMER2,
declare!(SAADC); RTC0,
declare!(TIMER0); TEMP,
declare!(TIMER1); RNG,
declare!(TIMER2); ECB,
declare!(RTC0); CCM_AAR,
declare!(TEMP); WDT,
declare!(RNG); RTC1,
declare!(ECB); QDEC,
declare!(CCM_AAR); COMP_LPCOMP,
declare!(WDT); SWI0_EGU0,
declare!(RTC1); SWI1_EGU1,
declare!(QDEC); SWI2_EGU2,
declare!(COMP_LPCOMP); SWI3_EGU3,
declare!(SWI0_EGU0); SWI4_EGU4,
declare!(SWI1_EGU1); SWI5_EGU5,
declare!(SWI2_EGU2); TIMER3,
declare!(SWI3_EGU3); TIMER4,
declare!(SWI4_EGU4); PWM0,
declare!(SWI5_EGU5); PDM,
declare!(TIMER3); MWU,
declare!(TIMER4); PWM1,
declare!(PWM0); PWM2,
declare!(PDM); SPIM2_SPIS2_SPI2,
declare!(MWU); RTC2,
declare!(PWM1); FPU,
declare!(PWM2); USBD,
declare!(SPIM2_SPIS2_SPI2); UARTE1,
declare!(RTC2); PWM3,
declare!(FPU); SPIM3,
declare!(USBD); I2S,
declare!(UARTE1); );
declare!(PWM3);
declare!(SPIM3);
declare!(I2S);
}

View File

@ -311,52 +311,48 @@ impl_saadc_input!(P0_31, ANALOG_INPUT7);
impl_i2s!(I2S, I2S, I2S); impl_i2s!(I2S, I2S, I2S);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; POWER_CLOCK,
RADIO,
use crate::pac::Interrupt as InterruptEnum; UARTE0_UART0,
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0,
declare!(POWER_CLOCK); SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1,
declare!(RADIO); NFCT,
declare!(UARTE0_UART0); GPIOTE,
declare!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); SAADC,
declare!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1); TIMER0,
declare!(NFCT); TIMER1,
declare!(GPIOTE); TIMER2,
declare!(SAADC); RTC0,
declare!(TIMER0); TEMP,
declare!(TIMER1); RNG,
declare!(TIMER2); ECB,
declare!(RTC0); CCM_AAR,
declare!(TEMP); WDT,
declare!(RNG); RTC1,
declare!(ECB); QDEC,
declare!(CCM_AAR); COMP_LPCOMP,
declare!(WDT); SWI0_EGU0,
declare!(RTC1); SWI1_EGU1,
declare!(QDEC); SWI2_EGU2,
declare!(COMP_LPCOMP); SWI3_EGU3,
declare!(SWI0_EGU0); SWI4_EGU4,
declare!(SWI1_EGU1); SWI5_EGU5,
declare!(SWI2_EGU2); TIMER3,
declare!(SWI3_EGU3); TIMER4,
declare!(SWI4_EGU4); PWM0,
declare!(SWI5_EGU5); PDM,
declare!(TIMER3); MWU,
declare!(TIMER4); PWM1,
declare!(PWM0); PWM2,
declare!(PDM); SPIM2_SPIS2_SPI2,
declare!(MWU); RTC2,
declare!(PWM1); FPU,
declare!(PWM2); USBD,
declare!(SPIM2_SPIS2_SPI2); UARTE1,
declare!(RTC2); QSPI,
declare!(FPU); CRYPTOCELL,
declare!(USBD); PWM3,
declare!(UARTE1); SPIM3,
declare!(QSPI); I2S,
declare!(CRYPTOCELL); );
declare!(PWM3);
declare!(SPIM3);
declare!(I2S);
}

View File

@ -5,6 +5,8 @@ pub mod pac {
// The nRF5340 has a secure and non-secure (NS) mode. // The nRF5340 has a secure and non-secure (NS) mode.
// To avoid cfg spam, we remove _ns or _s suffixes here. // To avoid cfg spam, we remove _ns or _s suffixes here.
pub use nrf5340_app_pac::NVIC_PRIO_BITS;
#[doc(no_inline)] #[doc(no_inline)]
pub use nrf5340_app_pac::{ pub use nrf5340_app_pac::{
interrupt, interrupt,
@ -504,50 +506,46 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
impl_saadc_input!(P0_19, ANALOG_INPUT6); impl_saadc_input!(P0_19, ANALOG_INPUT6);
impl_saadc_input!(P0_20, ANALOG_INPUT7); impl_saadc_input!(P0_20, ANALOG_INPUT7);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; FPU,
CACHE,
use crate::pac::Interrupt as InterruptEnum; SPU,
CLOCK_POWER,
declare!(FPU); SERIAL0,
declare!(CACHE); SERIAL1,
declare!(SPU); SPIM4,
declare!(CLOCK_POWER); SERIAL2,
declare!(SERIAL0); SERIAL3,
declare!(SERIAL1); GPIOTE0,
declare!(SPIM4); SAADC,
declare!(SERIAL2); TIMER0,
declare!(SERIAL3); TIMER1,
declare!(GPIOTE0); TIMER2,
declare!(SAADC); RTC0,
declare!(TIMER0); RTC1,
declare!(TIMER1); WDT0,
declare!(TIMER2); WDT1,
declare!(RTC0); COMP_LPCOMP,
declare!(RTC1); EGU0,
declare!(WDT0); EGU1,
declare!(WDT1); EGU2,
declare!(COMP_LPCOMP); EGU3,
declare!(EGU0); EGU4,
declare!(EGU1); EGU5,
declare!(EGU2); PWM0,
declare!(EGU3); PWM1,
declare!(EGU4); PWM2,
declare!(EGU5); PWM3,
declare!(PWM0); PDM0,
declare!(PWM1); I2S0,
declare!(PWM2); IPC,
declare!(PWM3); QSPI,
declare!(PDM0); NFCT,
declare!(I2S0); GPIOTE1,
declare!(IPC); QDEC0,
declare!(QSPI); QDEC1,
declare!(NFCT); USBD,
declare!(GPIOTE1); USBREGULATOR,
declare!(QDEC0); KMU,
declare!(QDEC1); CRYPTOCELL,
declare!(USBD); );
declare!(USBREGULATOR);
declare!(KMU);
declare!(CRYPTOCELL);
}

View File

@ -5,6 +5,8 @@ pub mod pac {
// The nRF5340 has a secure and non-secure (NS) mode. // The nRF5340 has a secure and non-secure (NS) mode.
// To avoid cfg spam, we remove _ns or _s suffixes here. // To avoid cfg spam, we remove _ns or _s suffixes here.
pub use nrf5340_net_pac::NVIC_PRIO_BITS;
#[doc(no_inline)] #[doc(no_inline)]
pub use nrf5340_net_pac::{ pub use nrf5340_net_pac::{
interrupt, interrupt,
@ -340,29 +342,25 @@ impl_ppi_channel!(PPI_CH29, 29 => configurable);
impl_ppi_channel!(PPI_CH30, 30 => configurable); impl_ppi_channel!(PPI_CH30, 30 => configurable);
impl_ppi_channel!(PPI_CH31, 31 => configurable); impl_ppi_channel!(PPI_CH31, 31 => configurable);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; CLOCK_POWER,
RADIO,
use crate::pac::Interrupt as InterruptEnum; RNG,
GPIOTE,
declare!(CLOCK_POWER); WDT,
declare!(RADIO); TIMER0,
declare!(RNG); ECB,
declare!(GPIOTE); AAR_CCM,
declare!(WDT); TEMP,
declare!(TIMER0); RTC0,
declare!(ECB); IPC,
declare!(AAR_CCM); SERIAL0,
declare!(TEMP); EGU0,
declare!(RTC0); RTC1,
declare!(IPC); TIMER1,
declare!(SERIAL0); TIMER2,
declare!(EGU0); SWI0,
declare!(RTC1); SWI1,
declare!(TIMER1); SWI2,
declare!(TIMER2); SWI3,
declare!(SWI0); );
declare!(SWI1);
declare!(SWI2);
declare!(SWI3);
}

View File

@ -5,6 +5,8 @@ pub mod pac {
// The nRF9160 has a secure and non-secure (NS) mode. // The nRF9160 has a secure and non-secure (NS) mode.
// To avoid cfg spam, we remove _ns or _s suffixes here. // To avoid cfg spam, we remove _ns or _s suffixes here.
pub use nrf9160_pac::NVIC_PRIO_BITS;
#[doc(no_inline)] #[doc(no_inline)]
pub use nrf9160_pac::{ pub use nrf9160_pac::{
interrupt, interrupt,
@ -366,40 +368,36 @@ impl_saadc_input!(P0_18, ANALOG_INPUT5);
impl_saadc_input!(P0_19, ANALOG_INPUT6); impl_saadc_input!(P0_19, ANALOG_INPUT6);
impl_saadc_input!(P0_20, ANALOG_INPUT7); impl_saadc_input!(P0_20, ANALOG_INPUT7);
pub mod irqs { embassy_hal_common::interrupt_mod!(
use embassy_cortex_m::interrupt::_export::declare; SPU,
CLOCK_POWER,
use crate::pac::Interrupt as InterruptEnum; UARTE0_SPIM0_SPIS0_TWIM0_TWIS0,
UARTE1_SPIM1_SPIS1_TWIM1_TWIS1,
declare!(SPU); UARTE2_SPIM2_SPIS2_TWIM2_TWIS2,
declare!(CLOCK_POWER); UARTE3_SPIM3_SPIS3_TWIM3_TWIS3,
declare!(UARTE0_SPIM0_SPIS0_TWIM0_TWIS0); GPIOTE0,
declare!(UARTE1_SPIM1_SPIS1_TWIM1_TWIS1); SAADC,
declare!(UARTE2_SPIM2_SPIS2_TWIM2_TWIS2); TIMER0,
declare!(UARTE3_SPIM3_SPIS3_TWIM3_TWIS3); TIMER1,
declare!(GPIOTE0); TIMER2,
declare!(SAADC); RTC0,
declare!(TIMER0); RTC1,
declare!(TIMER1); WDT,
declare!(TIMER2); EGU0,
declare!(RTC0); EGU1,
declare!(RTC1); EGU2,
declare!(WDT); EGU3,
declare!(EGU0); EGU4,
declare!(EGU1); EGU5,
declare!(EGU2); PWM0,
declare!(EGU3); PWM1,
declare!(EGU4); PWM2,
declare!(EGU5); PDM,
declare!(PWM0); PWM3,
declare!(PWM1); I2S,
declare!(PWM2); IPC,
declare!(PDM); FPU,
declare!(PWM3); GPIOTE1,
declare!(I2S); KMU,
declare!(IPC); CRYPTOCELL,
declare!(FPU); );
declare!(GPIOTE1);
declare!(KMU);
declare!(CRYPTOCELL);
}

View File

@ -9,7 +9,7 @@ use embassy_sync::waitqueue::AtomicWaker;
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin}; use crate::gpio::{AnyPin, Flex, Input, Output, Pin as GpioPin};
use crate::interrupt::Interrupt; use crate::interrupt::InterruptExt;
use crate::ppi::{Event, Task}; use crate::ppi::{Event, Task};
use crate::{interrupt, pac, peripherals}; use crate::{interrupt, pac, peripherals};
@ -75,15 +75,15 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) {
// Enable interrupts // Enable interrupts
#[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s"))] #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s"))]
type Irq = interrupt::GPIOTE0; let irq = interrupt::GPIOTE0;
#[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns"))] #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns"))]
type Irq = interrupt::GPIOTE1; let irq = interrupt::GPIOTE1;
#[cfg(any(feature = "_nrf52", feature = "nrf5340-net"))] #[cfg(any(feature = "_nrf52", feature = "nrf5340-net"))]
type Irq = interrupt::GPIOTE; let irq = interrupt::GPIOTE;
Irq::unpend(); irq.unpend();
Irq::set_priority(irq_prio); irq.set_priority(irq_prio);
unsafe { Irq::enable() }; unsafe { irq.enable() };
let g = regs(); let g = regs();
g.events_port.write(|w| w); g.events_port.write(|w| w);
@ -91,18 +91,21 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) {
} }
#[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s"))] #[cfg(any(feature = "nrf5340-app-s", feature = "nrf9160-s"))]
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn GPIOTE0() { fn GPIOTE0() {
unsafe { handle_gpiote_interrupt() }; unsafe { handle_gpiote_interrupt() };
} }
#[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns"))] #[cfg(any(feature = "nrf5340-app-ns", feature = "nrf9160-ns"))]
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn GPIOTE1() { fn GPIOTE1() {
unsafe { handle_gpiote_interrupt() }; unsafe { handle_gpiote_interrupt() };
} }
#[cfg(any(feature = "_nrf52", feature = "nrf5340-net"))] #[cfg(any(feature = "_nrf52", feature = "nrf5340-net"))]
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn GPIOTE() { fn GPIOTE() {
unsafe { handle_gpiote_interrupt() }; unsafe { handle_gpiote_interrupt() };

View File

@ -13,10 +13,10 @@ use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use crate::gpio::{AnyPin, Pin as GpioPin}; use crate::gpio::{AnyPin, Pin as GpioPin};
use crate::interrupt::{self, Interrupt}; use crate::interrupt::typelevel::Interrupt;
use crate::pac::i2s::RegisterBlock; use crate::pac::i2s::RegisterBlock;
use crate::util::{slice_in_ram_or, slice_ptr_parts}; use crate::util::{slice_in_ram_or, slice_ptr_parts};
use crate::{Peripheral, EASY_DMA_SIZE}; use crate::{interrupt, Peripheral, EASY_DMA_SIZE};
/// Type alias for `MultiBuffering` with 2 buffers. /// Type alias for `MultiBuffering` with 2 buffers.
pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>; pub type DoubleBuffering<S, const NS: usize> = MultiBuffering<S, 2, NS>;
@ -367,7 +367,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let device = Device::<T>::new(); let device = Device::<T>::new();
let s = T::state(); let s = T::state();
@ -408,7 +408,7 @@ impl<'d, T: Instance> I2S<'d, T> {
/// Create a new I2S in master mode /// Create a new I2S in master mode
pub fn new_master( pub fn new_master(
i2s: impl Peripheral<P = T> + 'd, i2s: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
mck: impl Peripheral<P = impl GpioPin> + 'd, mck: impl Peripheral<P = impl GpioPin> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: impl Peripheral<P = impl GpioPin> + 'd,
lrck: impl Peripheral<P = impl GpioPin> + 'd, lrck: impl Peripheral<P = impl GpioPin> + 'd,
@ -431,7 +431,7 @@ impl<'d, T: Instance> I2S<'d, T> {
/// Create a new I2S in slave mode /// Create a new I2S in slave mode
pub fn new_slave( pub fn new_slave(
i2s: impl Peripheral<P = T> + 'd, i2s: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: impl Peripheral<P = impl GpioPin> + 'd,
lrck: impl Peripheral<P = impl GpioPin> + 'd, lrck: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -1173,7 +1173,7 @@ pub(crate) mod sealed {
/// I2S peripheral instance. /// I2S peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_i2s { macro_rules! impl_i2s {
@ -1188,7 +1188,7 @@ macro_rules! impl_i2s {
} }
} }
impl crate::i2s::Instance for peripherals::$type { impl crate::i2s::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -93,21 +93,14 @@ pub mod wdt;
#[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")] #[cfg_attr(feature = "_nrf9160", path = "chips/nrf9160.rs")]
mod chip; mod chip;
pub mod interrupt { /// Macro to bind interrupts to handlers.
//! Interrupt definitions and macros to bind them. ///
pub use cortex_m::interrupt::{CriticalSection, Mutex}; /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
pub use embassy_cortex_m::interrupt::{Binding, Handler, Interrupt, Priority}; /// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
/// prove at compile-time that the right interrupts have been bound.
pub use crate::chip::irqs::*; // developer note: this macro can't be in `embassy-hal-common` due to the use of `$crate`.
#[macro_export]
/// Macro to bind interrupts to handlers. macro_rules! bind_interrupts {
///
/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
/// prove at compile-time that the right interrupts have been bound.
// developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`.
#[macro_export]
macro_rules! bind_interrupts {
($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
$vis struct $name; $vis struct $name;
@ -116,17 +109,16 @@ pub mod interrupt {
#[no_mangle] #[no_mangle]
unsafe extern "C" fn $irq() { unsafe extern "C" fn $irq() {
$( $(
<$handler as $crate::interrupt::Handler<$crate::interrupt::$irq>>::on_interrupt(); <$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt();
)* )*
} }
$( $(
unsafe impl $crate::interrupt::Binding<$crate::interrupt::$irq, $handler> for $name {} unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {}
)* )*
)* )*
}; };
} }
}
// Reexports // Reexports
@ -135,10 +127,11 @@ pub use chip::pac;
#[cfg(not(feature = "unstable-pac"))] #[cfg(not(feature = "unstable-pac"))]
pub(crate) use chip::pac; pub(crate) use chip::pac;
pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE}; pub use chip::{peripherals, Peripherals, EASY_DMA_SIZE};
pub use embassy_cortex_m::executor;
pub use embassy_cortex_m::interrupt::_export::interrupt;
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
pub use crate::chip::interrupt;
pub use crate::pac::NVIC_PRIO_BITS;
pub mod config { pub mod config {
//! Configuration options used when initializing the HAL. //! Configuration options used when initializing the HAL.

View File

@ -6,7 +6,6 @@ use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::drop::OnDrop; use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use futures::future::poll_fn; use futures::future::poll_fn;
@ -14,15 +13,15 @@ use futures::future::poll_fn;
use crate::chip::EASY_DMA_SIZE; use crate::chip::EASY_DMA_SIZE;
use crate::gpio::sealed::Pin; use crate::gpio::sealed::Pin;
use crate::gpio::{AnyPin, Pin as GpioPin}; use crate::gpio::{AnyPin, Pin as GpioPin};
use crate::interrupt::{self}; use crate::interrupt::typelevel::Interrupt;
use crate::Peripheral; use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
pub struct InterruptHandler<T: Instance> { pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
T::regs().intenclr.write(|w| w.end().clear()); T::regs().intenclr.write(|w| w.end().clear());
T::state().waker.wake(); T::state().waker.wake();
@ -53,7 +52,7 @@ impl<'d, T: Instance> Pdm<'d, T> {
/// Create PDM driver /// Create PDM driver
pub fn new( pub fn new(
pdm: impl Peripheral<P = T> + 'd, pdm: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
clk: impl Peripheral<P = impl GpioPin> + 'd, clk: impl Peripheral<P = impl GpioPin> + 'd,
din: impl Peripheral<P = impl GpioPin> + 'd, din: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -274,7 +273,7 @@ pub(crate) mod sealed {
/// PDM peripheral instance. /// PDM peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_pdm { macro_rules! impl_pdm {
@ -289,7 +288,7 @@ macro_rules! impl_pdm {
} }
} }
impl crate::pdm::Instance for peripherals::$type { impl crate::pdm::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -8,10 +8,9 @@ use embassy_hal_common::{into_ref, PeripheralRef};
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{AnyPin, Pin as GpioPin, PselBits}; use crate::gpio::{AnyPin, Pin as GpioPin, PselBits};
use crate::interrupt::Interrupt;
use crate::ppi::{Event, Task}; use crate::ppi::{Event, Task};
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::{pac, Peripheral}; use crate::{interrupt, pac, Peripheral};
/// SimplePwm is the traditional pwm interface you're probably used to, allowing /// SimplePwm is the traditional pwm interface you're probably used to, allowing
/// to simply set a duty cycle across up to four channels. /// to simply set a duty cycle across up to four channels.
@ -843,7 +842,7 @@ pub(crate) mod sealed {
/// PWM peripheral instance. /// PWM peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_pwm { macro_rules! impl_pwm {
@ -854,7 +853,7 @@ macro_rules! impl_pwm {
} }
} }
impl crate::pwm::Instance for peripherals::$type { impl crate::pwm::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -10,7 +10,7 @@ use embassy_hal_common::{into_ref, PeripheralRef};
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{AnyPin, Pin as GpioPin}; use crate::gpio::{AnyPin, Pin as GpioPin};
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
/// Quadrature decoder driver. /// Quadrature decoder driver.
@ -50,7 +50,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
T::regs().intenclr.write(|w| w.reportrdy().clear()); T::regs().intenclr.write(|w| w.reportrdy().clear());
T::state().waker.wake(); T::state().waker.wake();
@ -61,7 +61,7 @@ impl<'d, T: Instance> Qdec<'d, T> {
/// Create a new QDEC. /// Create a new QDEC.
pub fn new( pub fn new(
qdec: impl Peripheral<P = T> + 'd, qdec: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
a: impl Peripheral<P = impl GpioPin> + 'd, a: impl Peripheral<P = impl GpioPin> + 'd,
b: impl Peripheral<P = impl GpioPin> + 'd, b: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -73,7 +73,7 @@ impl<'d, T: Instance> Qdec<'d, T> {
/// Create a new QDEC, with a pin for LED output. /// Create a new QDEC, with a pin for LED output.
pub fn new_with_led( pub fn new_with_led(
qdec: impl Peripheral<P = T> + 'd, qdec: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
a: impl Peripheral<P = impl GpioPin> + 'd, a: impl Peripheral<P = impl GpioPin> + 'd,
b: impl Peripheral<P = impl GpioPin> + 'd, b: impl Peripheral<P = impl GpioPin> + 'd,
led: impl Peripheral<P = impl GpioPin> + 'd, led: impl Peripheral<P = impl GpioPin> + 'd,
@ -271,7 +271,7 @@ pub(crate) mod sealed {
/// qdec peripheral instance. /// qdec peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_qdec { macro_rules! impl_qdec {
@ -286,7 +286,7 @@ macro_rules! impl_qdec {
} }
} }
impl crate::qdec::Instance for peripherals::$type { impl crate::qdec::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -12,12 +12,12 @@ use embassy_hal_common::{into_ref, PeripheralRef};
use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash}; use embedded_storage::nor_flash::{ErrorType, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash};
use crate::gpio::{self, Pin as GpioPin}; use crate::gpio::{self, Pin as GpioPin};
use crate::interrupt::{self, Interrupt}; use crate::interrupt::typelevel::Interrupt;
pub use crate::pac::qspi::ifconfig0::{ pub use crate::pac::qspi::ifconfig0::{
ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode, ADDRMODE_A as AddressMode, PPSIZE_A as WritePageSize, READOC_A as ReadOpcode, WRITEOC_A as WriteOpcode,
}; };
pub use crate::pac::qspi::ifconfig1::SPIMODE_A as SpiMode; pub use crate::pac::qspi::ifconfig1::SPIMODE_A as SpiMode;
use crate::Peripheral; use crate::{interrupt, Peripheral};
/// Deep power-down config. /// Deep power-down config.
pub struct DeepPowerDownConfig { pub struct DeepPowerDownConfig {
@ -120,7 +120,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = T::regs(); let r = T::regs();
let s = T::state(); let s = T::state();
@ -143,7 +143,7 @@ impl<'d, T: Instance> Qspi<'d, T> {
/// Create a new QSPI driver. /// Create a new QSPI driver.
pub fn new( pub fn new(
qspi: impl Peripheral<P = T> + 'd, qspi: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: impl Peripheral<P = impl GpioPin> + 'd,
csn: impl Peripheral<P = impl GpioPin> + 'd, csn: impl Peripheral<P = impl GpioPin> + 'd,
io0: impl Peripheral<P = impl GpioPin> + 'd, io0: impl Peripheral<P = impl GpioPin> + 'd,
@ -644,7 +644,7 @@ pub(crate) mod sealed {
/// QSPI peripheral instance. /// QSPI peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_qspi { macro_rules! impl_qspi {
@ -659,7 +659,7 @@ macro_rules! impl_qspi {
} }
} }
impl crate::qspi::Instance for peripherals::$type { impl crate::qspi::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -12,7 +12,7 @@ use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
@ -20,7 +20,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let s = T::state(); let s = T::state();
let r = T::regs(); let r = T::regs();
@ -89,7 +89,7 @@ impl<'d, T: Instance> Rng<'d, T> {
/// The synchronous API is safe. /// The synchronous API is safe.
pub fn new( pub fn new(
rng: impl Peripheral<P = T> + 'd, rng: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
) -> Self { ) -> Self {
into_ref!(rng); into_ref!(rng);
@ -255,7 +255,7 @@ pub(crate) mod sealed {
/// RNG peripheral instance. /// RNG peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_rng { macro_rules! impl_rng {
@ -270,7 +270,7 @@ macro_rules! impl_rng {
} }
} }
impl crate::rng::Instance for peripherals::$type { impl crate::rng::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -6,7 +6,6 @@ use core::future::poll_fn;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::drop::OnDrop; use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -18,6 +17,7 @@ use saadc::oversample::OVERSAMPLE_A;
use saadc::resolution::VAL_A; use saadc::resolution::VAL_A;
use self::sealed::Input as _; use self::sealed::Input as _;
use crate::interrupt::InterruptExt;
use crate::ppi::{ConfigurableChannel, Event, Ppi, Task}; use crate::ppi::{ConfigurableChannel, Event, Ppi, Task};
use crate::timer::{Frequency, Instance as TimerInstance, Timer}; use crate::timer::{Frequency, Instance as TimerInstance, Timer};
use crate::{interrupt, pac, peripherals, Peripheral}; use crate::{interrupt, pac, peripherals, Peripheral};
@ -33,7 +33,7 @@ pub struct InterruptHandler {
_private: (), _private: (),
} }
impl interrupt::Handler<interrupt::SAADC> for InterruptHandler { impl interrupt::typelevel::Handler<interrupt::typelevel::SAADC> for InterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = unsafe { &*SAADC::ptr() }; let r = unsafe { &*SAADC::ptr() };
@ -144,7 +144,7 @@ impl<'d, const N: usize> Saadc<'d, N> {
/// Create a new SAADC driver. /// Create a new SAADC driver.
pub fn new( pub fn new(
saadc: impl Peripheral<P = peripherals::SAADC> + 'd, saadc: impl Peripheral<P = peripherals::SAADC> + 'd,
_irq: impl interrupt::Binding<interrupt::SAADC, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::SAADC, InterruptHandler> + 'd,
config: Config, config: Config,
channel_configs: [ChannelConfig; N], channel_configs: [ChannelConfig; N],
) -> Self { ) -> Self {
@ -189,8 +189,8 @@ impl<'d, const N: usize> Saadc<'d, N> {
// Disable all events interrupts // Disable all events interrupts
r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) }); r.intenclr.write(|w| unsafe { w.bits(0x003F_FFFF) });
interrupt::SAADC::unpend(); interrupt::SAADC.unpend();
unsafe { interrupt::SAADC::enable() }; unsafe { interrupt::SAADC.enable() };
Self { _p: saadc } Self { _p: saadc }
} }

View File

@ -15,9 +15,9 @@ pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
use crate::chip::FORCE_COPY_BUFFER_SIZE; use crate::chip::FORCE_COPY_BUFFER_SIZE;
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
use crate::interrupt::{self, Interrupt}; use crate::interrupt::typelevel::Interrupt;
use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut};
use crate::{pac, Peripheral}; use crate::{interrupt, pac, Peripheral};
/// SPIM error /// SPIM error
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -63,7 +63,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = T::regs(); let r = T::regs();
let s = T::state(); let s = T::state();
@ -84,7 +84,7 @@ impl<'d, T: Instance> Spim<'d, T> {
/// Create a new SPIM driver. /// Create a new SPIM driver.
pub fn new( pub fn new(
spim: impl Peripheral<P = T> + 'd, spim: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: impl Peripheral<P = impl GpioPin> + 'd,
miso: impl Peripheral<P = impl GpioPin> + 'd, miso: impl Peripheral<P = impl GpioPin> + 'd,
mosi: impl Peripheral<P = impl GpioPin> + 'd, mosi: impl Peripheral<P = impl GpioPin> + 'd,
@ -103,7 +103,7 @@ impl<'d, T: Instance> Spim<'d, T> {
/// Create a new SPIM driver, capable of TX only (MOSI only). /// Create a new SPIM driver, capable of TX only (MOSI only).
pub fn new_txonly( pub fn new_txonly(
spim: impl Peripheral<P = T> + 'd, spim: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: impl Peripheral<P = impl GpioPin> + 'd,
mosi: impl Peripheral<P = impl GpioPin> + 'd, mosi: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -115,7 +115,7 @@ impl<'d, T: Instance> Spim<'d, T> {
/// Create a new SPIM driver, capable of RX only (MISO only). /// Create a new SPIM driver, capable of RX only (MISO only).
pub fn new_rxonly( pub fn new_rxonly(
spim: impl Peripheral<P = T> + 'd, spim: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: impl Peripheral<P = impl GpioPin> + 'd,
miso: impl Peripheral<P = impl GpioPin> + 'd, miso: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -408,7 +408,7 @@ pub(crate) mod sealed {
/// SPIM peripheral instance /// SPIM peripheral instance
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_spim { macro_rules! impl_spim {
@ -423,7 +423,7 @@ macro_rules! impl_spim {
} }
} }
impl crate::spim::Instance for peripherals::$type { impl crate::spim::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -13,9 +13,9 @@ pub use embedded_hal_02::spi::{Mode, Phase, Polarity, MODE_0, MODE_1, MODE_2, MO
use crate::chip::FORCE_COPY_BUFFER_SIZE; use crate::chip::FORCE_COPY_BUFFER_SIZE;
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{self, AnyPin, Pin as GpioPin}; use crate::gpio::{self, AnyPin, Pin as GpioPin};
use crate::interrupt::{self, Interrupt}; use crate::interrupt::typelevel::Interrupt;
use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut}; use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut};
use crate::{pac, Peripheral}; use crate::{interrupt, pac, Peripheral};
/// SPIS error /// SPIS error
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -68,7 +68,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = T::regs(); let r = T::regs();
let s = T::state(); let s = T::state();
@ -94,7 +94,7 @@ impl<'d, T: Instance> Spis<'d, T> {
/// Create a new SPIS driver. /// Create a new SPIS driver.
pub fn new( pub fn new(
spis: impl Peripheral<P = T> + 'd, spis: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
cs: impl Peripheral<P = impl GpioPin> + 'd, cs: impl Peripheral<P = impl GpioPin> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: impl Peripheral<P = impl GpioPin> + 'd,
miso: impl Peripheral<P = impl GpioPin> + 'd, miso: impl Peripheral<P = impl GpioPin> + 'd,
@ -115,7 +115,7 @@ impl<'d, T: Instance> Spis<'d, T> {
/// Create a new SPIS driver, capable of TX only (MISO only). /// Create a new SPIS driver, capable of TX only (MISO only).
pub fn new_txonly( pub fn new_txonly(
spis: impl Peripheral<P = T> + 'd, spis: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
cs: impl Peripheral<P = impl GpioPin> + 'd, cs: impl Peripheral<P = impl GpioPin> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: impl Peripheral<P = impl GpioPin> + 'd,
miso: impl Peripheral<P = impl GpioPin> + 'd, miso: impl Peripheral<P = impl GpioPin> + 'd,
@ -128,7 +128,7 @@ impl<'d, T: Instance> Spis<'d, T> {
/// Create a new SPIS driver, capable of RX only (MOSI only). /// Create a new SPIS driver, capable of RX only (MOSI only).
pub fn new_rxonly( pub fn new_rxonly(
spis: impl Peripheral<P = T> + 'd, spis: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
cs: impl Peripheral<P = impl GpioPin> + 'd, cs: impl Peripheral<P = impl GpioPin> + 'd,
sck: impl Peripheral<P = impl GpioPin> + 'd, sck: impl Peripheral<P = impl GpioPin> + 'd,
mosi: impl Peripheral<P = impl GpioPin> + 'd, mosi: impl Peripheral<P = impl GpioPin> + 'd,
@ -480,7 +480,7 @@ pub(crate) mod sealed {
/// SPIS peripheral instance /// SPIS peripheral instance
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_spis { macro_rules! impl_spis {
@ -495,7 +495,7 @@ macro_rules! impl_spis {
} }
} }
impl crate::spis::Instance for peripherals::$type { impl crate::spis::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -8,7 +8,7 @@ use embassy_hal_common::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use fixed::types::I30F2; use fixed::types::I30F2;
use crate::interrupt::Interrupt; use crate::interrupt::InterruptExt;
use crate::peripherals::TEMP; use crate::peripherals::TEMP;
use crate::{interrupt, pac, Peripheral}; use crate::{interrupt, pac, Peripheral};
@ -17,7 +17,7 @@ pub struct InterruptHandler {
_private: (), _private: (),
} }
impl interrupt::Handler<interrupt::TEMP> for InterruptHandler { impl interrupt::typelevel::Handler<interrupt::typelevel::TEMP> for InterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = unsafe { &*pac::TEMP::PTR }; let r = unsafe { &*pac::TEMP::PTR };
r.intenclr.write(|w| w.datardy().clear()); r.intenclr.write(|w| w.datardy().clear());
@ -36,13 +36,13 @@ impl<'d> Temp<'d> {
/// Create a new temperature sensor driver. /// Create a new temperature sensor driver.
pub fn new( pub fn new(
_peri: impl Peripheral<P = TEMP> + 'd, _peri: impl Peripheral<P = TEMP> + 'd,
_irq: impl interrupt::Binding<interrupt::TEMP, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::TEMP, InterruptHandler> + 'd,
) -> Self { ) -> Self {
into_ref!(_peri); into_ref!(_peri);
// Enable interrupt that signals temperature values // Enable interrupt that signals temperature values
interrupt::TEMP::unpend(); interrupt::TEMP.unpend();
unsafe { interrupt::TEMP::enable() }; unsafe { interrupt::TEMP.enable() };
Self { _peri } Self { _peri }
} }

View File

@ -7,7 +7,7 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex; use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex;
use embassy_time::driver::{AlarmHandle, Driver}; use embassy_time::driver::{AlarmHandle, Driver};
use crate::interrupt::Interrupt; use crate::interrupt::InterruptExt;
use crate::{interrupt, pac}; use crate::{interrupt, pac};
fn rtc() -> &'static pac::rtc0::RegisterBlock { fn rtc() -> &'static pac::rtc0::RegisterBlock {
@ -142,8 +142,8 @@ impl RtcDriver {
// Wait for clear // Wait for clear
while r.counter.read().bits() != 0 {} while r.counter.read().bits() != 0 {}
interrupt::RTC1::set_priority(irq_prio); interrupt::RTC1.set_priority(irq_prio);
unsafe { interrupt::RTC1::enable() }; unsafe { interrupt::RTC1.enable() };
} }
fn on_interrupt(&self) { fn on_interrupt(&self) {
@ -295,6 +295,7 @@ impl Driver for RtcDriver {
} }
} }
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn RTC1() { fn RTC1() {
DRIVER.on_interrupt() DRIVER.on_interrupt()

View File

@ -8,7 +8,6 @@
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use crate::interrupt::Interrupt;
use crate::ppi::{Event, Task}; use crate::ppi::{Event, Task};
use crate::{pac, Peripheral}; use crate::{pac, Peripheral};
@ -29,7 +28,7 @@ pub(crate) mod sealed {
/// Basic Timer instance. /// Basic Timer instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: crate::interrupt::typelevel::Interrupt;
} }
/// Extended timer instance. /// Extended timer instance.
@ -44,7 +43,7 @@ macro_rules! impl_timer {
} }
} }
impl crate::timer::Instance for peripherals::$type { impl crate::timer::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
($type:ident, $pac_type:ident, $irq:ident) => { ($type:ident, $pac_type:ident, $irq:ident) => {

View File

@ -16,9 +16,9 @@ use embassy_time::{Duration, Instant};
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
use crate::gpio::Pin as GpioPin; use crate::gpio::Pin as GpioPin;
use crate::interrupt::{self, Interrupt}; use crate::interrupt::typelevel::Interrupt;
use crate::util::{slice_in_ram, slice_in_ram_or}; use crate::util::{slice_in_ram, slice_in_ram_or};
use crate::{gpio, pac, Peripheral}; use crate::{gpio, interrupt, pac, Peripheral};
/// TWI frequency /// TWI frequency
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -98,7 +98,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = T::regs(); let r = T::regs();
let s = T::state(); let s = T::state();
@ -123,7 +123,7 @@ impl<'d, T: Instance> Twim<'d, T> {
/// Create a new TWI driver. /// Create a new TWI driver.
pub fn new( pub fn new(
twim: impl Peripheral<P = T> + 'd, twim: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sda: impl Peripheral<P = impl GpioPin> + 'd, sda: impl Peripheral<P = impl GpioPin> + 'd,
scl: impl Peripheral<P = impl GpioPin> + 'd, scl: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -750,7 +750,7 @@ pub(crate) mod sealed {
/// TWIM peripheral instance. /// TWIM peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_twim { macro_rules! impl_twim {
@ -765,7 +765,7 @@ macro_rules! impl_twim {
} }
} }
impl crate::twim::Instance for peripherals::$type { impl crate::twim::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -15,9 +15,9 @@ use embassy_time::{Duration, Instant};
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
use crate::gpio::Pin as GpioPin; use crate::gpio::Pin as GpioPin;
use crate::interrupt::{self, Interrupt}; use crate::interrupt::typelevel::Interrupt;
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::{gpio, pac, Peripheral}; use crate::{gpio, interrupt, pac, Peripheral};
/// TWIS config. /// TWIS config.
#[non_exhaustive] #[non_exhaustive]
@ -114,7 +114,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = T::regs(); let r = T::regs();
let s = T::state(); let s = T::state();
@ -143,7 +143,7 @@ impl<'d, T: Instance> Twis<'d, T> {
/// Create a new TWIS driver. /// Create a new TWIS driver.
pub fn new( pub fn new(
twis: impl Peripheral<P = T> + 'd, twis: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
sda: impl Peripheral<P = impl GpioPin> + 'd, sda: impl Peripheral<P = impl GpioPin> + 'd,
scl: impl Peripheral<P = impl GpioPin> + 'd, scl: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -778,7 +778,7 @@ pub(crate) mod sealed {
/// TWIS peripheral instance. /// TWIS peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_twis { macro_rules! impl_twis {
@ -793,7 +793,7 @@ macro_rules! impl_twis {
} }
} }
impl crate::twis::Instance for peripherals::$type { impl crate::twis::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -27,11 +27,11 @@ pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Pari
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE}; use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
use crate::gpio::sealed::Pin as _; use crate::gpio::sealed::Pin as _;
use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits}; use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
use crate::interrupt::{self, Interrupt}; use crate::interrupt::typelevel::Interrupt;
use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task}; use crate::ppi::{AnyConfigurableChannel, ConfigurableChannel, Event, Ppi, Task};
use crate::timer::{Frequency, Instance as TimerInstance, Timer}; use crate::timer::{Frequency, Instance as TimerInstance, Timer};
use crate::util::slice_in_ram_or; use crate::util::slice_in_ram_or;
use crate::{pac, Peripheral}; use crate::{interrupt, pac, Peripheral};
/// UARTE config. /// UARTE config.
#[derive(Clone)] #[derive(Clone)]
@ -68,7 +68,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = T::regs(); let r = T::regs();
let s = T::state(); let s = T::state();
@ -108,7 +108,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
/// Create a new UARTE without hardware flow control /// Create a new UARTE without hardware flow control
pub fn new( pub fn new(
uarte: impl Peripheral<P = T> + 'd, uarte: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: impl Peripheral<P = impl GpioPin> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -120,7 +120,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
/// Create a new UARTE with hardware flow control (RTS/CTS) /// Create a new UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts( pub fn new_with_rtscts(
uarte: impl Peripheral<P = T> + 'd, uarte: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: impl Peripheral<P = impl GpioPin> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: impl Peripheral<P = impl GpioPin> + 'd,
cts: impl Peripheral<P = impl GpioPin> + 'd, cts: impl Peripheral<P = impl GpioPin> + 'd,
@ -313,7 +313,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
/// Create a new tx-only UARTE without hardware flow control /// Create a new tx-only UARTE without hardware flow control
pub fn new( pub fn new(
uarte: impl Peripheral<P = T> + 'd, uarte: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
@ -324,7 +324,7 @@ impl<'d, T: Instance> UarteTx<'d, T> {
/// Create a new tx-only UARTE with hardware flow control (RTS/CTS) /// Create a new tx-only UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts( pub fn new_with_rtscts(
uarte: impl Peripheral<P = T> + 'd, uarte: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
txd: impl Peripheral<P = impl GpioPin> + 'd, txd: impl Peripheral<P = impl GpioPin> + 'd,
cts: impl Peripheral<P = impl GpioPin> + 'd, cts: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -509,7 +509,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
/// Create a new rx-only UARTE without hardware flow control /// Create a new rx-only UARTE without hardware flow control
pub fn new( pub fn new(
uarte: impl Peripheral<P = T> + 'd, uarte: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
) -> Self { ) -> Self {
@ -520,7 +520,7 @@ impl<'d, T: Instance> UarteRx<'d, T> {
/// Create a new rx-only UARTE with hardware flow control (RTS/CTS) /// Create a new rx-only UARTE with hardware flow control (RTS/CTS)
pub fn new_with_rtscts( pub fn new_with_rtscts(
uarte: impl Peripheral<P = T> + 'd, uarte: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rxd: impl Peripheral<P = impl GpioPin> + 'd, rxd: impl Peripheral<P = impl GpioPin> + 'd,
rts: impl Peripheral<P = impl GpioPin> + 'd, rts: impl Peripheral<P = impl GpioPin> + 'd,
config: Config, config: Config,
@ -889,7 +889,7 @@ pub(crate) mod sealed {
/// UARTE peripheral instance. /// UARTE peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_uarte { macro_rules! impl_uarte {
@ -908,7 +908,7 @@ macro_rules! impl_uarte {
} }
} }
impl crate::uarte::Instance for peripherals::$type { impl crate::uarte::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -18,9 +18,9 @@ use embassy_usb_driver::{Direction, EndpointAddress, EndpointError, EndpointInfo
use pac::usbd::RegisterBlock; use pac::usbd::RegisterBlock;
use self::vbus_detect::VbusDetect; use self::vbus_detect::VbusDetect;
use crate::interrupt::{self, Interrupt}; use crate::interrupt::typelevel::Interrupt;
use crate::util::slice_in_ram; use crate::util::slice_in_ram;
use crate::{pac, Peripheral}; use crate::{interrupt, pac, Peripheral};
const NEW_AW: AtomicWaker = AtomicWaker::new(); const NEW_AW: AtomicWaker = AtomicWaker::new();
static BUS_WAKER: AtomicWaker = NEW_AW; static BUS_WAKER: AtomicWaker = NEW_AW;
@ -34,7 +34,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let regs = T::regs(); let regs = T::regs();
@ -98,7 +98,7 @@ impl<'d, T: Instance, V: VbusDetect> Driver<'d, T, V> {
/// Create a new USB driver. /// Create a new USB driver.
pub fn new( pub fn new(
usb: impl Peripheral<P = T> + 'd, usb: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
vbus_detect: V, vbus_detect: V,
) -> Self { ) -> Self {
into_ref!(usb); into_ref!(usb);
@ -804,7 +804,7 @@ pub(crate) mod sealed {
/// USB peripheral instance. /// USB peripheral instance.
pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send { pub trait Instance: Peripheral<P = Self> + sealed::Instance + 'static + Send {
/// Interrupt for this peripheral. /// Interrupt for this peripheral.
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
macro_rules! impl_usb { macro_rules! impl_usb {
@ -815,7 +815,7 @@ macro_rules! impl_usb {
} }
} }
impl crate::usb::Instance for peripherals::$type { impl crate::usb::Instance for peripherals::$type {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -7,8 +7,8 @@ use core::task::Poll;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use super::BUS_WAKER; use super::BUS_WAKER;
use crate::interrupt::{self, Interrupt}; use crate::interrupt::typelevel::Interrupt;
use crate::pac; use crate::{interrupt, pac};
/// Trait for detecting USB VBUS power. /// Trait for detecting USB VBUS power.
/// ///
@ -29,9 +29,9 @@ pub trait VbusDetect {
} }
#[cfg(not(feature = "_nrf5340"))] #[cfg(not(feature = "_nrf5340"))]
type UsbRegIrq = interrupt::POWER_CLOCK; type UsbRegIrq = interrupt::typelevel::POWER_CLOCK;
#[cfg(feature = "_nrf5340")] #[cfg(feature = "_nrf5340")]
type UsbRegIrq = interrupt::USBREGULATOR; type UsbRegIrq = interrupt::typelevel::USBREGULATOR;
#[cfg(not(feature = "_nrf5340"))] #[cfg(not(feature = "_nrf5340"))]
type UsbRegPeri = pac::POWER; type UsbRegPeri = pac::POWER;
@ -43,7 +43,7 @@ pub struct InterruptHandler {
_private: (), _private: (),
} }
impl interrupt::Handler<UsbRegIrq> for InterruptHandler { impl interrupt::typelevel::Handler<UsbRegIrq> for InterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let regs = unsafe { &*UsbRegPeri::ptr() }; let regs = unsafe { &*UsbRegPeri::ptr() };
@ -77,7 +77,7 @@ static POWER_WAKER: AtomicWaker = AtomicWaker::new();
impl HardwareVbusDetect { impl HardwareVbusDetect {
/// Create a new `VbusDetectNative`. /// Create a new `VbusDetectNative`.
pub fn new(_irq: impl interrupt::Binding<UsbRegIrq, InterruptHandler> + 'static) -> Self { pub fn new(_irq: impl interrupt::typelevel::Binding<UsbRegIrq, InterruptHandler> + 'static) -> Self {
let regs = unsafe { &*UsbRegPeri::ptr() }; let regs = unsafe { &*UsbRegPeri::ptr() };
UsbRegIrq::unpend(); UsbRegIrq::unpend();

View File

@ -13,7 +13,8 @@ flavors = [
] ]
[features] [features]
default = [ "rp-pac/rt" ] default = [ "rt" ]
rt = [ "rp-pac/rt" ]
defmt = ["dep:defmt", "embassy-usb-driver?/defmt", "embassy-hal-common/defmt"] defmt = ["dep:defmt", "embassy-usb-driver?/defmt", "embassy-hal-common/defmt"]
@ -47,7 +48,7 @@ boot2-w25x10cl = []
run-from-ram = [] run-from-ram = []
# Enable nightly-only features # Enable nightly-only features
nightly = ["embassy-executor/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"] nightly = ["embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"]
# Implement embedded-hal 1.0 alpha traits. # Implement embedded-hal 1.0 alpha traits.
# Implement embedded-hal-async traits if `nightly` is set as well. # Implement embedded-hal-async traits if `nightly` is set as well.
@ -55,11 +56,9 @@ unstable-traits = ["embedded-hal-1", "embedded-hal-nb"]
[dependencies] [dependencies]
embassy-sync = { version = "0.2.0", path = "../embassy-sync" } embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
embassy-executor = { version = "0.2.0", path = "../embassy-executor" }
embassy-time = { version = "0.1.0", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] } embassy-time = { version = "0.1.0", path = "../embassy-time", features = [ "tick-hz-1_000_000" ] }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-2"]} embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-2"] }
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
atomic-polyfill = "1.0.1" atomic-polyfill = "1.0.1"
@ -90,5 +89,5 @@ pio = {version= "0.2.1" }
rp2040-boot2 = "0.3" rp2040-boot2 = "0.3"
[dev-dependencies] [dev-dependencies]
embassy-executor = { version = "0.2.0", path = "../embassy-executor", features = ["arch-std", "executor-thread"] } embassy-executor = { version = "0.2.0", path = "../embassy-executor", features = ["nightly", "arch-std", "executor-thread"] }
static_cell = "1.1" static_cell = "1.1"

View File

@ -3,14 +3,14 @@ use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_cortex_m::interrupt::{Binding, Interrupt};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embedded_hal_02::adc::{Channel, OneShot}; use embedded_hal_02::adc::{Channel, OneShot};
use crate::gpio::Pin; use crate::gpio::Pin;
use crate::interrupt::{self, ADC_IRQ_FIFO}; use crate::interrupt::typelevel::Binding;
use crate::interrupt::InterruptExt;
use crate::peripherals::ADC; use crate::peripherals::ADC;
use crate::{pac, peripherals, Peripheral}; use crate::{interrupt, pac, peripherals, Peripheral};
static WAKER: AtomicWaker = AtomicWaker::new(); static WAKER: AtomicWaker = AtomicWaker::new();
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -47,7 +47,7 @@ impl<'d> Adc<'d> {
pub fn new( pub fn new(
_inner: impl Peripheral<P = ADC> + 'd, _inner: impl Peripheral<P = ADC> + 'd,
_irq: impl Binding<ADC_IRQ_FIFO, InterruptHandler>, _irq: impl Binding<interrupt::typelevel::ADC_IRQ_FIFO, InterruptHandler>,
_config: Config, _config: Config,
) -> Self { ) -> Self {
unsafe { unsafe {
@ -62,10 +62,8 @@ impl<'d> Adc<'d> {
} }
// Setup IRQ // Setup IRQ
unsafe { interrupt::ADC_IRQ_FIFO.unpend();
ADC_IRQ_FIFO::unpend(); unsafe { interrupt::ADC_IRQ_FIFO.enable() };
ADC_IRQ_FIFO::enable();
};
Self { phantom: PhantomData } Self { phantom: PhantomData }
} }
@ -164,7 +162,7 @@ pub struct InterruptHandler {
_empty: (), _empty: (),
} }
impl interrupt::Handler<ADC_IRQ_FIFO> for InterruptHandler { impl interrupt::typelevel::Handler<interrupt::typelevel::ADC_IRQ_FIFO> for InterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = Adc::regs(); let r = Adc::regs();
r.inte().write(|w| w.set_fifo(false)); r.inte().write(|w| w.set_fifo(false));

View File

@ -4,14 +4,15 @@ use core::pin::Pin;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef}; use embassy_hal_common::{impl_peripheral, into_ref, Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use pac::dma::vals::DataSize; use pac::dma::vals::DataSize;
use crate::interrupt::InterruptExt;
use crate::pac::dma::vals; use crate::pac::dma::vals;
use crate::{interrupt, pac, peripherals}; use crate::{interrupt, pac, peripherals};
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
unsafe fn DMA_IRQ_0() { unsafe fn DMA_IRQ_0() {
let ints0 = pac::DMA.ints0().read().ints0(); let ints0 = pac::DMA.ints0().read().ints0();
@ -29,12 +30,12 @@ unsafe fn DMA_IRQ_0() {
} }
pub(crate) unsafe fn init() { pub(crate) unsafe fn init() {
interrupt::DMA_IRQ_0::disable(); interrupt::DMA_IRQ_0.disable();
interrupt::DMA_IRQ_0::set_priority(interrupt::Priority::P3); interrupt::DMA_IRQ_0.set_priority(interrupt::Priority::P3);
pac::DMA.inte0().write(|w| w.set_inte0(0xFFFF)); pac::DMA.inte0().write(|w| w.set_inte0(0xFFFF));
interrupt::DMA_IRQ_0::enable(); interrupt::DMA_IRQ_0.enable();
} }
pub unsafe fn read<'a, C: Channel, W: Word>( pub unsafe fn read<'a, C: Channel, W: Word>(

View File

@ -3,10 +3,10 @@ use core::future::Future;
use core::pin::Pin as FuturePin; use core::pin::Pin as FuturePin;
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::interrupt::InterruptExt;
use crate::pac::common::{Reg, RW}; use crate::pac::common::{Reg, RW};
use crate::pac::SIO; use crate::pac::SIO;
use crate::{interrupt, pac, peripherals, Peripheral, RegExt}; use crate::{interrupt, pac, peripherals, Peripheral, RegExt};
@ -137,11 +137,12 @@ pub enum InterruptTrigger {
} }
pub(crate) unsafe fn init() { pub(crate) unsafe fn init() {
interrupt::IO_IRQ_BANK0::disable(); interrupt::IO_IRQ_BANK0.disable();
interrupt::IO_IRQ_BANK0::set_priority(interrupt::Priority::P3); interrupt::IO_IRQ_BANK0.set_priority(interrupt::Priority::P3);
interrupt::IO_IRQ_BANK0::enable(); interrupt::IO_IRQ_BANK0.enable();
} }
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
unsafe fn IO_IRQ_BANK0() { unsafe fn IO_IRQ_BANK0() {
let cpu = SIO.cpuid().read() as usize; let cpu = SIO.cpuid().read() as usize;

View File

@ -2,14 +2,14 @@ use core::future;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_cortex_m::interrupt::{self, Binding, Interrupt};
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use pac::i2c; use pac::i2c;
use crate::gpio::sealed::Pin; use crate::gpio::sealed::Pin;
use crate::gpio::AnyPin; use crate::gpio::AnyPin;
use crate::{pac, peripherals, Peripheral}; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{interrupt, pac, peripherals, Peripheral};
/// I2C error abort reason /// I2C error abort reason
#[derive(Debug)] #[derive(Debug)]
@ -312,7 +312,7 @@ pub struct InterruptHandler<T: Instance> {
_uart: PhantomData<T>, _uart: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
// Mask interrupts and wake any task waiting for this interrupt // Mask interrupts and wake any task waiting for this interrupt
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let i2c = T::regs(); let i2c = T::regs();
@ -760,14 +760,15 @@ fn i2c_reserved_addr(addr: u16) -> bool {
} }
mod sealed { mod sealed {
use embassy_cortex_m::interrupt::Interrupt;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use crate::interrupt;
pub trait Instance { pub trait Instance {
const TX_DREQ: u8; const TX_DREQ: u8;
const RX_DREQ: u8; const RX_DREQ: u8;
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
fn regs() -> crate::pac::i2c::I2c; fn regs() -> crate::pac::i2c::I2c;
fn reset() -> crate::pac::resets::regs::Peripherals; fn reset() -> crate::pac::resets::regs::Peripherals;
@ -803,7 +804,7 @@ macro_rules! impl_instance {
const TX_DREQ: u8 = $tx_dreq; const TX_DREQ: u8 = $tx_dreq;
const RX_DREQ: u8 = $rx_dreq; const RX_DREQ: u8 = $rx_dreq;
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
#[inline] #[inline]
fn regs() -> pac::i2c::I2c { fn regs() -> pac::i2c::I2c {

View File

@ -1,65 +0,0 @@
//! Interrupt definitions and macros to bind them.
pub use cortex_m::interrupt::{CriticalSection, Mutex};
use embassy_cortex_m::interrupt::_export::declare;
pub use embassy_cortex_m::interrupt::{Binding, Handler, Interrupt, Priority};
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);
declare!(SWI_IRQ_0);
declare!(SWI_IRQ_1);
declare!(SWI_IRQ_2);
declare!(SWI_IRQ_3);
declare!(SWI_IRQ_4);
declare!(SWI_IRQ_5);
/// Macro to bind interrupts to handlers.
///
/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
/// prove at compile-time that the right interrupts have been bound.
// developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`.
#[macro_export]
macro_rules! bind_interrupts {
($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
$vis struct $name;
$(
#[allow(non_snake_case)]
#[no_mangle]
unsafe extern "C" fn $irq() {
$(
<$handler as $crate::interrupt::Handler<$crate::interrupt::$irq>>::on_interrupt();
)*
}
$(
unsafe impl $crate::interrupt::Binding<$crate::interrupt::$irq, $handler> for $name {}
)*
)*
};
}

View File

@ -16,7 +16,6 @@ pub mod flash;
mod float; mod float;
pub mod gpio; pub mod gpio;
pub mod i2c; pub mod i2c;
pub mod interrupt;
pub mod multicore; pub mod multicore;
pub mod pwm; pub mod pwm;
mod reset; mod reset;
@ -37,14 +36,77 @@ pub mod pio_instr_util;
pub mod relocate; pub mod relocate;
// Reexports // Reexports
pub use embassy_cortex_m::executor;
pub use embassy_cortex_m::interrupt::_export::interrupt;
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
#[cfg(feature = "unstable-pac")] #[cfg(feature = "unstable-pac")]
pub use rp_pac as pac; pub use rp_pac as pac;
#[cfg(not(feature = "unstable-pac"))] #[cfg(not(feature = "unstable-pac"))]
pub(crate) use rp_pac as pac; pub(crate) use rp_pac as pac;
#[cfg(feature = "rt")]
pub use crate::pac::NVIC_PRIO_BITS;
embassy_hal_common::interrupt_mod!(
TIMER_IRQ_0,
TIMER_IRQ_1,
TIMER_IRQ_2,
TIMER_IRQ_3,
PWM_IRQ_WRAP,
USBCTRL_IRQ,
XIP_IRQ,
PIO0_IRQ_0,
PIO0_IRQ_1,
PIO1_IRQ_0,
PIO1_IRQ_1,
DMA_IRQ_0,
DMA_IRQ_1,
IO_IRQ_BANK0,
IO_IRQ_QSPI,
SIO_IRQ_PROC0,
SIO_IRQ_PROC1,
CLOCKS_IRQ,
SPI0_IRQ,
SPI1_IRQ,
UART0_IRQ,
UART1_IRQ,
ADC_IRQ_FIFO,
I2C0_IRQ,
I2C1_IRQ,
RTC_IRQ,
SWI_IRQ_0,
SWI_IRQ_1,
SWI_IRQ_2,
SWI_IRQ_3,
SWI_IRQ_4,
SWI_IRQ_5,
);
/// Macro to bind interrupts to handlers.
///
/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
/// prove at compile-time that the right interrupts have been bound.
// developer note: this macro can't be in `embassy-hal-common` due to the use of `$crate`.
#[macro_export]
macro_rules! bind_interrupts {
($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
$vis struct $name;
$(
#[allow(non_snake_case)]
#[no_mangle]
unsafe extern "C" fn $irq() {
$(
<$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt();
)*
}
$(
unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {}
)*
)*
};
}
embassy_hal_common::peripherals! { embassy_hal_common::peripherals! {
PIN_0, PIN_0,
PIN_1, PIN_1,

View File

@ -50,7 +50,7 @@
use core::mem::ManuallyDrop; use core::mem::ManuallyDrop;
use core::sync::atomic::{compiler_fence, AtomicBool, Ordering}; use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
use crate::interrupt::Interrupt; use crate::interrupt::InterruptExt;
use crate::peripherals::CORE1; use crate::peripherals::CORE1;
use crate::{gpio, interrupt, pac}; use crate::{gpio, interrupt, pac};
@ -106,6 +106,7 @@ impl<const SIZE: usize> Stack<SIZE> {
} }
} }
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
#[link_section = ".data.ram_func"] #[link_section = ".data.ram_func"]
unsafe fn SIO_IRQ_PROC1() { unsafe fn SIO_IRQ_PROC1() {
@ -156,7 +157,7 @@ where
IS_CORE1_INIT.store(true, Ordering::Release); IS_CORE1_INIT.store(true, Ordering::Release);
// Enable fifo interrupt on CORE1 for `pause` functionality. // Enable fifo interrupt on CORE1 for `pause` functionality.
unsafe { interrupt::SIO_IRQ_PROC1::enable() }; unsafe { interrupt::SIO_IRQ_PROC1.enable() };
entry() entry()
} }
@ -297,6 +298,7 @@ fn fifo_read() -> u32 {
// Pop a value from inter-core FIFO, `wfe` until available // Pop a value from inter-core FIFO, `wfe` until available
#[inline(always)] #[inline(always)]
#[allow(unused)]
fn fifo_read_wfe() -> u32 { fn fifo_read_wfe() -> u32 {
unsafe { unsafe {
let sio = pac::SIO; let sio = pac::SIO;

View File

@ -5,7 +5,6 @@ use core::sync::atomic::{compiler_fence, Ordering};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use atomic_polyfill::{AtomicU32, AtomicU8}; use atomic_polyfill::{AtomicU32, AtomicU8};
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use fixed::types::extra::U8; use fixed::types::extra::U8;
@ -17,6 +16,7 @@ use pio::{SideSet, Wrap};
use crate::dma::{Channel, Transfer, Word}; use crate::dma::{Channel, Transfer, Word};
use crate::gpio::sealed::Pin as SealedPin; use crate::gpio::sealed::Pin as SealedPin;
use crate::gpio::{self, AnyPin, Drive, Level, Pull, SlewRate}; use crate::gpio::{self, AnyPin, Drive, Level, Pull, SlewRate};
use crate::interrupt::InterruptExt;
use crate::pac::dma::vals::TreqSel; use crate::pac::dma::vals::TreqSel;
use crate::relocate::RelocatedProgram; use crate::relocate::RelocatedProgram;
use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt}; use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt};
@ -85,6 +85,7 @@ const RXNEMPTY_MASK: u32 = 1 << 0;
const TXNFULL_MASK: u32 = 1 << 4; const TXNFULL_MASK: u32 = 1 << 4;
const SMIRQ_MASK: u32 = 1 << 8; const SMIRQ_MASK: u32 = 1 << 8;
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
unsafe fn PIO0_IRQ_0() { unsafe fn PIO0_IRQ_0() {
use crate::pac; use crate::pac;
@ -97,6 +98,7 @@ unsafe fn PIO0_IRQ_0() {
pac::PIO0.irqs(0).inte().write_clear(|m| m.0 = ints); pac::PIO0.irqs(0).inte().write_clear(|m| m.0 = ints);
} }
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
unsafe fn PIO1_IRQ_0() { unsafe fn PIO1_IRQ_0() {
use crate::pac; use crate::pac;
@ -110,15 +112,15 @@ unsafe fn PIO1_IRQ_0() {
} }
pub(crate) unsafe fn init() { pub(crate) unsafe fn init() {
interrupt::PIO0_IRQ_0::disable(); interrupt::PIO0_IRQ_0.disable();
interrupt::PIO0_IRQ_0::set_priority(interrupt::Priority::P3); interrupt::PIO0_IRQ_0.set_priority(interrupt::Priority::P3);
pac::PIO0.irqs(0).inte().write(|m| m.0 = 0); pac::PIO0.irqs(0).inte().write(|m| m.0 = 0);
interrupt::PIO0_IRQ_0::enable(); interrupt::PIO0_IRQ_0.enable();
interrupt::PIO1_IRQ_0::disable(); interrupt::PIO1_IRQ_0.disable();
interrupt::PIO1_IRQ_0::set_priority(interrupt::Priority::P3); interrupt::PIO1_IRQ_0.set_priority(interrupt::Priority::P3);
pac::PIO1.irqs(0).inte().write(|m| m.0 = 0); pac::PIO1.irqs(0).inte().write(|m| m.0 = 0);
interrupt::PIO1_IRQ_0::enable(); interrupt::PIO1_IRQ_0.enable();
} }
/// Future that waits for TX-FIFO to become writable /// Future that waits for TX-FIFO to become writable

View File

@ -6,7 +6,7 @@ use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::blocking_mutex::Mutex; use embassy_sync::blocking_mutex::Mutex;
use embassy_time::driver::{AlarmHandle, Driver}; use embassy_time::driver::{AlarmHandle, Driver};
use crate::interrupt::Interrupt; use crate::interrupt::InterruptExt;
use crate::{interrupt, pac}; use crate::{interrupt, pac};
struct AlarmState { struct AlarmState {
@ -145,27 +145,31 @@ pub unsafe fn init() {
w.set_alarm(2, true); w.set_alarm(2, true);
w.set_alarm(3, true); w.set_alarm(3, true);
}); });
interrupt::TIMER_IRQ_0::enable(); interrupt::TIMER_IRQ_0.enable();
interrupt::TIMER_IRQ_1::enable(); interrupt::TIMER_IRQ_1.enable();
interrupt::TIMER_IRQ_2::enable(); interrupt::TIMER_IRQ_2.enable();
interrupt::TIMER_IRQ_3::enable(); interrupt::TIMER_IRQ_3.enable();
} }
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
unsafe fn TIMER_IRQ_0() { unsafe fn TIMER_IRQ_0() {
DRIVER.check_alarm(0) DRIVER.check_alarm(0)
} }
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
unsafe fn TIMER_IRQ_1() { unsafe fn TIMER_IRQ_1() {
DRIVER.check_alarm(1) DRIVER.check_alarm(1)
} }
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
unsafe fn TIMER_IRQ_2() { unsafe fn TIMER_IRQ_2() {
DRIVER.check_alarm(2) DRIVER.check_alarm(2)
} }
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
unsafe fn TIMER_IRQ_3() { unsafe fn TIMER_IRQ_3() {
DRIVER.check_alarm(3) DRIVER.check_alarm(3)

View File

@ -3,14 +3,14 @@ use core::slice;
use core::task::Poll; use core::task::Poll;
use atomic_polyfill::{AtomicU8, Ordering}; use atomic_polyfill::{AtomicU8, Ordering};
use embassy_cortex_m::interrupt::{self, Binding, Interrupt};
use embassy_hal_common::atomic_ring_buffer::RingBuffer; use embassy_hal_common::atomic_ring_buffer::RingBuffer;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use super::*; use super::*;
use crate::clocks::clk_peri_freq; use crate::clocks::clk_peri_freq;
use crate::RegExt; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{interrupt, RegExt};
pub struct State { pub struct State {
tx_waker: AtomicWaker, tx_waker: AtomicWaker,
@ -485,7 +485,7 @@ pub struct BufferedInterruptHandler<T: Instance> {
_uart: PhantomData<T>, _uart: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for BufferedInterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for BufferedInterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = T::regs(); let r = T::regs();
if r.uartdmacr().read().rxdmae() { if r.uartdmacr().read().rxdmae() {

View File

@ -3,7 +3,6 @@ use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use atomic_polyfill::{AtomicU16, Ordering}; use atomic_polyfill::{AtomicU16, Ordering};
use embassy_cortex_m::interrupt::{self, Binding, Interrupt};
use embassy_futures::select::{select, Either}; use embassy_futures::select::{select, Either};
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -14,8 +13,9 @@ use crate::clocks::clk_peri_freq;
use crate::dma::{AnyChannel, Channel}; use crate::dma::{AnyChannel, Channel};
use crate::gpio::sealed::Pin; use crate::gpio::sealed::Pin;
use crate::gpio::AnyPin; use crate::gpio::AnyPin;
use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::pac::io::vals::{Inover, Outover}; use crate::pac::io::vals::{Inover, Outover};
use crate::{pac, peripherals, Peripheral, RegExt}; use crate::{interrupt, pac, peripherals, Peripheral, RegExt};
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
mod buffered; mod buffered;
@ -332,7 +332,7 @@ pub struct InterruptHandler<T: Instance> {
_uart: PhantomData<T>, _uart: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let uart = T::regs(); let uart = T::regs();
if !uart.uartdmacr().read().rxdmae() { if !uart.uartdmacr().read().rxdmae() {
@ -930,7 +930,7 @@ mod sealed {
const TX_DREQ: u8; const TX_DREQ: u8;
const RX_DREQ: u8; const RX_DREQ: u8;
type Interrupt: crate::interrupt::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
fn regs() -> pac::uart::Uart; fn regs() -> pac::uart::Uart;
@ -968,7 +968,7 @@ macro_rules! impl_instance {
const TX_DREQ: u8 = $tx_dreq; const TX_DREQ: u8 = $tx_dreq;
const RX_DREQ: u8 = $rx_dreq; const RX_DREQ: u8 = $rx_dreq;
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
fn regs() -> pac::uart::Uart { fn regs() -> pac::uart::Uart {
pac::$inst pac::$inst

View File

@ -4,15 +4,14 @@ use core::slice;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_cortex_m::interrupt::{self, Binding};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embassy_usb_driver as driver; use embassy_usb_driver as driver;
use embassy_usb_driver::{ use embassy_usb_driver::{
Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported, Direction, EndpointAddress, EndpointAllocError, EndpointError, EndpointInfo, EndpointType, Event, Unsupported,
}; };
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::{Binding, Interrupt};
use crate::{pac, peripherals, Peripheral, RegExt}; use crate::{interrupt, pac, peripherals, Peripheral, RegExt};
pub(crate) mod sealed { pub(crate) mod sealed {
pub trait Instance { pub trait Instance {
@ -22,7 +21,7 @@ pub(crate) mod sealed {
} }
pub trait Instance: sealed::Instance + 'static { pub trait Instance: sealed::Instance + 'static {
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
impl crate::usb::sealed::Instance for peripherals::USB { impl crate::usb::sealed::Instance for peripherals::USB {
@ -35,7 +34,7 @@ impl crate::usb::sealed::Instance for peripherals::USB {
} }
impl crate::usb::Instance for peripherals::USB { impl crate::usb::Instance for peripherals::USB {
type Interrupt = crate::interrupt::USBCTRL_IRQ; type Interrupt = crate::interrupt::typelevel::USBCTRL_IRQ;
} }
const EP_COUNT: usize = 16; const EP_COUNT: usize = 16;
@ -249,7 +248,7 @@ pub struct InterruptHandler<T: Instance> {
_uart: PhantomData<T>, _uart: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let regs = T::regs(); let regs = T::regs();
//let x = regs.istr().read().0; //let x = regs.istr().read().0;

View File

@ -32,11 +32,9 @@ flavors = [
[dependencies] [dependencies]
embassy-sync = { version = "0.2.0", path = "../embassy-sync" } embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
embassy-executor = { version = "0.2.0", path = "../embassy-executor" }
embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true } embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" } embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-4"]} embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common", features = ["cortex-m", "prio-bits-4"] }
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" } embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" } embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true } embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional = true }
@ -79,8 +77,10 @@ quote = "1.0.15"
stm32-metapac = { version = "9", default-features = false, features = ["metadata"]} stm32-metapac = { version = "9", default-features = false, features = ["metadata"]}
[features] [features]
default = ["stm32-metapac/rt"] default = ["rt"]
defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-executor/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"] rt = ["stm32-metapac/rt"]
defmt = ["dep:defmt", "bxcan/unstable-defmt", "embassy-sync/defmt", "embassy-embedded-hal/defmt", "embassy-hal-common/defmt", "embedded-io?/defmt", "embassy-usb-driver?/defmt", "embassy-net-driver/defmt"]
memory-x = ["stm32-metapac/memory-x"] memory-x = ["stm32-metapac/memory-x"]
exti = [] exti = []
@ -99,7 +99,7 @@ time-driver-tim12 = ["_time-driver"]
time-driver-tim15 = ["_time-driver"] time-driver-tim15 = ["_time-driver"]
# Enable nightly-only features # Enable nightly-only features
nightly = ["embassy-executor/nightly", "embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io", "dep:embassy-usb-driver", "embassy-embedded-hal/nightly"] nightly = ["embedded-hal-1", "embedded-hal-async", "embedded-storage-async", "dep:embedded-io", "dep:embassy-usb-driver", "embassy-embedded-hal/nightly"]
# Reexport stm32-metapac at `embassy_stm32::pac`. # Reexport stm32-metapac at `embassy_stm32::pac`.
# This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version. # This is unstable because semver-minor (non-breaking) releases of embassy-stm32 may major-bump (breaking) the stm32-metapac version.

View File

@ -160,13 +160,11 @@ fn main() {
} }
g.extend(quote! { g.extend(quote! {
pub mod interrupt { embassy_hal_common::interrupt_mod!(
use crate::pac::Interrupt as InterruptEnum;
use embassy_cortex_m::interrupt::_export::declare;
#( #(
declare!(#irqs); #irqs,
)* )*
} );
}); });
// ======== // ========
@ -297,6 +295,7 @@ fn main() {
let channels = channels.iter().map(|(_, dma, ch)| format_ident!("{}_{}", dma, ch)); let channels = channels.iter().map(|(_, dma, ch)| format_ident!("{}_{}", dma, ch));
g.extend(quote! { g.extend(quote! {
#[cfg(feature = "rt")]
#[crate::interrupt] #[crate::interrupt]
unsafe fn #irq () { unsafe fn #irq () {
#( #(

View File

@ -8,7 +8,7 @@ use embassy_sync::waitqueue::AtomicWaker;
use crate::dma::Transfer; use crate::dma::Transfer;
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
use crate::gpio::Speed; use crate::gpio::Speed;
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
@ -16,7 +16,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let ris = crate::pac::DCMI.ris().read(); let ris = crate::pac::DCMI.ris().read();
if ris.err_ris() { if ris.err_ris() {
@ -119,7 +119,7 @@ where
pub fn new_8bit( pub fn new_8bit(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
@ -143,7 +143,7 @@ where
pub fn new_10bit( pub fn new_10bit(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
@ -169,7 +169,7 @@ where
pub fn new_12bit( pub fn new_12bit(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
@ -197,7 +197,7 @@ where
pub fn new_14bit( pub fn new_14bit(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
@ -227,7 +227,7 @@ where
pub fn new_es_8bit( pub fn new_es_8bit(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
@ -249,7 +249,7 @@ where
pub fn new_es_10bit( pub fn new_es_10bit(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
@ -273,7 +273,7 @@ where
pub fn new_es_12bit( pub fn new_es_12bit(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
@ -299,7 +299,7 @@ where
pub fn new_es_14bit( pub fn new_es_14bit(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
d1: impl Peripheral<P = impl D1Pin<T>> + 'd, d1: impl Peripheral<P = impl D1Pin<T>> + 'd,
d2: impl Peripheral<P = impl D2Pin<T>> + 'd, d2: impl Peripheral<P = impl D2Pin<T>> + 'd,
@ -570,7 +570,7 @@ mod sealed {
} }
pub trait Instance: sealed::Instance + 'static { pub trait Instance: sealed::Instance + 'static {
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
pin_trait!(D0Pin, Instance); pin_trait!(D0Pin, Instance);
@ -602,7 +602,7 @@ macro_rules! impl_peripheral {
} }
impl Instance for crate::peripherals::$inst { impl Instance for crate::peripherals::$inst {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
} }

View File

@ -6,7 +6,6 @@ use core::sync::atomic::{fence, Ordering};
use core::task::{Context, Poll, Waker}; use core::task::{Context, Poll, Waker};
use atomic_polyfill::AtomicUsize; use atomic_polyfill::AtomicUsize;
use embassy_cortex_m::interrupt::Priority;
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -14,7 +13,8 @@ use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError};
use super::word::{Word, WordSize}; use super::word::{Word, WordSize};
use super::Dir; use super::Dir;
use crate::_generated::BDMA_CHANNEL_COUNT; use crate::_generated::BDMA_CHANNEL_COUNT;
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::interrupt::Priority;
use crate::pac; use crate::pac;
use crate::pac::bdma::{regs, vals}; use crate::pac::bdma::{regs, vals};
@ -70,8 +70,8 @@ static STATE: State = State::new();
pub(crate) unsafe fn init(irq_priority: Priority) { pub(crate) unsafe fn init(irq_priority: Priority) {
foreach_interrupt! { foreach_interrupt! {
($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => { ($peri:ident, bdma, $block:ident, $signal_name:ident, $irq:ident) => {
crate::interrupt::$irq::set_priority(irq_priority); crate::interrupt::typelevel::$irq::set_priority(irq_priority);
crate::interrupt::$irq::enable(); crate::interrupt::typelevel::$irq::enable();
}; };
} }
crate::_generated::init_bdma(); crate::_generated::init_bdma();

View File

@ -5,7 +5,6 @@ use core::sync::atomic::{fence, Ordering};
use core::task::{Context, Poll, Waker}; use core::task::{Context, Poll, Waker};
use atomic_polyfill::AtomicUsize; use atomic_polyfill::AtomicUsize;
use embassy_cortex_m::interrupt::Priority;
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
@ -13,7 +12,8 @@ use super::ringbuffer::{DmaCtrl, DmaRingBuffer, OverrunError};
use super::word::{Word, WordSize}; use super::word::{Word, WordSize};
use super::Dir; use super::Dir;
use crate::_generated::DMA_CHANNEL_COUNT; use crate::_generated::DMA_CHANNEL_COUNT;
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::interrupt::Priority;
use crate::pac::dma::{regs, vals}; use crate::pac::dma::{regs, vals};
use crate::{interrupt, pac}; use crate::{interrupt, pac};
@ -149,8 +149,8 @@ static STATE: State = State::new();
pub(crate) unsafe fn init(irq_priority: Priority) { pub(crate) unsafe fn init(irq_priority: Priority) {
foreach_interrupt! { foreach_interrupt! {
($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => { ($peri:ident, dma, $block:ident, $signal_name:ident, $irq:ident) => {
interrupt::$irq::set_priority(irq_priority); interrupt::typelevel::$irq::set_priority(irq_priority);
interrupt::$irq::enable(); interrupt::typelevel::$irq::enable();
}; };
} }
crate::_generated::init_dma(); crate::_generated::init_dma();

View File

@ -5,14 +5,14 @@ use core::pin::Pin;
use core::sync::atomic::{fence, Ordering}; use core::sync::atomic::{fence, Ordering};
use core::task::{Context, Poll}; use core::task::{Context, Poll};
use embassy_cortex_m::interrupt::Priority;
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use super::word::{Word, WordSize}; use super::word::{Word, WordSize};
use super::Dir; use super::Dir;
use crate::_generated::GPDMA_CHANNEL_COUNT; use crate::_generated::GPDMA_CHANNEL_COUNT;
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::interrupt::Priority;
use crate::pac; use crate::pac;
use crate::pac::gpdma::vals; use crate::pac::gpdma::vals;
@ -56,8 +56,8 @@ static STATE: State = State::new();
pub(crate) unsafe fn init(irq_priority: Priority) { pub(crate) unsafe fn init(irq_priority: Priority) {
foreach_interrupt! { foreach_interrupt! {
($peri:ident, gpdma, $block:ident, $signal_name:ident, $irq:ident) => { ($peri:ident, gpdma, $block:ident, $signal_name:ident, $irq:ident) => {
crate::interrupt::$irq::set_priority(irq_priority); crate::interrupt::typelevel::$irq::set_priority(irq_priority);
crate::interrupt::$irq::enable(); crate::interrupt::typelevel::$irq::enable();
}; };
} }
crate::_generated::init_gpdma(); crate::_generated::init_gpdma();

View File

@ -26,11 +26,11 @@ pub mod word;
use core::mem; use core::mem;
use embassy_cortex_m::interrupt::Priority;
use embassy_hal_common::impl_peripheral; use embassy_hal_common::impl_peripheral;
#[cfg(dmamux)] #[cfg(dmamux)]
pub use self::dmamux::*; pub use self::dmamux::*;
use crate::interrupt::Priority;
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]

View File

@ -5,7 +5,6 @@ mod tx_desc;
use core::sync::atomic::{fence, Ordering}; use core::sync::atomic::{fence, Ordering};
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf}; use stm32_metapac::eth::vals::{Apcs, Cr, Dm, DmaomrSr, Fes, Ftf, Ifg, MbProgress, Mw, Pbl, Rsf, St, Tsf};
@ -14,6 +13,7 @@ pub(crate) use self::tx_desc::{TDes, TDesRing};
use super::*; use super::*;
use crate::gpio::sealed::{AFType, Pin as __GpioPin}; use crate::gpio::sealed::{AFType, Pin as __GpioPin};
use crate::gpio::AnyPin; use crate::gpio::AnyPin;
use crate::interrupt::InterruptExt;
#[cfg(eth_v1a)] #[cfg(eth_v1a)]
use crate::pac::AFIO; use crate::pac::AFIO;
#[cfg(any(eth_v1b, eth_v1c))] #[cfg(any(eth_v1b, eth_v1c))]
@ -24,7 +24,7 @@ use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
pub struct InterruptHandler {} pub struct InterruptHandler {}
impl interrupt::Handler<interrupt::ETH> for InterruptHandler { impl interrupt::typelevel::Handler<interrupt::typelevel::ETH> for InterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
WAKER.wake(); WAKER.wake();
@ -100,7 +100,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
pub fn new<const TX: usize, const RX: usize>( pub fn new<const TX: usize, const RX: usize>(
queue: &'d mut PacketQueue<TX, RX>, queue: &'d mut PacketQueue<TX, RX>,
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<interrupt::ETH, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd, ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd,
mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd, mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd,
mdc: impl Peripheral<P = impl MDCPin<T>> + 'd, mdc: impl Peripheral<P = impl MDCPin<T>> + 'd,
@ -267,8 +267,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
P::phy_reset(&mut this); P::phy_reset(&mut this);
P::phy_init(&mut this); P::phy_init(&mut this);
interrupt::ETH::unpend(); interrupt::ETH.unpend();
interrupt::ETH::enable(); interrupt::ETH.enable();
this this
} }

View File

@ -2,20 +2,20 @@ mod descriptors;
use core::sync::atomic::{fence, Ordering}; use core::sync::atomic::{fence, Ordering};
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing}; pub(crate) use self::descriptors::{RDes, RDesRing, TDes, TDesRing};
use super::*; use super::*;
use crate::gpio::sealed::{AFType, Pin as _}; use crate::gpio::sealed::{AFType, Pin as _};
use crate::gpio::{AnyPin, Speed}; use crate::gpio::{AnyPin, Speed};
use crate::interrupt::InterruptExt;
use crate::pac::ETH; use crate::pac::ETH;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
/// Interrupt handler. /// Interrupt handler.
pub struct InterruptHandler {} pub struct InterruptHandler {}
impl interrupt::Handler<interrupt::ETH> for InterruptHandler { impl interrupt::typelevel::Handler<interrupt::typelevel::ETH> for InterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
WAKER.wake(); WAKER.wake();
@ -64,7 +64,7 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
pub fn new<const TX: usize, const RX: usize>( pub fn new<const TX: usize, const RX: usize>(
queue: &'d mut PacketQueue<TX, RX>, queue: &'d mut PacketQueue<TX, RX>,
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<interrupt::ETH, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd, ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd,
mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd, mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd,
mdc: impl Peripheral<P = impl MDCPin<T>> + 'd, mdc: impl Peripheral<P = impl MDCPin<T>> + 'd,
@ -238,8 +238,8 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
P::phy_reset(&mut this); P::phy_reset(&mut this);
P::phy_init(&mut this); P::phy_init(&mut this);
interrupt::ETH::unpend(); interrupt::ETH.unpend();
interrupt::ETH::enable(); interrupt::ETH.enable();
this this
} }

View File

@ -291,6 +291,7 @@ macro_rules! foreach_exti_irq {
macro_rules! impl_irq { macro_rules! impl_irq {
($e:ident) => { ($e:ident) => {
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
unsafe fn $e() { unsafe fn $e() {
on_irq() on_irq()
@ -354,13 +355,13 @@ impl_exti!(EXTI15, 15);
macro_rules! enable_irq { macro_rules! enable_irq {
($e:ident) => { ($e:ident) => {
crate::interrupt::$e::enable(); crate::interrupt::typelevel::$e::enable();
}; };
} }
/// safety: must be called only once /// safety: must be called only once
pub(crate) unsafe fn init() { pub(crate) unsafe fn init() {
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
foreach_exti_irq!(enable_irq); foreach_exti_irq!(enable_irq);

View File

@ -1,7 +1,6 @@
use core::marker::PhantomData; use core::marker::PhantomData;
use atomic_polyfill::{fence, Ordering}; use atomic_polyfill::{fence, Ordering};
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::drop::OnDrop; use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::into_ref; use embassy_hal_common::into_ref;
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
@ -11,6 +10,7 @@ use super::{
blocking_read, ensure_sector_aligned, family, get_sector, Async, Error, Flash, FlashLayout, FLASH_BASE, FLASH_SIZE, blocking_read, ensure_sector_aligned, family, get_sector, Async, Error, Flash, FlashLayout, FLASH_BASE, FLASH_SIZE,
WRITE_SIZE, WRITE_SIZE,
}; };
use crate::interrupt::InterruptExt;
use crate::peripherals::FLASH; use crate::peripherals::FLASH;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
@ -19,12 +19,12 @@ pub(super) static REGION_ACCESS: Mutex<CriticalSectionRawMutex, ()> = Mutex::new
impl<'d> Flash<'d, Async> { impl<'d> Flash<'d, Async> {
pub fn new( pub fn new(
p: impl Peripheral<P = FLASH> + 'd, p: impl Peripheral<P = FLASH> + 'd,
_irq: impl interrupt::Binding<crate::interrupt::FLASH, InterruptHandler> + 'd, _irq: impl interrupt::typelevel::Binding<crate::interrupt::typelevel::FLASH, InterruptHandler> + 'd,
) -> Self { ) -> Self {
into_ref!(p); into_ref!(p);
crate::interrupt::FLASH::unpend(); crate::interrupt::FLASH.unpend();
unsafe { crate::interrupt::FLASH::enable() }; unsafe { crate::interrupt::FLASH.enable() };
Self { Self {
inner: p, inner: p,
@ -49,7 +49,7 @@ impl<'d> Flash<'d, Async> {
/// Interrupt handler /// Interrupt handler
pub struct InterruptHandler; pub struct InterruptHandler;
impl interrupt::Handler<crate::interrupt::FLASH> for InterruptHandler { impl interrupt::typelevel::Handler<crate::interrupt::typelevel::FLASH> for InterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
family::on_interrupt(); family::on_interrupt();
} }

View File

@ -1,6 +1,6 @@
#![macro_use] #![macro_use]
use crate::interrupt::Interrupt; use crate::interrupt;
#[cfg_attr(i2c_v1, path = "v1.rs")] #[cfg_attr(i2c_v1, path = "v1.rs")]
#[cfg_attr(i2c_v2, path = "v2.rs")] #[cfg_attr(i2c_v2, path = "v2.rs")]
@ -35,7 +35,7 @@ pub(crate) mod sealed {
} }
pub trait Instance: sealed::Instance + 'static { pub trait Instance: sealed::Instance + 'static {
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
pin_trait!(SclPin, Instance); pin_trait!(SclPin, Instance);
@ -57,7 +57,7 @@ foreach_interrupt!(
} }
impl Instance for peripherals::$inst { impl Instance for peripherals::$inst {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
); );

View File

@ -16,7 +16,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() {} unsafe fn on_interrupt() {}
} }
@ -57,7 +57,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
_peri: impl Peripheral<P = T> + 'd, _peri: impl Peripheral<P = T> + 'd,
scl: impl Peripheral<P = impl SclPin<T>> + 'd, scl: impl Peripheral<P = impl SclPin<T>> + 'd,
sda: impl Peripheral<P = impl SdaPin<T>> + 'd, sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_dma: impl Peripheral<P = TXDMA> + 'd, tx_dma: impl Peripheral<P = TXDMA> + 'd,
rx_dma: impl Peripheral<P = RXDMA> + 'd, rx_dma: impl Peripheral<P = RXDMA> + 'd,
freq: Hertz, freq: Hertz,

View File

@ -3,7 +3,6 @@ use core::future::poll_fn;
use core::marker::PhantomData; use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use embassy_cortex_m::interrupt::Interrupt;
use embassy_embedded_hal::SetConfig; use embassy_embedded_hal::SetConfig;
use embassy_hal_common::drop::OnDrop; use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
@ -13,6 +12,7 @@ use crate::dma::{NoDma, Transfer};
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
use crate::gpio::Pull; use crate::gpio::Pull;
use crate::i2c::{Error, Instance, SclPin, SdaPin}; use crate::i2c::{Error, Instance, SclPin, SdaPin};
use crate::interrupt::typelevel::Interrupt;
use crate::pac::i2c; use crate::pac::i2c;
use crate::time::Hertz; use crate::time::Hertz;
use crate::{interrupt, Peripheral}; use crate::{interrupt, Peripheral};
@ -22,7 +22,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let regs = T::regs(); let regs = T::regs();
let isr = regs.isr().read(); let isr = regs.isr().read();
@ -78,7 +78,7 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
scl: impl Peripheral<P = impl SclPin<T>> + 'd, scl: impl Peripheral<P = impl SclPin<T>> + 'd,
sda: impl Peripheral<P = impl SdaPin<T>> + 'd, sda: impl Peripheral<P = impl SdaPin<T>> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_dma: impl Peripheral<P = TXDMA> + 'd, tx_dma: impl Peripheral<P = TXDMA> + 'd,
rx_dma: impl Peripheral<P = RXDMA> + 'd, rx_dma: impl Peripheral<P = RXDMA> + 'd,
freq: Hertz, freq: Hertz,

View File

@ -72,21 +72,16 @@ pub(crate) mod _generated {
include!(concat!(env!("OUT_DIR"), "/_generated.rs")); include!(concat!(env!("OUT_DIR"), "/_generated.rs"));
} }
pub mod interrupt { pub use crate::_generated::interrupt;
//! Interrupt definitions and macros to bind them.
pub use cortex_m::interrupt::{CriticalSection, Mutex};
pub use embassy_cortex_m::interrupt::{Binding, Handler, Interrupt, Priority};
pub use crate::_generated::interrupt::*; /// Macro to bind interrupts to handlers.
///
/// Macro to bind interrupts to handlers. /// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
/// /// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`) /// prove at compile-time that the right interrupts have been bound.
/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to // developer note: this macro can't be in `embassy-hal-common` due to the use of `$crate`.
/// prove at compile-time that the right interrupts have been bound. #[macro_export]
// developer note: this macro can't be in `embassy-cortex-m` due to the use of `$crate`. macro_rules! bind_interrupts {
#[macro_export]
macro_rules! bind_interrupts {
($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => { ($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
$vis struct $name; $vis struct $name;
@ -95,29 +90,29 @@ pub mod interrupt {
#[no_mangle] #[no_mangle]
unsafe extern "C" fn $irq() { unsafe extern "C" fn $irq() {
$( $(
<$handler as $crate::interrupt::Handler<$crate::interrupt::$irq>>::on_interrupt(); <$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt();
)* )*
} }
$( $(
unsafe impl $crate::interrupt::Binding<$crate::interrupt::$irq, $handler> for $name {} unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {}
)* )*
)* )*
}; };
}
} }
// Reexports // Reexports
pub use _generated::{peripherals, Peripherals}; pub use _generated::{peripherals, Peripherals};
pub use embassy_cortex_m::executor;
use embassy_cortex_m::interrupt::Priority;
pub use embassy_cortex_m::interrupt::_export::interrupt;
pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
#[cfg(feature = "unstable-pac")] #[cfg(feature = "unstable-pac")]
pub use stm32_metapac as pac; pub use stm32_metapac as pac;
#[cfg(not(feature = "unstable-pac"))] #[cfg(not(feature = "unstable-pac"))]
pub(crate) use stm32_metapac as pac; pub(crate) use stm32_metapac as pac;
use crate::interrupt::Priority;
#[cfg(feature = "rt")]
pub use crate::pac::NVIC_PRIO_BITS;
#[non_exhaustive] #[non_exhaustive]
pub struct Config { pub struct Config {
pub rcc: rcc::Config, pub rcc: rcc::Config,

View File

@ -1,4 +1,6 @@
use stm32_metapac::rcc::vals::{Hpre, Ppre, Sw}; use stm32_metapac::flash::vals::Latency;
use stm32_metapac::rcc::vals::{Hpre, Pllsrc, Ppre, Sw};
use stm32_metapac::FLASH;
use crate::pac::{PWR, RCC}; use crate::pac::{PWR, RCC};
use crate::rcc::{set_freqs, Clocks}; use crate::rcc::{set_freqs, Clocks};
@ -15,6 +17,7 @@ pub const LSI_FREQ: Hertz = Hertz(32_000);
pub enum ClockSrc { pub enum ClockSrc {
HSE(Hertz), HSE(Hertz),
HSI16, HSI16,
PLLCLK(PllSrc, PllM, PllN, PllR),
} }
/// AHB prescaler /// AHB prescaler
@ -41,6 +44,128 @@ pub enum APBPrescaler {
Div16, Div16,
} }
/// PLL clock input source
#[derive(Clone, Copy, Debug)]
pub enum PllSrc {
HSI16,
HSE(Hertz),
}
impl Into<Pllsrc> for PllSrc {
fn into(self) -> Pllsrc {
match self {
PllSrc::HSE(..) => Pllsrc::HSE,
PllSrc::HSI16 => Pllsrc::HSI16,
}
}
}
#[derive(Clone, Copy)]
pub enum PllR {
Div2,
Div4,
Div6,
Div8,
}
impl PllR {
pub fn to_div(self) -> u32 {
let val: u8 = self.into();
(val as u32 + 1) * 2
}
}
impl From<PllR> for u8 {
fn from(val: PllR) -> u8 {
match val {
PllR::Div2 => 0b00,
PllR::Div4 => 0b01,
PllR::Div6 => 0b10,
PllR::Div8 => 0b11,
}
}
}
seq_macro::seq!(N in 8..=127 {
#[derive(Clone, Copy)]
pub enum PllN {
#(
Mul~N,
)*
}
impl From<PllN> for u8 {
fn from(val: PllN) -> u8 {
match val {
#(
PllN::Mul~N => N,
)*
}
}
}
impl PllN {
pub fn to_mul(self) -> u32 {
match self {
#(
PllN::Mul~N => N,
)*
}
}
}
});
// Pre-division
#[derive(Copy, Clone)]
pub enum PllM {
Div1,
Div2,
Div3,
Div4,
Div5,
Div6,
Div7,
Div8,
Div9,
Div10,
Div11,
Div12,
Div13,
Div14,
Div15,
Div16,
}
impl PllM {
pub fn to_div(self) -> u32 {
let val: u8 = self.into();
val as u32 + 1
}
}
impl From<PllM> for u8 {
fn from(val: PllM) -> u8 {
match val {
PllM::Div1 => 0b0000,
PllM::Div2 => 0b0001,
PllM::Div3 => 0b0010,
PllM::Div4 => 0b0011,
PllM::Div5 => 0b0100,
PllM::Div6 => 0b0101,
PllM::Div7 => 0b0110,
PllM::Div8 => 0b0111,
PllM::Div9 => 0b1000,
PllM::Div10 => 0b1001,
PllM::Div11 => 0b1010,
PllM::Div12 => 0b1011,
PllM::Div13 => 0b1100,
PllM::Div14 => 0b1101,
PllM::Div15 => 0b1110,
PllM::Div16 => 0b1111,
}
}
}
impl AHBPrescaler { impl AHBPrescaler {
const fn div(self) -> u32 { const fn div(self) -> u32 {
match self { match self {
@ -135,6 +260,76 @@ pub(crate) unsafe fn init(config: Config) {
(freq.0, Sw::HSE) (freq.0, Sw::HSE)
} }
ClockSrc::PLLCLK(src, prediv, mul, div) => {
let src_freq = match src {
PllSrc::HSI16 => {
// Enable HSI16 as clock source for PLL
RCC.cr().write(|w| w.set_hsion(true));
while !RCC.cr().read().hsirdy() {}
HSI_FREQ.0
}
PllSrc::HSE(freq) => {
// Enable HSE as clock source for PLL
RCC.cr().write(|w| w.set_hseon(true));
while !RCC.cr().read().hserdy() {}
freq.0
}
};
// Make sure PLL is disabled while we configure it
RCC.cr().modify(|w| w.set_pllon(false));
while RCC.cr().read().pllrdy() {}
let freq = src_freq / prediv.to_div() * mul.to_mul() / div.to_div();
assert!(freq <= 170_000_000);
if freq >= 150_000_000 {
// Enable Core Boost mode on freq >= 150Mhz ([RM0440] p234)
PWR.cr5().modify(|w| w.set_r1mode(false));
// Set flash wait state in boost mode based on frequency ([RM0440] p191)
if freq <= 36_000_000 {
FLASH.acr().modify(|w| w.set_latency(Latency::WS0));
} else if freq <= 68_000_000 {
FLASH.acr().modify(|w| w.set_latency(Latency::WS1));
} else if freq <= 102_000_000 {
FLASH.acr().modify(|w| w.set_latency(Latency::WS2));
} else if freq <= 136_000_000 {
FLASH.acr().modify(|w| w.set_latency(Latency::WS3));
} else {
FLASH.acr().modify(|w| w.set_latency(Latency::WS4));
}
} else {
PWR.cr5().modify(|w| w.set_r1mode(true));
// Set flash wait state in normal mode based on frequency ([RM0440] p191)
if freq <= 30_000_000 {
FLASH.acr().modify(|w| w.set_latency(Latency::WS0));
} else if freq <= 60_000_000 {
FLASH.acr().modify(|w| w.set_latency(Latency::WS1));
} else if freq <= 80_000_000 {
FLASH.acr().modify(|w| w.set_latency(Latency::WS2));
} else if freq <= 120_000_000 {
FLASH.acr().modify(|w| w.set_latency(Latency::WS3));
} else {
FLASH.acr().modify(|w| w.set_latency(Latency::WS4));
}
}
RCC.pllcfgr().write(move |w| {
w.set_plln(mul.into());
w.set_pllm(prediv.into());
w.set_pllr(div.into());
w.set_pllsrc(src.into());
});
// Enable PLL
RCC.cr().modify(|w| w.set_pllon(true));
while !RCC.cr().read().pllrdy() {}
RCC.pllcfgr().modify(|w| w.set_pllren(true));
(freq, Sw::PLLRCLK)
}
}; };
RCC.cfgr().modify(|w| { RCC.cfgr().modify(|w| {

View File

@ -149,6 +149,7 @@ foreach_peripheral!(
}; };
); );
#[cfg(feature = "rt")]
macro_rules! irq { macro_rules! irq {
($irq:ident) => { ($irq:ident) => {
mod rng_irq { mod rng_irq {
@ -166,6 +167,7 @@ macro_rules! irq {
}; };
} }
#[cfg(feature = "rt")]
foreach_interrupt!( foreach_interrupt!(
(RNG) => { (RNG) => {
irq!(RNG); irq!(RNG);

View File

@ -14,7 +14,7 @@ use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID,
use crate::dma::NoDma; use crate::dma::NoDma;
use crate::gpio::sealed::{AFType, Pin}; use crate::gpio::sealed::{AFType, Pin};
use crate::gpio::{AnyPin, Pull, Speed}; use crate::gpio::{AnyPin, Pull, Speed};
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::sdmmc::Sdmmc as RegBlock; use crate::pac::sdmmc::Sdmmc as RegBlock;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::time::Hertz; use crate::time::Hertz;
@ -42,7 +42,7 @@ impl<T: Instance> InterruptHandler<T> {
} }
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
Self::data_interrupts(false); Self::data_interrupts(false);
T::state().wake(); T::state().wake();
@ -276,7 +276,7 @@ pub struct Sdmmc<'d, T: Instance, Dma: SdmmcDma<T> = NoDma> {
impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> { impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
pub fn new_1bit( pub fn new_1bit(
sdmmc: impl Peripheral<P = T> + 'd, sdmmc: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
clk: impl Peripheral<P = impl CkPin<T>> + 'd, clk: impl Peripheral<P = impl CkPin<T>> + 'd,
cmd: impl Peripheral<P = impl CmdPin<T>> + 'd, cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
@ -310,7 +310,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
pub fn new_4bit( pub fn new_4bit(
sdmmc: impl Peripheral<P = T> + 'd, sdmmc: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
dma: impl Peripheral<P = Dma> + 'd, dma: impl Peripheral<P = Dma> + 'd,
clk: impl Peripheral<P = impl CkPin<T>> + 'd, clk: impl Peripheral<P = impl CkPin<T>> + 'd,
cmd: impl Peripheral<P = impl CmdPin<T>> + 'd, cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
@ -356,7 +356,7 @@ impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
impl<'d, T: Instance> Sdmmc<'d, T, NoDma> { impl<'d, T: Instance> Sdmmc<'d, T, NoDma> {
pub fn new_1bit( pub fn new_1bit(
sdmmc: impl Peripheral<P = T> + 'd, sdmmc: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
clk: impl Peripheral<P = impl CkPin<T>> + 'd, clk: impl Peripheral<P = impl CkPin<T>> + 'd,
cmd: impl Peripheral<P = impl CmdPin<T>> + 'd, cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
@ -389,7 +389,7 @@ impl<'d, T: Instance> Sdmmc<'d, T, NoDma> {
pub fn new_4bit( pub fn new_4bit(
sdmmc: impl Peripheral<P = T> + 'd, sdmmc: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
clk: impl Peripheral<P = impl CkPin<T>> + 'd, clk: impl Peripheral<P = impl CkPin<T>> + 'd,
cmd: impl Peripheral<P = impl CmdPin<T>> + 'd, cmd: impl Peripheral<P = impl CmdPin<T>> + 'd,
d0: impl Peripheral<P = impl D0Pin<T>> + 'd, d0: impl Peripheral<P = impl D0Pin<T>> + 'd,
@ -1401,7 +1401,7 @@ pub(crate) mod sealed {
use super::*; use super::*;
pub trait Instance { pub trait Instance {
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
fn regs() -> RegBlock; fn regs() -> RegBlock;
fn state() -> &'static AtomicWaker; fn state() -> &'static AtomicWaker;
@ -1490,7 +1490,7 @@ cfg_if::cfg_if! {
foreach_peripheral!( foreach_peripheral!(
(sdmmc, $inst:ident) => { (sdmmc, $inst:ident) => {
impl sealed::Instance for peripherals::$inst { impl sealed::Instance for peripherals::$inst {
type Interrupt = crate::interrupt::$inst; type Interrupt = crate::interrupt::typelevel::$inst;
fn regs() -> RegBlock { fn regs() -> RegBlock {
crate::pac::$inst crate::pac::$inst

View File

@ -11,7 +11,7 @@ use embassy_time::driver::{AlarmHandle, Driver};
use embassy_time::TICK_HZ; use embassy_time::TICK_HZ;
use stm32_metapac::timer::regs; use stm32_metapac::timer::regs;
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::timer::vals; use crate::pac::timer::vals;
use crate::rcc::sealed::RccPeripheral; use crate::rcc::sealed::RccPeripheral;
use crate::timer::sealed::{Basic16bitInstance as BasicInstance, GeneralPurpose16bitInstance as Instance}; use crate::timer::sealed::{Basic16bitInstance as BasicInstance, GeneralPurpose16bitInstance as Instance};
@ -40,6 +40,7 @@ type T = peripherals::TIM15;
foreach_interrupt! { foreach_interrupt! {
(TIM2, timer, $block:ident, UP, $irq:ident) => { (TIM2, timer, $block:ident, UP, $irq:ident) => {
#[cfg(time_driver_tim2)] #[cfg(time_driver_tim2)]
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn $irq() { fn $irq() {
DRIVER.on_interrupt() DRIVER.on_interrupt()
@ -47,6 +48,7 @@ foreach_interrupt! {
}; };
(TIM3, timer, $block:ident, UP, $irq:ident) => { (TIM3, timer, $block:ident, UP, $irq:ident) => {
#[cfg(time_driver_tim3)] #[cfg(time_driver_tim3)]
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn $irq() { fn $irq() {
DRIVER.on_interrupt() DRIVER.on_interrupt()
@ -54,6 +56,7 @@ foreach_interrupt! {
}; };
(TIM4, timer, $block:ident, UP, $irq:ident) => { (TIM4, timer, $block:ident, UP, $irq:ident) => {
#[cfg(time_driver_tim4)] #[cfg(time_driver_tim4)]
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn $irq() { fn $irq() {
DRIVER.on_interrupt() DRIVER.on_interrupt()
@ -61,6 +64,7 @@ foreach_interrupt! {
}; };
(TIM5, timer, $block:ident, UP, $irq:ident) => { (TIM5, timer, $block:ident, UP, $irq:ident) => {
#[cfg(time_driver_tim5)] #[cfg(time_driver_tim5)]
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn $irq() { fn $irq() {
DRIVER.on_interrupt() DRIVER.on_interrupt()
@ -68,6 +72,7 @@ foreach_interrupt! {
}; };
(TIM12, timer, $block:ident, UP, $irq:ident) => { (TIM12, timer, $block:ident, UP, $irq:ident) => {
#[cfg(time_driver_tim12)] #[cfg(time_driver_tim12)]
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn $irq() { fn $irq() {
DRIVER.on_interrupt() DRIVER.on_interrupt()
@ -75,6 +80,7 @@ foreach_interrupt! {
}; };
(TIM15, timer, $block:ident, UP, $irq:ident) => { (TIM15, timer, $block:ident, UP, $irq:ident) => {
#[cfg(time_driver_tim15)] #[cfg(time_driver_tim15)]
#[cfg(feature = "rt")]
#[interrupt] #[interrupt]
fn $irq() { fn $irq() {
DRIVER.on_interrupt() DRIVER.on_interrupt()

View File

@ -1,6 +1,6 @@
use stm32_metapac::timer::vals; use stm32_metapac::timer::vals;
use crate::interrupt::Interrupt; use crate::interrupt;
use crate::rcc::sealed::RccPeripheral as __RccPeri; use crate::rcc::sealed::RccPeripheral as __RccPeri;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::time::Hertz; use crate::time::Hertz;
@ -13,7 +13,7 @@ pub mod low_level {
pub(crate) mod sealed { pub(crate) mod sealed {
use super::*; use super::*;
pub trait Basic16bitInstance: RccPeripheral { pub trait Basic16bitInstance: RccPeripheral {
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
fn regs() -> crate::pac::timer::TimBasic; fn regs() -> crate::pac::timer::TimBasic;
@ -57,7 +57,7 @@ pub trait Basic16bitInstance: sealed::Basic16bitInstance + 'static {}
macro_rules! impl_basic_16bit_timer { macro_rules! impl_basic_16bit_timer {
($inst:ident, $irq:ident) => { ($inst:ident, $irq:ident) => {
impl sealed::Basic16bitInstance for crate::peripherals::$inst { impl sealed::Basic16bitInstance for crate::peripherals::$inst {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
fn regs() -> crate::pac::timer::TimBasic { fn regs() -> crate::pac::timer::TimBasic {
crate::pac::timer::TimBasic(crate::pac::$inst.0) crate::pac::timer::TimBasic(crate::pac::$inst.0)

View File

@ -2,18 +2,18 @@ use core::future::poll_fn;
use core::slice; use core::slice;
use core::task::Poll; use core::task::Poll;
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::atomic_ring_buffer::RingBuffer; use embassy_hal_common::atomic_ring_buffer::RingBuffer;
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use super::*; use super::*;
use crate::interrupt::typelevel::Interrupt;
/// Interrupt handler. /// Interrupt handler.
pub struct InterruptHandler<T: BasicInstance> { pub struct InterruptHandler<T: BasicInstance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: BasicInstance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = T::regs(); let r = T::regs();
let state = T::buffered_state(); let state = T::buffered_state();
@ -115,7 +115,7 @@ pub struct BufferedUartRx<'d, T: BasicInstance> {
impl<'d, T: BasicInstance> BufferedUart<'d, T> { impl<'d, T: BasicInstance> BufferedUart<'d, T> {
pub fn new( pub fn new(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd,
tx_buffer: &'d mut [u8], tx_buffer: &'d mut [u8],
@ -130,7 +130,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
pub fn new_with_rtscts( pub fn new_with_rtscts(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd, rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
@ -159,7 +159,7 @@ impl<'d, T: BasicInstance> BufferedUart<'d, T> {
#[cfg(not(any(usart_v1, usart_v2)))] #[cfg(not(any(usart_v1, usart_v2)))]
pub fn new_with_de( pub fn new_with_de(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd,
de: impl Peripheral<P = impl DePin<T>> + 'd, de: impl Peripheral<P = impl DePin<T>> + 'd,

View File

@ -5,13 +5,13 @@ use core::marker::PhantomData;
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use core::task::Poll; use core::task::Poll;
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::drop::OnDrop; use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::{into_ref, PeripheralRef}; use embassy_hal_common::{into_ref, PeripheralRef};
use futures::future::{select, Either}; use futures::future::{select, Either};
use crate::dma::{NoDma, Transfer}; use crate::dma::{NoDma, Transfer};
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
use crate::interrupt::typelevel::Interrupt;
#[cfg(not(any(usart_v1, usart_v2)))] #[cfg(not(any(usart_v1, usart_v2)))]
#[allow(unused_imports)] #[allow(unused_imports)]
use crate::pac::usart::regs::Isr as Sr; use crate::pac::usart::regs::Isr as Sr;
@ -31,7 +31,7 @@ pub struct InterruptHandler<T: BasicInstance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: BasicInstance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: BasicInstance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
let r = T::regs(); let r = T::regs();
let s = T::state(); let s = T::state();
@ -281,7 +281,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
/// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power. /// Useful if you only want Uart Rx. It saves 1 pin and consumes a little less power.
pub fn new( pub fn new(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd,
rx_dma: impl Peripheral<P = RxDma> + 'd, rx_dma: impl Peripheral<P = RxDma> + 'd,
config: Config, config: Config,
@ -294,7 +294,7 @@ impl<'d, T: BasicInstance, RxDma> UartRx<'d, T, RxDma> {
pub fn new_with_rts( pub fn new_with_rts(
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd, rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
rx_dma: impl Peripheral<P = RxDma> + 'd, rx_dma: impl Peripheral<P = RxDma> + 'd,
@ -650,7 +650,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
tx_dma: impl Peripheral<P = TxDma> + 'd, tx_dma: impl Peripheral<P = TxDma> + 'd,
rx_dma: impl Peripheral<P = RxDma> + 'd, rx_dma: impl Peripheral<P = RxDma> + 'd,
config: Config, config: Config,
@ -665,7 +665,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
rts: impl Peripheral<P = impl RtsPin<T>> + 'd, rts: impl Peripheral<P = impl RtsPin<T>> + 'd,
cts: impl Peripheral<P = impl CtsPin<T>> + 'd, cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
tx_dma: impl Peripheral<P = TxDma> + 'd, tx_dma: impl Peripheral<P = TxDma> + 'd,
@ -693,7 +693,7 @@ impl<'d, T: BasicInstance, TxDma, RxDma> Uart<'d, T, TxDma, RxDma> {
peri: impl Peripheral<P = T> + 'd, peri: impl Peripheral<P = T> + 'd,
rx: impl Peripheral<P = impl RxPin<T>> + 'd, rx: impl Peripheral<P = impl RxPin<T>> + 'd,
tx: impl Peripheral<P = impl TxPin<T>> + 'd, tx: impl Peripheral<P = impl TxPin<T>> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
de: impl Peripheral<P = impl DePin<T>> + 'd, de: impl Peripheral<P = impl DePin<T>> + 'd,
tx_dma: impl Peripheral<P = TxDma> + 'd, tx_dma: impl Peripheral<P = TxDma> + 'd,
rx_dma: impl Peripheral<P = RxDma> + 'd, rx_dma: impl Peripheral<P = RxDma> + 'd,
@ -1179,7 +1179,7 @@ pub(crate) mod sealed {
pub trait BasicInstance: crate::rcc::RccPeripheral { pub trait BasicInstance: crate::rcc::RccPeripheral {
const KIND: Kind; const KIND: Kind;
type Interrupt: crate::interrupt::Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
fn regs() -> Regs; fn regs() -> Regs;
fn state() -> &'static State; fn state() -> &'static State;
@ -1211,7 +1211,7 @@ macro_rules! impl_usart {
($inst:ident, $irq:ident, $kind:expr) => { ($inst:ident, $irq:ident, $kind:expr) => {
impl sealed::BasicInstance for crate::peripherals::$inst { impl sealed::BasicInstance for crate::peripherals::$inst {
const KIND: Kind = $kind; const KIND: Kind = $kind;
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
fn regs() -> Regs { fn regs() -> Regs {
Regs(crate::pac::$inst.0) Regs(crate::pac::$inst.0)

View File

@ -1,4 +1,4 @@
use crate::interrupt::Interrupt; use crate::interrupt;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
@ -13,7 +13,7 @@ pub(crate) mod sealed {
} }
pub trait Instance: sealed::Instance + RccPeripheral + 'static { pub trait Instance: sealed::Instance + RccPeripheral + 'static {
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
// Internal PHY pins // Internal PHY pins
@ -29,7 +29,7 @@ foreach_interrupt!(
} }
impl Instance for crate::peripherals::$inst { impl Instance for crate::peripherals::$inst {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
); );

View File

@ -14,7 +14,7 @@ use embassy_usb_driver::{
use super::{DmPin, DpPin, Instance}; use super::{DmPin, DpPin, Instance};
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
use crate::interrupt::Interrupt; use crate::interrupt::typelevel::Interrupt;
use crate::pac::usb::regs; use crate::pac::usb::regs;
use crate::pac::usb::vals::{EpType, Stat}; use crate::pac::usb::vals::{EpType, Stat};
use crate::pac::USBRAM; use crate::pac::USBRAM;
@ -26,7 +26,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
unsafe { unsafe {
let regs = T::regs(); let regs = T::regs();
@ -255,7 +255,7 @@ pub struct Driver<'d, T: Instance> {
impl<'d, T: Instance> Driver<'d, T> { impl<'d, T: Instance> Driver<'d, T> {
pub fn new( pub fn new(
_usb: impl Peripheral<P = T> + 'd, _usb: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
dp: impl Peripheral<P = impl DpPin<T>> + 'd, dp: impl Peripheral<P = impl DpPin<T>> + 'd,
dm: impl Peripheral<P = impl DmPin<T>> + 'd, dm: impl Peripheral<P = impl DmPin<T>> + 'd,
) -> Self { ) -> Self {

View File

@ -1,7 +1,5 @@
use embassy_cortex_m::interrupt::Interrupt;
use crate::peripherals;
use crate::rcc::RccPeripheral; use crate::rcc::RccPeripheral;
use crate::{interrupt, peripherals};
#[cfg(feature = "nightly")] #[cfg(feature = "nightly")]
mod usb; mod usb;
@ -25,7 +23,7 @@ pub(crate) mod sealed {
} }
pub trait Instance: sealed::Instance + RccPeripheral { pub trait Instance: sealed::Instance + RccPeripheral {
type Interrupt: Interrupt; type Interrupt: interrupt::typelevel::Interrupt;
} }
// Internal PHY pins // Internal PHY pins
@ -109,7 +107,7 @@ foreach_interrupt!(
} }
impl Instance for peripherals::USB_OTG_FS { impl Instance for peripherals::USB_OTG_FS {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
@ -161,7 +159,7 @@ foreach_interrupt!(
} }
impl Instance for peripherals::USB_OTG_HS { impl Instance for peripherals::USB_OTG_HS {
type Interrupt = crate::interrupt::$irq; type Interrupt = crate::interrupt::typelevel::$irq;
} }
}; };
); );

View File

@ -3,7 +3,6 @@ use core::marker::PhantomData;
use core::task::Poll; use core::task::Poll;
use atomic_polyfill::{AtomicBool, AtomicU16, Ordering}; use atomic_polyfill::{AtomicBool, AtomicU16, Ordering};
use embassy_cortex_m::interrupt::Interrupt;
use embassy_hal_common::{into_ref, Peripheral}; use embassy_hal_common::{into_ref, Peripheral};
use embassy_sync::waitqueue::AtomicWaker; use embassy_sync::waitqueue::AtomicWaker;
use embassy_usb_driver::{ use embassy_usb_driver::{
@ -15,6 +14,7 @@ use futures::future::poll_fn;
use super::*; use super::*;
use crate::gpio::sealed::AFType; use crate::gpio::sealed::AFType;
use crate::interrupt; use crate::interrupt;
use crate::interrupt::typelevel::Interrupt;
use crate::pac::otg::{regs, vals}; use crate::pac::otg::{regs, vals};
use crate::rcc::sealed::RccPeripheral; use crate::rcc::sealed::RccPeripheral;
use crate::time::Hertz; use crate::time::Hertz;
@ -24,7 +24,7 @@ pub struct InterruptHandler<T: Instance> {
_phantom: PhantomData<T>, _phantom: PhantomData<T>,
} }
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> { impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
trace!("irq"); trace!("irq");
let r = T::regs(); let r = T::regs();
@ -291,7 +291,7 @@ impl<'d, T: Instance> Driver<'d, T> {
/// Endpoint allocation will fail if it is too small. /// Endpoint allocation will fail if it is too small.
pub fn new_fs( pub fn new_fs(
_peri: impl Peripheral<P = T> + 'd, _peri: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
dp: impl Peripheral<P = impl DpPin<T>> + 'd, dp: impl Peripheral<P = impl DpPin<T>> + 'd,
dm: impl Peripheral<P = impl DmPin<T>> + 'd, dm: impl Peripheral<P = impl DmPin<T>> + 'd,
ep_out_buffer: &'d mut [u8], ep_out_buffer: &'d mut [u8],
@ -322,7 +322,7 @@ impl<'d, T: Instance> Driver<'d, T> {
/// Endpoint allocation will fail if it is too small. /// Endpoint allocation will fail if it is too small.
pub fn new_hs_ulpi( pub fn new_hs_ulpi(
_peri: impl Peripheral<P = T> + 'd, _peri: impl Peripheral<P = T> + 'd,
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd, _irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
ulpi_clk: impl Peripheral<P = impl UlpiClkPin<T>> + 'd, ulpi_clk: impl Peripheral<P = impl UlpiClkPin<T>> + 'd,
ulpi_dir: impl Peripheral<P = impl UlpiDirPin<T>> + 'd, ulpi_dir: impl Peripheral<P = impl UlpiDirPin<T>> + 'd,
ulpi_nxt: impl Peripheral<P = impl UlpiNxtPin<T>> + 'd, ulpi_nxt: impl Peripheral<P = impl UlpiNxtPin<T>> + 'd,

View File

@ -195,9 +195,6 @@ macro_rules! unwrap {
} }
} }
#[cfg(feature = "defmt-timestamp-uptime")]
defmt::timestamp! {"{=u64:us}", crate::time::Instant::now().as_micros() }
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct NoneError; pub struct NoneError;

View File

@ -0,0 +1,9 @@
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
# replace nRF82840_xxAA with your chip as listed in `probe-rs-cli chip list`
runner = "probe-rs-cli run --chip nRF52840_xxAA"
[build]
target = "thumbv7em-none-eabi"
[env]
DEFMT_LOG = "trace"

View File

@ -0,0 +1,21 @@
[package]
edition = "2021"
name = "embassy-nrf52840-rtic-examples"
version = "0.1.0"
license = "MIT OR Apache-2.0"
[dependencies]
rtic = { version = "2", features = ["thumbv7-backend"] }
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime", "generic-queue"] }
embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nightly", "unstable-traits", "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
defmt = "0.3"
defmt-rtt = "0.4"
cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
cortex-m-rt = "0.7.0"
panic-probe = { version = "0.3", features = ["print-defmt"] }
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }

View File

@ -0,0 +1,35 @@
//! This build script copies the `memory.x` file from the crate root into
//! a directory where the linker can always find it at build time.
//! For many projects this is optional, as the linker always searches the
//! project root directory -- wherever `Cargo.toml` is. However, if you
//! are using a workspace or have a more complicated build setup, this
//! build script becomes required. Additionally, by requesting that
//! Cargo re-run the build script whenever `memory.x` is changed,
//! updating `memory.x` ensures a rebuild of the application with the
//! new memory settings.
use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
fn main() {
// Put `memory.x` in our output directory and ensure it's
// on the linker search path.
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
File::create(out.join("memory.x"))
.unwrap()
.write_all(include_bytes!("memory.x"))
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
// By default, Cargo will re-run a build script whenever
// any file in the project changes. By specifying `memory.x`
// here, we ensure the build script is only re-run when
// `memory.x` is changed.
println!("cargo:rerun-if-changed=memory.x");
println!("cargo:rustc-link-arg-bins=--nmagic");
println!("cargo:rustc-link-arg-bins=-Tlink.x");
println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
}

View File

@ -0,0 +1,7 @@
MEMORY
{
/* NOTE 1 K = 1 KiBi = 1024 bytes */
/* These values correspond to the NRF52840 with Softdevices S140 7.0.1 */
FLASH : ORIGIN = 0x00000000, LENGTH = 1024K
RAM : ORIGIN = 0x20000000, LENGTH = 256K
}

View File

@ -0,0 +1,43 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use {defmt_rtt as _, panic_probe as _};
#[rtic::app(device = embassy_nrf, peripherals = false, dispatchers = [SWI0_EGU0, SWI1_EGU1])]
mod app {
use defmt::info;
use embassy_nrf::gpio::{Level, Output, OutputDrive};
use embassy_nrf::peripherals;
use embassy_time::{Duration, Timer};
#[shared]
struct Shared {}
#[local]
struct Local {}
#[init]
fn init(_: init::Context) -> (Shared, Local) {
info!("Hello World!");
let p = embassy_nrf::init(Default::default());
blink::spawn(p.P0_13).map_err(|_| ()).unwrap();
(Shared {}, Local {})
}
#[task(priority = 1)]
async fn blink(_cx: blink::Context, pin: peripherals::P0_13) {
let mut led = Output::new(pin, Level::Low, OutputDrive::Standard);
loop {
info!("off!");
led.set_high();
Timer::after(Duration::from_millis(300)).await;
info!("on!");
led.set_low();
Timer::after(Duration::from_millis(300)).await;
}
}
}

View File

@ -57,14 +57,11 @@
#![no_main] #![no_main]
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
use core::mem;
use cortex_m::peripheral::NVIC;
use cortex_m_rt::entry; use cortex_m_rt::entry;
use defmt::{info, unwrap}; use defmt::{info, unwrap};
use embassy_nrf::executor::{Executor, InterruptExecutor}; use embassy_executor::{Executor, InterruptExecutor};
use embassy_nrf::interrupt; use embassy_nrf::interrupt;
use embassy_nrf::pac::Interrupt; use embassy_nrf::interrupt::{InterruptExt, Priority};
use embassy_time::{Duration, Instant, Timer}; use embassy_time::{Duration, Instant, Timer};
use static_cell::StaticCell; use static_cell::StaticCell;
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
@ -130,16 +127,15 @@ fn main() -> ! {
info!("Hello World!"); info!("Hello World!");
let _p = embassy_nrf::init(Default::default()); let _p = embassy_nrf::init(Default::default());
let mut nvic: NVIC = unsafe { mem::transmute(()) };
// High-priority executor: SWI1_EGU1, priority level 6 // High-priority executor: SWI1_EGU1, priority level 6
unsafe { nvic.set_priority(Interrupt::SWI1_EGU1, 6 << 5) }; interrupt::SWI1_EGU1.set_priority(Priority::P6);
let spawner = EXECUTOR_HIGH.start(Interrupt::SWI1_EGU1); let spawner = EXECUTOR_HIGH.start(interrupt::SWI1_EGU1);
unwrap!(spawner.spawn(run_high())); unwrap!(spawner.spawn(run_high()));
// Medium-priority executor: SWI0_EGU0, priority level 7 // Medium-priority executor: SWI0_EGU0, priority level 7
unsafe { nvic.set_priority(Interrupt::SWI0_EGU0, 7 << 5) }; interrupt::SWI0_EGU0.set_priority(Priority::P7);
let spawner = EXECUTOR_MED.start(Interrupt::SWI0_EGU0); let spawner = EXECUTOR_MED.start(interrupt::SWI0_EGU0);
unwrap!(spawner.spawn(run_med())); unwrap!(spawner.spawn(run_med()));
// Low priority executor: runs in thread mode, using WFE/SEV // Low priority executor: runs in thread mode, using WFE/SEV

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