From 15c3e78408a2835003b9d7dee0b7fbae544d10ba Mon Sep 17 00:00:00 2001 From: Thales Fragoso Date: Sun, 7 Mar 2021 20:15:40 -0300 Subject: [PATCH] Move nRF's util into a separate crate --- Cargo.toml | 1 + embassy-extras/Cargo.toml | 19 +++ embassy-extras/src/fmt.rs | 119 ++++++++++++++++++ .../util/mod.rs => embassy-extras/src/lib.rs | 5 + .../util => embassy-extras/src}/peripheral.rs | 5 +- .../src}/ring_buffer.rs | 0 embassy-nrf/Cargo.toml | 1 + embassy-nrf/src/buffered_uarte.rs | 8 +- embassy-nrf/src/lib.rs | 1 - embassy-nrf/src/qspi.rs | 3 +- embassy-nrf/src/spim.rs | 2 +- embassy-nrf/src/uarte.rs | 6 +- 12 files changed, 157 insertions(+), 13 deletions(-) create mode 100644 embassy-extras/Cargo.toml create mode 100644 embassy-extras/src/fmt.rs rename embassy-nrf/src/util/mod.rs => embassy-extras/src/lib.rs (80%) rename {embassy-nrf/src/util => embassy-extras/src}/peripheral.rs (96%) rename {embassy-nrf/src/util => embassy-extras/src}/ring_buffer.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 80ae9374..06943731 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "embassy-nrf-examples", "embassy-stm32f4-examples", "embassy-macros", + "embassy-extras", ] # embassy-std enables std-only features. Since Cargo resolves all features diff --git a/embassy-extras/Cargo.toml b/embassy-extras/Cargo.toml new file mode 100644 index 00000000..3c42b5c2 --- /dev/null +++ b/embassy-extras/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "embassy-extras" +version = "0.1.0" +authors = ["Dario Nieuwenhuis "] +edition = "2018" + +[features] +defmt-trace = [ ] +defmt-debug = [ ] +defmt-info = [ ] +defmt-warn = [ ] +defmt-error = [ ] + +[dependencies] +embassy = { version = "0.1.0", path = "../embassy" } + +defmt = { version = "0.2.0", optional = true } +log = { version = "0.4.11", optional = true } +cortex-m = "0.7.1" diff --git a/embassy-extras/src/fmt.rs b/embassy-extras/src/fmt.rs new file mode 100644 index 00000000..1be1057a --- /dev/null +++ b/embassy-extras/src/fmt.rs @@ -0,0 +1,119 @@ +#![macro_use] +#![allow(clippy::module_inception)] + +#[cfg(all(feature = "defmt", feature = "log"))] +compile_error!("You may not enable both `defmt` and `log` features."); + +pub use fmt::*; + +#[cfg(feature = "defmt")] +mod fmt { + pub use defmt::{ + assert, assert_eq, assert_ne, debug, debug_assert, debug_assert_eq, debug_assert_ne, error, + info, panic, todo, trace, unreachable, unwrap, warn, + }; +} + +#[cfg(feature = "log")] +mod fmt { + pub use core::{ + assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo, + unreachable, + }; + pub use log::{debug, error, info, trace, warn}; +} + +#[cfg(not(any(feature = "defmt", feature = "log")))] +mod fmt { + #![macro_use] + + pub use core::{ + assert, assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, panic, todo, + unreachable, + }; + + #[macro_export] + macro_rules! trace { + ($($msg:expr),+ $(,)?) => { + () + }; + } + + #[macro_export] + macro_rules! debug { + ($($msg:expr),+ $(,)?) => { + () + }; + } + + #[macro_export] + macro_rules! info { + ($($msg:expr),+ $(,)?) => { + () + }; + } + + #[macro_export] + macro_rules! warn { + ($($msg:expr),+ $(,)?) => { + () + }; + } + + #[macro_export] + macro_rules! error { + ($($msg:expr),+ $(,)?) => { + () + }; + } +} + +#[cfg(not(feature = "defmt"))] +#[macro_export] +macro_rules! unwrap { + ($arg:expr) => { + match $crate::fmt::Try::into_result($arg) { + ::core::result::Result::Ok(t) => t, + ::core::result::Result::Err(e) => { + ::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e); + } + } + }; + ($arg:expr, $($msg:expr),+ $(,)? ) => { + match $crate::fmt::Try::into_result($arg) { + ::core::result::Result::Ok(t) => t, + ::core::result::Result::Err(e) => { + ::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e); + } + } + } +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub struct NoneError; + +pub trait Try { + type Ok; + type Error; + fn into_result(self) -> Result; +} + +impl Try for Option { + type Ok = T; + type Error = NoneError; + + #[inline] + fn into_result(self) -> Result { + self.ok_or(NoneError) + } +} + +impl Try for Result { + type Ok = T; + type Error = E; + + #[inline] + fn into_result(self) -> Self { + self + } +} diff --git a/embassy-nrf/src/util/mod.rs b/embassy-extras/src/lib.rs similarity index 80% rename from embassy-nrf/src/util/mod.rs rename to embassy-extras/src/lib.rs index cf330654..4a95173c 100644 --- a/embassy-nrf/src/util/mod.rs +++ b/embassy-extras/src/lib.rs @@ -1,3 +1,8 @@ +#![no_std] + +// This mod MUST go first, so that the others see its macros. +pub(crate) mod fmt; + pub mod peripheral; pub mod ring_buffer; diff --git a/embassy-nrf/src/util/peripheral.rs b/embassy-extras/src/peripheral.rs similarity index 96% rename from embassy-nrf/src/util/peripheral.rs rename to embassy-extras/src/peripheral.rs index bb88f082..e9357969 100644 --- a/embassy-nrf/src/util/peripheral.rs +++ b/embassy-extras/src/peripheral.rs @@ -4,10 +4,9 @@ use core::mem::MaybeUninit; use core::pin::Pin; use core::sync::atomic::{compiler_fence, Ordering}; -use embassy::interrupt::InterruptExt; +use embassy::interrupt::{Interrupt, InterruptExt}; -use crate::fmt::{assert, *}; -use crate::interrupt::Interrupt; +use crate::fmt::assert; pub trait PeripheralState { type Interrupt: Interrupt; diff --git a/embassy-nrf/src/util/ring_buffer.rs b/embassy-extras/src/ring_buffer.rs similarity index 100% rename from embassy-nrf/src/util/ring_buffer.rs rename to embassy-extras/src/ring_buffer.rs diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 419b7f33..026e815f 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -20,6 +20,7 @@ defmt-error = [ ] [dependencies] embassy = { version = "0.1.0", path = "../embassy" } +embassy-extras = {version = "0.1.0", path = "../embassy-extras" } defmt = { version = "0.2.0", optional = true } log = { version = "0.4.11", optional = true } diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 848687f7..b1366cd9 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs @@ -13,14 +13,15 @@ use core::task::{Context, Poll}; use embassy::interrupt::InterruptExt; use embassy::io::{AsyncBufRead, AsyncWrite, Result}; use embassy::util::WakerRegistration; +use embassy_extras::low_power_wait_until; +use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; +use embassy_extras::ring_buffer::RingBuffer; use embedded_hal::digital::v2::OutputPin; +use crate::fmt::*; use crate::hal::ppi::ConfigurablePpi; use crate::interrupt::{self, Interrupt}; use crate::pac; -use crate::util::peripheral::{PeripheralMutex, PeripheralState}; -use crate::util::ring_buffer::RingBuffer; -use crate::{fmt::*, util::low_power_wait_until}; // Re-export SVD variants to allow user to directly set values pub use crate::hal::uarte::Pins; @@ -116,7 +117,6 @@ impl<'a, U: Instance, T: TimerInstance, P1: ConfigurablePpi, P2: ConfigurablePpi } }); - // Enable UARTE instance uarte.enable.write(|w| w.enable().enabled()); diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 3de6299e..bb37ec36 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -90,7 +90,6 @@ pub(crate) fn slice_in_ram_or(slice: &[u8], err: T) -> Result<(), T> { // This mod MUST go first, so that the others see its macros. pub(crate) mod fmt; -pub(crate) mod util; pub mod buffered_uarte; pub mod gpiote; diff --git a/embassy-nrf/src/qspi.rs b/embassy-nrf/src/qspi.rs index 1dc178f2..f6e8175f 100644 --- a/embassy-nrf/src/qspi.rs +++ b/embassy-nrf/src/qspi.rs @@ -2,6 +2,8 @@ use core::future::Future; use core::pin::Pin; use core::task::Poll; +use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; + use crate::fmt::{assert, assert_eq, *}; use crate::hal::gpio::{Output, Pin as GpioPin, PushPull}; use crate::interrupt::{self}; @@ -11,7 +13,6 @@ pub use crate::pac::qspi::ifconfig0::ADDRMODE_A as AddressMode; pub use crate::pac::qspi::ifconfig0::PPSIZE_A as WritePageSize; pub use crate::pac::qspi::ifconfig0::READOC_A as ReadOpcode; pub use crate::pac::qspi::ifconfig0::WRITEOC_A as WriteOpcode; -use crate::util::peripheral::{PeripheralMutex, PeripheralState}; // TODO // - config: diff --git a/embassy-nrf/src/spim.rs b/embassy-nrf/src/spim.rs index b7232963..4921bae3 100644 --- a/embassy-nrf/src/spim.rs +++ b/embassy-nrf/src/spim.rs @@ -3,10 +3,10 @@ use core::pin::Pin; use core::sync::atomic::{compiler_fence, Ordering}; use core::task::Poll; use embassy::util::WakerRegistration; +use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; use futures::future::poll_fn; use crate::interrupt::{self, Interrupt}; -use crate::util::peripheral::{PeripheralMutex, PeripheralState}; use crate::{pac, slice_in_ram_or}; pub use crate::hal::spim::{ diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs index aea01f95..b5e4da86 100644 --- a/embassy-nrf/src/uarte.rs +++ b/embassy-nrf/src/uarte.rs @@ -16,8 +16,8 @@ use crate::fmt::{assert, *}; use crate::hal::pac; use crate::hal::prelude::*; use crate::hal::target_constants::EASY_DMA_SIZE; +use crate::interrupt; use crate::interrupt::Interrupt; -use crate::{interrupt, util}; pub use crate::hal::uarte::Pins; // Re-export SVD variants to allow user to directly set values. @@ -45,7 +45,7 @@ where /// Creates the interface to a UARTE instance. /// Sets the baud rate, parity and assigns the pins to the UARTE peripheral. /// - /// # Unsafe + /// # Safety /// /// The returned API is safe unless you use `mem::forget` (or similar safe mechanisms) /// on stack allocated buffers which which have been passed to [`send()`](Uarte::send) @@ -327,7 +327,7 @@ where .tasks_stoprx .write(|w| unsafe { w.bits(1) }); - util::low_power_wait_until(|| T::state().rx_done.signaled()) + embassy_extras::low_power_wait_until(|| T::state().rx_done.signaled()) } } }