Merge branch 'main' into v4-optional
This commit is contained in:
commit
8a1d3d5c84
3
ci.sh
3
ci.sh
@ -3,7 +3,7 @@
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
export RUSTFLAGS=-Dwarnings
|
export RUSTFLAGS=-Dwarnings
|
||||||
export DEFMT_LOG=trace
|
export DEFMT_LOG=trace,cyw43=info,cyw43_pio=info,smoltcp=info
|
||||||
|
|
||||||
# needed by wifi examples
|
# needed by wifi examples
|
||||||
export WIFI_NETWORK=x
|
export WIFI_NETWORK=x
|
||||||
@ -112,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 \
|
||||||
|
@ -2,120 +2,208 @@
|
|||||||
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 embassy_cortex_m::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> {
|
|
||||||
/// Interrupt handler function.
|
|
||||||
///
|
|
||||||
/// Must be called every time the `I` interrupt fires, synchronously from
|
|
||||||
/// the interrupt handler context.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// This function must ONLY be called from the interrupt handler for `I`.
|
|
||||||
unsafe fn on_interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compile-time assertion that an interrupt has been bound to a handler.
|
/// Type-level interrupt infrastructure.
|
||||||
///
|
///
|
||||||
/// For the vast majority of cases, you should use the `bind_interrupts!`
|
/// This module contains one *type* per interrupt. This is used for checking at compile time that
|
||||||
/// macro instead of writing `unsafe impl`s of this trait.
|
/// the interrupts are correctly bound to HAL drivers.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// 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
|
||||||
/// By implementing this trait, you are asserting that you have arranged for `H::on_interrupt()`
|
/// interrupts directly (pending/unpending, enabling/disabling, setting the priority, etc...)
|
||||||
/// to be called every time the `I` interrupt fires.
|
pub mod typelevel {
|
||||||
///
|
use super::InterruptExt;
|
||||||
/// This allows drivers to check bindings at compile-time.
|
|
||||||
pub unsafe trait Binding<I: Interrupt, H: Handler<I>> {}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
mod sealed {
|
||||||
pub(crate) struct NrWrap(pub(crate) u16);
|
pub trait Interrupt {}
|
||||||
unsafe impl cortex_m::interrupt::InterruptNumber for NrWrap {
|
}
|
||||||
fn number(self) -> u16 {
|
|
||||||
self.0
|
/// 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.
|
||||||
|
///
|
||||||
|
/// Must be called every time the `I` interrupt fires, synchronously from
|
||||||
|
/// the interrupt handler context.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This function must ONLY be called from the interrupt handler for `I`.
|
||||||
|
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>> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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) }
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
@ -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()
|
|
||||||
}
|
|
||||||
|
@ -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)
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
@ -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;
|
||||||
|
@ -278,10 +278,18 @@ impl<'a> TcpSocket<'a> {
|
|||||||
self.io.with(|s, _| s.may_send())
|
self.io.with(|s, _| s.may_send())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get whether the socket is ready to receive data, i.e. whether there is some pending data in the receive buffer.
|
/// return whether the recieve half of the full-duplex connection is open.
|
||||||
|
/// This function returns true if it’s possible to receive data from the remote endpoint.
|
||||||
|
/// It will return true while there is data in the receive buffer, and if there isn’t,
|
||||||
|
/// as long as the remote endpoint has not closed the connection.
|
||||||
pub fn may_recv(&self) -> bool {
|
pub fn may_recv(&self) -> bool {
|
||||||
self.io.with(|s, _| s.may_recv())
|
self.io.with(|s, _| s.may_recv())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get whether the socket is ready to receive data, i.e. whether there is some pending data in the receive buffer.
|
||||||
|
pub fn can_recv(&self) -> bool {
|
||||||
|
self.io.with(|s, _| s.can_recv())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drop for TcpSocket<'a> {
|
impl<'a> Drop for TcpSocket<'a> {
|
||||||
|
@ -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",
|
||||||
|
@ -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,
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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_cortex_m::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);
|
|
||||||
}
|
|
||||||
|
@ -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() };
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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-cortex-m` 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
|
||||||
|
|
||||||
@ -136,9 +128,11 @@ pub use chip::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::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.
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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 }
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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 }
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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) => {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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"]
|
||||||
|
|
||||||
@ -41,6 +42,11 @@ boot2-ram-memcpy = []
|
|||||||
boot2-w25q080 = []
|
boot2-w25q080 = []
|
||||||
boot2-w25x10cl = []
|
boot2-w25x10cl = []
|
||||||
|
|
||||||
|
# Indicate code is running from RAM.
|
||||||
|
# Set this if all code is in RAM, and the cores never access memory-mapped flash memory through XIP.
|
||||||
|
# This allows the flash driver to not force pausing execution on both cores when doing flash operations.
|
||||||
|
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 = ["embassy-executor/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"]
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
@ -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>(
|
||||||
@ -75,16 +76,17 @@ pub unsafe fn write<'a, C: Channel, W: Word>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DUMMY: u32 = 0;
|
||||||
|
|
||||||
pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
|
pub unsafe fn write_repeated<'a, C: Channel, W: Word>(
|
||||||
ch: impl Peripheral<P = C> + 'a,
|
ch: impl Peripheral<P = C> + 'a,
|
||||||
to: *mut W,
|
to: *mut W,
|
||||||
len: usize,
|
len: usize,
|
||||||
dreq: u8,
|
dreq: u8,
|
||||||
) -> Transfer<'a, C> {
|
) -> Transfer<'a, C> {
|
||||||
let dummy: u32 = 0;
|
|
||||||
copy_inner(
|
copy_inner(
|
||||||
ch,
|
ch,
|
||||||
&dummy as *const u32,
|
&DUMMY as *const u32,
|
||||||
to as *mut u32,
|
to as *mut u32,
|
||||||
len,
|
len,
|
||||||
W::size(),
|
W::size(),
|
||||||
|
@ -9,7 +9,11 @@ use embedded_storage::nor_flash::{
|
|||||||
use crate::pac;
|
use crate::pac;
|
||||||
use crate::peripherals::FLASH;
|
use crate::peripherals::FLASH;
|
||||||
|
|
||||||
pub const FLASH_BASE: usize = 0x10000000;
|
pub const FLASH_BASE: *const u32 = 0x10000000 as _;
|
||||||
|
|
||||||
|
// If running from RAM, we might have no boot2. Use bootrom `flash_enter_cmd_xip` instead.
|
||||||
|
// TODO: when run-from-ram is set, completely skip the "pause cores and jumpp to RAM" dance.
|
||||||
|
pub const USE_BOOT2: bool = !cfg!(feature = "run-from-ram");
|
||||||
|
|
||||||
// **NOTE**:
|
// **NOTE**:
|
||||||
//
|
//
|
||||||
@ -63,8 +67,8 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
|||||||
pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
|
pub fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
|
||||||
trace!(
|
trace!(
|
||||||
"Reading from 0x{:x} to 0x{:x}",
|
"Reading from 0x{:x} to 0x{:x}",
|
||||||
FLASH_BASE + offset as usize,
|
FLASH_BASE as u32 + offset,
|
||||||
FLASH_BASE + offset as usize + bytes.len()
|
FLASH_BASE as u32 + offset + bytes.len() as u32
|
||||||
);
|
);
|
||||||
check_read(self, offset, bytes.len())?;
|
check_read(self, offset, bytes.len())?;
|
||||||
|
|
||||||
@ -89,7 +93,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
|||||||
|
|
||||||
let len = to - from;
|
let len = to - from;
|
||||||
|
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len, true))? };
|
unsafe { self.in_ram(|| ram_helpers::flash_range_erase(from, len))? };
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -114,7 +118,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
|||||||
|
|
||||||
let unaligned_offset = offset as usize - start;
|
let unaligned_offset = offset as usize - start;
|
||||||
|
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf, true))? }
|
unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
|
||||||
}
|
}
|
||||||
|
|
||||||
let remaining_len = bytes.len() - start_padding;
|
let remaining_len = bytes.len() - start_padding;
|
||||||
@ -132,12 +136,12 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
|||||||
if bytes.as_ptr() as usize >= 0x2000_0000 {
|
if bytes.as_ptr() as usize >= 0x2000_0000 {
|
||||||
let aligned_data = &bytes[start_padding..end_padding];
|
let aligned_data = &bytes[start_padding..end_padding];
|
||||||
|
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data, true))? }
|
unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, aligned_data))? }
|
||||||
} else {
|
} else {
|
||||||
for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) {
|
for chunk in bytes[start_padding..end_padding].chunks_exact(PAGE_SIZE) {
|
||||||
let mut ram_buf = [0xFF_u8; PAGE_SIZE];
|
let mut ram_buf = [0xFF_u8; PAGE_SIZE];
|
||||||
ram_buf.copy_from_slice(chunk);
|
ram_buf.copy_from_slice(chunk);
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf, true))? }
|
unsafe { self.in_ram(|| ram_helpers::flash_range_program(aligned_offset as u32, &ram_buf))? }
|
||||||
aligned_offset += PAGE_SIZE;
|
aligned_offset += PAGE_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,7 +156,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
|||||||
|
|
||||||
let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset);
|
let unaligned_offset = end_offset - (PAGE_SIZE - rem_offset);
|
||||||
|
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf, true))? }
|
unsafe { self.in_ram(|| ram_helpers::flash_range_program(unaligned_offset as u32, &pad_buf))? }
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -190,7 +194,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
|||||||
|
|
||||||
/// Read SPI flash unique ID
|
/// Read SPI flash unique ID
|
||||||
pub fn unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> {
|
pub fn unique_id(&mut self, uid: &mut [u8]) -> Result<(), Error> {
|
||||||
unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid, true))? };
|
unsafe { self.in_ram(|| ram_helpers::flash_unique_id(uid))? };
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +203,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> Flash<'d, T, FLASH_SIZE> {
|
|||||||
let mut jedec = None;
|
let mut jedec = None;
|
||||||
unsafe {
|
unsafe {
|
||||||
self.in_ram(|| {
|
self.in_ram(|| {
|
||||||
jedec.replace(ram_helpers::flash_jedec_id(true));
|
jedec.replace(ram_helpers::flash_jedec_id());
|
||||||
})?;
|
})?;
|
||||||
};
|
};
|
||||||
Ok(jedec.unwrap())
|
Ok(jedec.unwrap())
|
||||||
@ -242,6 +246,7 @@ impl<'d, T: Instance, const FLASH_SIZE: usize> NorFlash for Flash<'d, T, FLASH_S
|
|||||||
mod ram_helpers {
|
mod ram_helpers {
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
use crate::rom_data;
|
use crate::rom_data;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -306,7 +311,7 @@ mod ram_helpers {
|
|||||||
///
|
///
|
||||||
/// `addr` and `len` must be multiples of 4096
|
/// `addr` and `len` must be multiples of 4096
|
||||||
///
|
///
|
||||||
/// If `use_boot2` is `true`, a copy of the 2nd stage boot loader
|
/// If `USE_BOOT2` is `true`, a copy of the 2nd stage boot loader
|
||||||
/// is used to re-initialize the XIP engine after flashing.
|
/// is used to re-initialize the XIP engine after flashing.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -318,10 +323,10 @@ mod ram_helpers {
|
|||||||
/// - DMA must not access flash memory
|
/// - DMA must not access flash memory
|
||||||
///
|
///
|
||||||
/// `addr` and `len` parameters must be valid and are not checked.
|
/// `addr` and `len` parameters must be valid and are not checked.
|
||||||
pub unsafe fn flash_range_erase(addr: u32, len: u32, use_boot2: bool) {
|
pub unsafe fn flash_range_erase(addr: u32, len: u32) {
|
||||||
let mut boot2 = [0u32; 256 / 4];
|
let mut boot2 = [0u32; 256 / 4];
|
||||||
let ptrs = if use_boot2 {
|
let ptrs = if USE_BOOT2 {
|
||||||
rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256);
|
rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256);
|
||||||
flash_function_pointers_with_boot2(true, false, &boot2)
|
flash_function_pointers_with_boot2(true, false, &boot2)
|
||||||
} else {
|
} else {
|
||||||
flash_function_pointers(true, false)
|
flash_function_pointers(true, false)
|
||||||
@ -336,7 +341,7 @@ mod ram_helpers {
|
|||||||
///
|
///
|
||||||
/// `addr` and `data.len()` must be multiples of 4096
|
/// `addr` and `data.len()` must be multiples of 4096
|
||||||
///
|
///
|
||||||
/// If `use_boot2` is `true`, a copy of the 2nd stage boot loader
|
/// If `USE_BOOT2` is `true`, a copy of the 2nd stage boot loader
|
||||||
/// is used to re-initialize the XIP engine after flashing.
|
/// is used to re-initialize the XIP engine after flashing.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -348,10 +353,10 @@ mod ram_helpers {
|
|||||||
/// - DMA must not access flash memory
|
/// - DMA must not access flash memory
|
||||||
///
|
///
|
||||||
/// `addr` and `len` parameters must be valid and are not checked.
|
/// `addr` and `len` parameters must be valid and are not checked.
|
||||||
pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8], use_boot2: bool) {
|
pub unsafe fn flash_range_erase_and_program(addr: u32, data: &[u8]) {
|
||||||
let mut boot2 = [0u32; 256 / 4];
|
let mut boot2 = [0u32; 256 / 4];
|
||||||
let ptrs = if use_boot2 {
|
let ptrs = if USE_BOOT2 {
|
||||||
rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256);
|
rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256);
|
||||||
flash_function_pointers_with_boot2(true, true, &boot2)
|
flash_function_pointers_with_boot2(true, true, &boot2)
|
||||||
} else {
|
} else {
|
||||||
flash_function_pointers(true, true)
|
flash_function_pointers(true, true)
|
||||||
@ -371,7 +376,7 @@ mod ram_helpers {
|
|||||||
///
|
///
|
||||||
/// `addr` and `data.len()` must be multiples of 256
|
/// `addr` and `data.len()` must be multiples of 256
|
||||||
///
|
///
|
||||||
/// If `use_boot2` is `true`, a copy of the 2nd stage boot loader
|
/// If `USE_BOOT2` is `true`, a copy of the 2nd stage boot loader
|
||||||
/// is used to re-initialize the XIP engine after flashing.
|
/// is used to re-initialize the XIP engine after flashing.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
@ -383,10 +388,10 @@ mod ram_helpers {
|
|||||||
/// - DMA must not access flash memory
|
/// - DMA must not access flash memory
|
||||||
///
|
///
|
||||||
/// `addr` and `len` parameters must be valid and are not checked.
|
/// `addr` and `len` parameters must be valid and are not checked.
|
||||||
pub unsafe fn flash_range_program(addr: u32, data: &[u8], use_boot2: bool) {
|
pub unsafe fn flash_range_program(addr: u32, data: &[u8]) {
|
||||||
let mut boot2 = [0u32; 256 / 4];
|
let mut boot2 = [0u32; 256 / 4];
|
||||||
let ptrs = if use_boot2 {
|
let ptrs = if USE_BOOT2 {
|
||||||
rom_data::memcpy44(&mut boot2 as *mut _, super::FLASH_BASE as *const _, 256);
|
rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256);
|
||||||
flash_function_pointers_with_boot2(false, true, &boot2)
|
flash_function_pointers_with_boot2(false, true, &boot2)
|
||||||
} else {
|
} else {
|
||||||
flash_function_pointers(false, true)
|
flash_function_pointers(false, true)
|
||||||
@ -508,10 +513,10 @@ mod ram_helpers {
|
|||||||
/// - DMA must not access flash memory
|
/// - DMA must not access flash memory
|
||||||
///
|
///
|
||||||
/// Credit: taken from `rp2040-flash` (also licensed Apache+MIT)
|
/// Credit: taken from `rp2040-flash` (also licensed Apache+MIT)
|
||||||
pub unsafe fn flash_unique_id(out: &mut [u8], use_boot2: bool) {
|
pub unsafe fn flash_unique_id(out: &mut [u8]) {
|
||||||
let mut boot2 = [0u32; 256 / 4];
|
let mut boot2 = [0u32; 256 / 4];
|
||||||
let ptrs = if use_boot2 {
|
let ptrs = if USE_BOOT2 {
|
||||||
rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256);
|
rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256);
|
||||||
flash_function_pointers_with_boot2(false, false, &boot2)
|
flash_function_pointers_with_boot2(false, false, &boot2)
|
||||||
} else {
|
} else {
|
||||||
flash_function_pointers(false, false)
|
flash_function_pointers(false, false)
|
||||||
@ -536,10 +541,10 @@ mod ram_helpers {
|
|||||||
/// - DMA must not access flash memory
|
/// - DMA must not access flash memory
|
||||||
///
|
///
|
||||||
/// Credit: taken from `rp2040-flash` (also licensed Apache+MIT)
|
/// Credit: taken from `rp2040-flash` (also licensed Apache+MIT)
|
||||||
pub unsafe fn flash_jedec_id(use_boot2: bool) -> u32 {
|
pub unsafe fn flash_jedec_id() -> u32 {
|
||||||
let mut boot2 = [0u32; 256 / 4];
|
let mut boot2 = [0u32; 256 / 4];
|
||||||
let ptrs = if use_boot2 {
|
let ptrs = if USE_BOOT2 {
|
||||||
rom_data::memcpy44(&mut boot2 as *mut _, 0x10000000 as *const _, 256);
|
rom_data::memcpy44(&mut boot2 as *mut _, FLASH_BASE, 256);
|
||||||
flash_function_pointers_with_boot2(false, false, &boot2)
|
flash_function_pointers_with_boot2(false, false, &boot2)
|
||||||
} else {
|
} else {
|
||||||
flash_function_pointers(false, false)
|
flash_function_pointers(false, false)
|
||||||
@ -586,7 +591,6 @@ mod ram_helpers {
|
|||||||
"ldr r4, [r5, #4]",
|
"ldr r4, [r5, #4]",
|
||||||
"blx r4", // flash_exit_xip()
|
"blx r4", // flash_exit_xip()
|
||||||
|
|
||||||
"mov r7, r10", // cmd
|
|
||||||
|
|
||||||
"movs r4, #0x18",
|
"movs r4, #0x18",
|
||||||
"lsls r4, r4, #24", // 0x18000000, SSI, RP2040 datasheet 4.10.13
|
"lsls r4, r4, #24", // 0x18000000, SSI, RP2040 datasheet 4.10.13
|
||||||
@ -603,8 +607,9 @@ mod ram_helpers {
|
|||||||
"str r1, [r4, #0]",
|
"str r1, [r4, #0]",
|
||||||
|
|
||||||
// Write ctrlr1 with len-1
|
// Write ctrlr1 with len-1
|
||||||
"ldr r0, [r7, #8]", // dummy_len
|
"mov r3, r10", // cmd
|
||||||
"ldr r1, [r7, #16]", // data_len
|
"ldr r0, [r3, #8]", // dummy_len
|
||||||
|
"ldr r1, [r3, #16]", // data_len
|
||||||
"add r0, r1",
|
"add r0, r1",
|
||||||
"subs r0, #1",
|
"subs r0, #1",
|
||||||
"str r0, [r4, #0x04]", // CTRLR1
|
"str r0, [r4, #0x04]", // CTRLR1
|
||||||
@ -616,8 +621,8 @@ mod ram_helpers {
|
|||||||
// Write cmd/addr phase to DR
|
// Write cmd/addr phase to DR
|
||||||
"mov r2, r4",
|
"mov r2, r4",
|
||||||
"adds r2, 0x60", // &DR
|
"adds r2, 0x60", // &DR
|
||||||
"ldr r0, [r7, #0]", // cmd_addr
|
"ldr r0, [r3, #0]", // cmd_addr
|
||||||
"ldr r1, [r7, #4]", // cmd_addr_len
|
"ldr r1, [r3, #4]", // cmd_addr_len
|
||||||
"10:",
|
"10:",
|
||||||
"ldrb r3, [r0]",
|
"ldrb r3, [r0]",
|
||||||
"strb r3, [r2]", // DR
|
"strb r3, [r2]", // DR
|
||||||
@ -626,7 +631,8 @@ mod ram_helpers {
|
|||||||
"bne 10b",
|
"bne 10b",
|
||||||
|
|
||||||
// Skip any dummy cycles
|
// Skip any dummy cycles
|
||||||
"ldr r1, [r7, #8]", // dummy_len
|
"mov r3, r10", // cmd
|
||||||
|
"ldr r1, [r3, #8]", // dummy_len
|
||||||
"cmp r1, #0",
|
"cmp r1, #0",
|
||||||
"beq 9f",
|
"beq 9f",
|
||||||
"4:",
|
"4:",
|
||||||
@ -643,8 +649,9 @@ mod ram_helpers {
|
|||||||
|
|
||||||
// Read RX fifo
|
// Read RX fifo
|
||||||
"9:",
|
"9:",
|
||||||
"ldr r0, [r7, #12]", // data
|
"mov r2, r10", // cmd
|
||||||
"ldr r1, [r7, #16]", // data_len
|
"ldr r0, [r2, #12]", // data
|
||||||
|
"ldr r1, [r2, #16]", // data_len
|
||||||
|
|
||||||
"2:",
|
"2:",
|
||||||
"ldr r3, [r4, #0x28]", // SR
|
"ldr r3, [r4, #0x28]", // SR
|
||||||
@ -678,13 +685,12 @@ mod ram_helpers {
|
|||||||
out("r2") _,
|
out("r2") _,
|
||||||
out("r3") _,
|
out("r3") _,
|
||||||
out("r4") _,
|
out("r4") _,
|
||||||
|
out("r5") _,
|
||||||
// Registers r8-r10 are used to store values
|
// Registers r8-r10 are used to store values
|
||||||
// from r0-r2 in registers not clobbered by
|
// from r0-r2 in registers not clobbered by
|
||||||
// function calls.
|
// function calls.
|
||||||
// The values can't be passed in using r8-r10 directly
|
// The values can't be passed in using r8-r10 directly
|
||||||
// due to https://github.com/rust-lang/rust/issues/99071
|
// due to https://github.com/rust-lang/rust/issues/99071
|
||||||
out("r8") _,
|
|
||||||
out("r9") _,
|
|
||||||
out("r10") _,
|
out("r10") _,
|
||||||
clobber_abi("C"),
|
clobber_abi("C"),
|
||||||
);
|
);
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {}
|
|
||||||
)*
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
@ -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;
|
||||||
@ -38,13 +37,77 @@ pub mod relocate;
|
|||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use embassy_cortex_m::executor;
|
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_cortex_m::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-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::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,
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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() {
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -79,7 +79,9 @@ 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"]
|
||||||
|
rt = ["stm32-metapac/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"]
|
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"]
|
||||||
memory-x = ["stm32-metapac/memory-x"]
|
memory-x = ["stm32-metapac/memory-x"]
|
||||||
exti = []
|
exti = []
|
||||||
|
@ -160,13 +160,11 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
g.extend(quote! {
|
g.extend(quote! {
|
||||||
pub mod interrupt {
|
embassy_cortex_m::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 () {
|
||||||
#(
|
#(
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ 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::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();
|
||||||
|
@ -13,7 +13,7 @@ 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::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();
|
||||||
|
@ -12,7 +12,7 @@ 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::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();
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -72,52 +72,48 @@ 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.
|
||||||
|
///
|
||||||
|
/// 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;
|
||||||
|
|
||||||
/// Macro to bind interrupts to handlers.
|
$(
|
||||||
///
|
#[allow(non_snake_case)]
|
||||||
/// This defines the right interrupt handlers, and creates a unit struct (like `struct Irqs;`)
|
#[no_mangle]
|
||||||
/// and implements the right [`Binding`]s for it. You can pass this struct to drivers to
|
unsafe extern "C" fn $irq() {
|
||||||
/// 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`.
|
<$handler as $crate::interrupt::typelevel::Handler<$crate::interrupt::typelevel::$irq>>::on_interrupt();
|
||||||
#[macro_export]
|
)*
|
||||||
macro_rules! bind_interrupts {
|
}
|
||||||
($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
|
|
||||||
$vis struct $name;
|
|
||||||
|
|
||||||
$(
|
$(
|
||||||
#[allow(non_snake_case)]
|
unsafe impl $crate::interrupt::typelevel::Binding<$crate::interrupt::typelevel::$irq, $handler> for $name {}
|
||||||
#[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 {}
|
|
||||||
)*
|
|
||||||
)*
|
)*
|
||||||
};
|
)*
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use _generated::{peripherals, Peripherals};
|
pub use _generated::{peripherals, Peripherals};
|
||||||
pub use embassy_cortex_m::executor;
|
pub use embassy_cortex_m::executor;
|
||||||
use embassy_cortex_m::interrupt::Priority;
|
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;
|
||||||
|
|
||||||
|
#[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,
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
@ -2,7 +2,6 @@ use core::mem::MaybeUninit;
|
|||||||
|
|
||||||
use atomic_polyfill::{compiler_fence, Ordering};
|
use atomic_polyfill::{compiler_fence, Ordering};
|
||||||
use bit_field::BitField;
|
use bit_field::BitField;
|
||||||
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::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::channel::Channel;
|
use embassy_sync::channel::Channel;
|
||||||
@ -15,6 +14,7 @@ use self::shci::{shci_ble_init, ShciBleInitCmdParam};
|
|||||||
use self::sys::Sys;
|
use self::sys::Sys;
|
||||||
use self::unsafe_linked_list::LinkedListNode;
|
use self::unsafe_linked_list::LinkedListNode;
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
|
use crate::interrupt::InterruptExt;
|
||||||
use crate::peripherals::IPCC;
|
use crate::peripherals::IPCC;
|
||||||
pub use crate::tl_mbox::ipcc::Config;
|
pub use crate::tl_mbox::ipcc::Config;
|
||||||
use crate::tl_mbox::ipcc::Ipcc;
|
use crate::tl_mbox::ipcc::Ipcc;
|
||||||
@ -63,7 +63,7 @@ pub struct FusInfoTable {
|
|||||||
/// Interrupt handler.
|
/// Interrupt handler.
|
||||||
pub struct ReceiveInterruptHandler {}
|
pub struct ReceiveInterruptHandler {}
|
||||||
|
|
||||||
impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler {
|
impl interrupt::typelevel::Handler<interrupt::typelevel::IPCC_C1_RX> for ReceiveInterruptHandler {
|
||||||
unsafe fn on_interrupt() {
|
unsafe fn on_interrupt() {
|
||||||
// info!("ipcc rx interrupt");
|
// info!("ipcc rx interrupt");
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler {
|
|||||||
|
|
||||||
pub struct TransmitInterruptHandler {}
|
pub struct TransmitInterruptHandler {}
|
||||||
|
|
||||||
impl interrupt::Handler<interrupt::IPCC_C1_TX> for TransmitInterruptHandler {
|
impl interrupt::typelevel::Handler<interrupt::typelevel::IPCC_C1_TX> for TransmitInterruptHandler {
|
||||||
unsafe fn on_interrupt() {
|
unsafe fn on_interrupt() {
|
||||||
// info!("ipcc tx interrupt");
|
// info!("ipcc tx interrupt");
|
||||||
|
|
||||||
@ -324,8 +324,8 @@ impl<'d> TlMbox<'d> {
|
|||||||
/// initializes low-level transport between CPU1 and BLE stack on CPU2
|
/// initializes low-level transport between CPU1 and BLE stack on CPU2
|
||||||
pub fn new(
|
pub fn new(
|
||||||
ipcc: impl Peripheral<P = IPCC> + 'd,
|
ipcc: impl Peripheral<P = IPCC> + 'd,
|
||||||
_irqs: impl interrupt::Binding<interrupt::IPCC_C1_RX, ReceiveInterruptHandler>
|
_irqs: impl interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_RX, ReceiveInterruptHandler>
|
||||||
+ interrupt::Binding<interrupt::IPCC_C1_TX, TransmitInterruptHandler>,
|
+ interrupt::typelevel::Binding<interrupt::typelevel::IPCC_C1_TX, TransmitInterruptHandler>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(ipcc);
|
into_ref!(ipcc);
|
||||||
@ -379,11 +379,11 @@ impl<'d> TlMbox<'d> {
|
|||||||
MemoryManager::enable();
|
MemoryManager::enable();
|
||||||
|
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
crate::interrupt::IPCC_C1_RX::unpend();
|
crate::interrupt::IPCC_C1_RX.unpend();
|
||||||
crate::interrupt::IPCC_C1_TX::unpend();
|
crate::interrupt::IPCC_C1_TX.unpend();
|
||||||
|
|
||||||
unsafe { crate::interrupt::IPCC_C1_RX::enable() };
|
unsafe { crate::interrupt::IPCC_C1_RX.enable() };
|
||||||
unsafe { crate::interrupt::IPCC_C1_TX::enable() };
|
unsafe { crate::interrupt::IPCC_C1_TX.enable() };
|
||||||
|
|
||||||
Self { _ipcc: ipcc }
|
Self { _ipcc: ipcc }
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
|
9
examples/nrf52840-rtic/.cargo/config.toml
Normal file
9
examples/nrf52840-rtic/.cargo/config.toml
Normal 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"
|
21
examples/nrf52840-rtic/Cargo.toml
Normal file
21
examples/nrf52840-rtic/Cargo.toml
Normal 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"] }
|
35
examples/nrf52840-rtic/build.rs
Normal file
35
examples/nrf52840-rtic/build.rs
Normal 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");
|
||||||
|
}
|
7
examples/nrf52840-rtic/memory.x
Normal file
7
examples/nrf52840-rtic/memory.x
Normal 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
|
||||||
|
}
|
43
examples/nrf52840-rtic/src/bin/blinky.rs
Normal file
43
examples/nrf52840-rtic/src/bin/blinky.rs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,8 @@
|
|||||||
//! adapted from https://github.com/stm32-rs/stm32f7xx-hal/blob/master/build.rs
|
//! adapted from https://github.com/stm32-rs/stm32f7xx-hal/blob/master/build.rs
|
||||||
use std::env;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::io::{self};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::{env, io};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum Error {
|
enum Error {
|
||||||
|
8
tests/perf-server/Cargo.toml
Normal file
8
tests/perf-server/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "perf-server"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log = "0.4.17"
|
||||||
|
pretty_env_logger = "0.4.0"
|
11
tests/perf-server/deploy.sh
Executable file
11
tests/perf-server/deploy.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
HOST=root@192.168.1.3
|
||||||
|
|
||||||
|
cargo build --release
|
||||||
|
ssh $HOST -- systemctl stop perf-server
|
||||||
|
scp target/release/perf-server $HOST:/root
|
||||||
|
scp perf-server.service $HOST:/etc/systemd/system/
|
||||||
|
ssh $HOST -- 'systemctl daemon-reload; systemctl restart perf-server'
|
16
tests/perf-server/perf-server.service
Normal file
16
tests/perf-server/perf-server.service
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=perf-server
|
||||||
|
After=network.target
|
||||||
|
StartLimitIntervalSec=0
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Restart=always
|
||||||
|
RestartSec=1
|
||||||
|
User=root
|
||||||
|
ExecStart=/root/perf-server
|
||||||
|
Environment=RUST_BACKTRACE=1
|
||||||
|
Environment=RUST_LOG=info
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
90
tests/perf-server/src/main.rs
Normal file
90
tests/perf-server/src/main.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::net::{TcpListener, TcpStream};
|
||||||
|
use std::thread::spawn;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
pretty_env_logger::init();
|
||||||
|
spawn(|| rx_listen());
|
||||||
|
spawn(|| rxtx_listen());
|
||||||
|
tx_listen();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tx_listen() {
|
||||||
|
info!("tx: listening on 0.0.0.0:4321");
|
||||||
|
let listener = TcpListener::bind("0.0.0.0:4321").unwrap();
|
||||||
|
loop {
|
||||||
|
let (socket, addr) = listener.accept().unwrap();
|
||||||
|
info!("tx: received connection from: {}", addr);
|
||||||
|
spawn(|| tx_conn(socket));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tx_conn(mut socket: TcpStream) {
|
||||||
|
socket.set_read_timeout(Some(Duration::from_secs(30))).unwrap();
|
||||||
|
socket.set_write_timeout(Some(Duration::from_secs(30))).unwrap();
|
||||||
|
|
||||||
|
let buf = [0; 1024];
|
||||||
|
loop {
|
||||||
|
if let Err(e) = socket.write_all(&buf) {
|
||||||
|
info!("tx: failed to write to socket; err = {:?}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rx_listen() {
|
||||||
|
info!("rx: listening on 0.0.0.0:4322");
|
||||||
|
let listener = TcpListener::bind("0.0.0.0:4322").unwrap();
|
||||||
|
loop {
|
||||||
|
let (socket, addr) = listener.accept().unwrap();
|
||||||
|
info!("rx: received connection from: {}", addr);
|
||||||
|
spawn(|| rx_conn(socket));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rx_conn(mut socket: TcpStream) {
|
||||||
|
socket.set_read_timeout(Some(Duration::from_secs(30))).unwrap();
|
||||||
|
socket.set_write_timeout(Some(Duration::from_secs(30))).unwrap();
|
||||||
|
|
||||||
|
let mut buf = [0; 1024];
|
||||||
|
loop {
|
||||||
|
if let Err(e) = socket.read_exact(&mut buf) {
|
||||||
|
info!("rx: failed to read from socket; err = {:?}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rxtx_listen() {
|
||||||
|
info!("rxtx: listening on 0.0.0.0:4323");
|
||||||
|
let listener = TcpListener::bind("0.0.0.0:4323").unwrap();
|
||||||
|
loop {
|
||||||
|
let (socket, addr) = listener.accept().unwrap();
|
||||||
|
info!("rxtx: received connection from: {}", addr);
|
||||||
|
spawn(|| rxtx_conn(socket));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rxtx_conn(mut socket: TcpStream) {
|
||||||
|
socket.set_read_timeout(Some(Duration::from_secs(30))).unwrap();
|
||||||
|
socket.set_write_timeout(Some(Duration::from_secs(30))).unwrap();
|
||||||
|
|
||||||
|
let mut buf = [0; 1024];
|
||||||
|
loop {
|
||||||
|
match socket.read(&mut buf) {
|
||||||
|
Ok(n) => {
|
||||||
|
if let Err(e) = socket.write_all(&buf[..n]) {
|
||||||
|
info!("rxtx: failed to write to socket; err = {:?}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
info!("rxtx: failed to read from socket; err = {:?}", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,13 +5,16 @@ version = "0.1.0"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
teleprobe-meta = "1"
|
teleprobe-meta = "1.1"
|
||||||
|
|
||||||
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
|
embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] }
|
||||||
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
|
embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
|
||||||
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] }
|
embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] }
|
||||||
embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics"] }
|
embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] }
|
||||||
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
|
embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
|
||||||
|
embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] }
|
||||||
|
cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] }
|
||||||
|
cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] }
|
||||||
|
|
||||||
defmt = "0.3.0"
|
defmt = "0.3.0"
|
||||||
defmt-rtt = "0.4"
|
defmt-rtt = "0.4"
|
||||||
@ -25,6 +28,7 @@ panic-probe = { version = "0.3.0", features = ["print-defmt"] }
|
|||||||
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
futures = { version = "0.3.17", default-features = false, features = ["async-await"] }
|
||||||
embedded-io = { version = "0.4.0", features = ["async"] }
|
embedded-io = { version = "0.4.0", features = ["async"] }
|
||||||
embedded-storage = { version = "0.3" }
|
embedded-storage = { version = "0.3" }
|
||||||
|
static_cell = { version = "1.1", features = ["nightly"]}
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
debug = 2
|
debug = 2
|
||||||
|
267
tests/rp/src/bin/cyw43-perf.rs
Normal file
267
tests/rp/src/bin/cyw43-perf.rs
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
#[path = "../common.rs"]
|
||||||
|
mod common;
|
||||||
|
|
||||||
|
use cyw43_pio::PioSpi;
|
||||||
|
use defmt::{assert, panic, *};
|
||||||
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_futures::join::join;
|
||||||
|
use embassy_net::tcp::TcpSocket;
|
||||||
|
use embassy_net::{Config, Ipv4Address, Stack, StackResources};
|
||||||
|
use embassy_rp::gpio::{Level, Output};
|
||||||
|
use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0};
|
||||||
|
use embassy_rp::pio::Pio;
|
||||||
|
use embassy_rp::rom_data;
|
||||||
|
use embassy_time::{with_timeout, Duration, Timer};
|
||||||
|
use static_cell::make_static;
|
||||||
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
teleprobe_meta::timeout!(120);
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn wifi_task(
|
||||||
|
runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>,
|
||||||
|
) -> ! {
|
||||||
|
runner.run().await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::task]
|
||||||
|
async fn net_task(stack: &'static Stack<cyw43::NetDriver<'static>>) -> ! {
|
||||||
|
stack.run().await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[embassy_executor::main]
|
||||||
|
async fn main(spawner: Spawner) {
|
||||||
|
info!("Hello World!");
|
||||||
|
let p = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
|
// needed for reading the firmware from flash via XIP.
|
||||||
|
unsafe {
|
||||||
|
rom_data::flash_exit_xip();
|
||||||
|
rom_data::flash_enter_cmd_xip();
|
||||||
|
}
|
||||||
|
|
||||||
|
// cyw43 firmware needs to be flashed manually:
|
||||||
|
// probe-rs-cli download 43439A0.bin --format bin --chip RP2040 --base-address 0x101c0000
|
||||||
|
// probe-rs-cli download 43439A0_clm.bin --format bin --chip RP2040 --base-address 0x101f8000
|
||||||
|
let fw = unsafe { core::slice::from_raw_parts(0x101c0000 as *const u8, 224190) };
|
||||||
|
let clm = unsafe { core::slice::from_raw_parts(0x101f8000 as *const u8, 4752) };
|
||||||
|
|
||||||
|
let pwr = Output::new(p.PIN_23, Level::Low);
|
||||||
|
let cs = Output::new(p.PIN_25, Level::High);
|
||||||
|
let mut pio = Pio::new(p.PIO0);
|
||||||
|
let spi = PioSpi::new(&mut pio.common, pio.sm0, pio.irq0, cs, p.PIN_24, p.PIN_29, p.DMA_CH0);
|
||||||
|
|
||||||
|
let state = make_static!(cyw43::State::new());
|
||||||
|
let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw).await;
|
||||||
|
unwrap!(spawner.spawn(wifi_task(runner)));
|
||||||
|
|
||||||
|
control.init(clm).await;
|
||||||
|
control
|
||||||
|
.set_power_management(cyw43::PowerManagementMode::PowerSave)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let config = Config::Dhcp(Default::default());
|
||||||
|
//let config = embassy_net::Config::Static(embassy_net::Config {
|
||||||
|
// address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24),
|
||||||
|
// dns_servers: Vec::new(),
|
||||||
|
// gateway: Some(Ipv4Address::new(192, 168, 69, 1)),
|
||||||
|
//});
|
||||||
|
|
||||||
|
// Generate random seed
|
||||||
|
let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random.
|
||||||
|
|
||||||
|
// Init network stack
|
||||||
|
let stack = &*make_static!(Stack::new(
|
||||||
|
net_device,
|
||||||
|
config,
|
||||||
|
make_static!(StackResources::<2>::new()),
|
||||||
|
seed
|
||||||
|
));
|
||||||
|
|
||||||
|
unwrap!(spawner.spawn(net_task(stack)));
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await {
|
||||||
|
Ok(_) => break,
|
||||||
|
Err(err) => {
|
||||||
|
panic!("join failed with status={}", err.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
info!("Waiting for DHCP up...");
|
||||||
|
while stack.config().is_none() {
|
||||||
|
Timer::after(Duration::from_millis(100)).await;
|
||||||
|
}
|
||||||
|
info!("IP addressing up!");
|
||||||
|
|
||||||
|
let down = test_download(stack).await;
|
||||||
|
let up = test_upload(stack).await;
|
||||||
|
let updown = test_upload_download(stack).await;
|
||||||
|
|
||||||
|
assert!(down > TEST_EXPECTED_DOWNLOAD_KBPS);
|
||||||
|
assert!(up > TEST_EXPECTED_UPLOAD_KBPS);
|
||||||
|
assert!(updown > TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS);
|
||||||
|
|
||||||
|
info!("Test OK");
|
||||||
|
cortex_m::asm::bkpt();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test-only wifi network, no internet access!
|
||||||
|
const WIFI_NETWORK: &str = "EmbassyTest";
|
||||||
|
const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
|
||||||
|
|
||||||
|
const TEST_DURATION: usize = 10;
|
||||||
|
const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 500;
|
||||||
|
const TEST_EXPECTED_UPLOAD_KBPS: usize = 500;
|
||||||
|
const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 400;
|
||||||
|
const RX_BUFFER_SIZE: usize = 4096;
|
||||||
|
const TX_BUFFER_SIZE: usize = 4096;
|
||||||
|
const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2);
|
||||||
|
const DOWNLOAD_PORT: u16 = 4321;
|
||||||
|
const UPLOAD_PORT: u16 = 4322;
|
||||||
|
const UPLOAD_DOWNLOAD_PORT: u16 = 4323;
|
||||||
|
|
||||||
|
async fn test_download(stack: &'static Stack<cyw43::NetDriver<'static>>) -> usize {
|
||||||
|
info!("Testing download...");
|
||||||
|
|
||||||
|
let mut rx_buffer = [0; RX_BUFFER_SIZE];
|
||||||
|
let mut tx_buffer = [0; TX_BUFFER_SIZE];
|
||||||
|
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
||||||
|
socket.set_timeout(Some(Duration::from_secs(10)));
|
||||||
|
|
||||||
|
info!("connecting to {:?}:{}...", SERVER_ADDRESS, DOWNLOAD_PORT);
|
||||||
|
if let Err(e) = socket.connect((SERVER_ADDRESS, DOWNLOAD_PORT)).await {
|
||||||
|
error!("connect error: {:?}", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
info!("connected, testing...");
|
||||||
|
|
||||||
|
let mut rx_buf = [0; 4096];
|
||||||
|
let mut total: usize = 0;
|
||||||
|
with_timeout(Duration::from_secs(TEST_DURATION as _), async {
|
||||||
|
loop {
|
||||||
|
match socket.read(&mut rx_buf).await {
|
||||||
|
Ok(0) => {
|
||||||
|
error!("read EOF");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Ok(n) => total += n,
|
||||||
|
Err(e) => {
|
||||||
|
error!("read error: {:?}", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
let kbps = (total + 512) / 1024 / TEST_DURATION;
|
||||||
|
info!("download: {} kB/s", kbps);
|
||||||
|
kbps
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn test_upload(stack: &'static Stack<cyw43::NetDriver<'static>>) -> usize {
|
||||||
|
info!("Testing upload...");
|
||||||
|
|
||||||
|
let mut rx_buffer = [0; RX_BUFFER_SIZE];
|
||||||
|
let mut tx_buffer = [0; TX_BUFFER_SIZE];
|
||||||
|
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
||||||
|
socket.set_timeout(Some(Duration::from_secs(10)));
|
||||||
|
|
||||||
|
info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_PORT);
|
||||||
|
if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_PORT)).await {
|
||||||
|
error!("connect error: {:?}", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
info!("connected, testing...");
|
||||||
|
|
||||||
|
let buf = [0; 4096];
|
||||||
|
let mut total: usize = 0;
|
||||||
|
with_timeout(Duration::from_secs(TEST_DURATION as _), async {
|
||||||
|
loop {
|
||||||
|
match socket.write(&buf).await {
|
||||||
|
Ok(0) => {
|
||||||
|
error!("write zero?!??!?!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Ok(n) => total += n,
|
||||||
|
Err(e) => {
|
||||||
|
error!("write error: {:?}", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
let kbps = (total + 512) / 1024 / TEST_DURATION;
|
||||||
|
info!("upload: {} kB/s", kbps);
|
||||||
|
kbps
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn test_upload_download(stack: &'static Stack<cyw43::NetDriver<'static>>) -> usize {
|
||||||
|
info!("Testing upload+download...");
|
||||||
|
|
||||||
|
let mut rx_buffer = [0; RX_BUFFER_SIZE];
|
||||||
|
let mut tx_buffer = [0; TX_BUFFER_SIZE];
|
||||||
|
let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
|
||||||
|
socket.set_timeout(Some(Duration::from_secs(10)));
|
||||||
|
|
||||||
|
info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT);
|
||||||
|
if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT)).await {
|
||||||
|
error!("connect error: {:?}", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
info!("connected, testing...");
|
||||||
|
|
||||||
|
let (mut reader, mut writer) = socket.split();
|
||||||
|
|
||||||
|
let tx_buf = [0; 4096];
|
||||||
|
let mut rx_buf = [0; 4096];
|
||||||
|
let mut total: usize = 0;
|
||||||
|
let tx_fut = async {
|
||||||
|
loop {
|
||||||
|
match writer.write(&tx_buf).await {
|
||||||
|
Ok(0) => {
|
||||||
|
error!("write zero?!??!?!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
error!("write error: {:?}", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let rx_fut = async {
|
||||||
|
loop {
|
||||||
|
match reader.read(&mut rx_buf).await {
|
||||||
|
Ok(0) => {
|
||||||
|
error!("read EOF");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Ok(n) => total += n,
|
||||||
|
Err(e) => {
|
||||||
|
error!("read error: {:?}", e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
with_timeout(Duration::from_secs(TEST_DURATION as _), join(tx_fut, rx_fut))
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
let kbps = (total + 512) / 1024 / TEST_DURATION;
|
||||||
|
info!("upload+download: {} kB/s", kbps);
|
||||||
|
kbps
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user