Merge remote-tracking branch 'origin/master' into nrf-pdm
This commit is contained in:
@ -18,7 +18,7 @@ flavors = [
|
||||
|
||||
time = ["dep:embassy-time"]
|
||||
|
||||
defmt = ["dep:defmt", "embassy-executor/defmt", "embassy-util/defmt", "embassy-usb?/defmt", "embedded-io?/defmt", "embassy-embedded-hal/defmt"]
|
||||
defmt = ["dep:defmt", "embassy-executor/defmt", "embassy-sync/defmt", "embassy-usb?/defmt", "embedded-io?/defmt", "embassy-embedded-hal/defmt"]
|
||||
|
||||
# Enable nightly-only features
|
||||
nightly = ["embedded-hal-1", "embedded-hal-async", "embassy-usb", "embedded-storage-async", "dep:embedded-io", "embassy-embedded-hal/nightly"]
|
||||
@ -66,7 +66,7 @@ _gpio-p1 = []
|
||||
[dependencies]
|
||||
embassy-executor = { version = "0.1.0", path = "../embassy-executor", optional = true }
|
||||
embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true }
|
||||
embassy-util = { version = "0.1.0", path = "../embassy-util" }
|
||||
embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
|
||||
embassy-cortex-m = { version = "0.1.0", path = "../embassy-cortex-m", features = ["prio-bits-3"]}
|
||||
embassy-hal-common = {version = "0.1.0", path = "../embassy-hal-common" }
|
||||
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
|
||||
|
@ -21,7 +21,7 @@ use core::task::Poll;
|
||||
use embassy_cortex_m::peripheral::{PeripheralMutex, PeripheralState, StateStorage};
|
||||
use embassy_hal_common::ring_buffer::RingBuffer;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_util::waitqueue::WakerRegistration;
|
||||
use embassy_sync::waitqueue::WakerRegistration;
|
||||
use futures::future::poll_fn;
|
||||
// Re-export SVD variants to allow user to directly set values
|
||||
pub use pac::uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
|
||||
@ -45,8 +45,10 @@ enum TxState {
|
||||
Transmitting(usize),
|
||||
}
|
||||
|
||||
/// A type for storing the state of the UARTE peripheral that can be stored in a static.
|
||||
pub struct State<'d, U: UarteInstance, T: TimerInstance>(StateStorage<StateInner<'d, U, T>>);
|
||||
impl<'d, U: UarteInstance, T: TimerInstance> State<'d, U, T> {
|
||||
/// Create an instance for storing UARTE peripheral state.
|
||||
pub fn new() -> Self {
|
||||
Self(StateStorage::new())
|
||||
}
|
||||
@ -75,6 +77,12 @@ pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> {
|
||||
impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {}
|
||||
|
||||
impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
||||
/// Create a new instance of a BufferedUarte.
|
||||
///
|
||||
/// See the [module documentation](crate::buffered_uarte) for more details about the intended use.
|
||||
///
|
||||
/// The BufferedUarte uses the provided state to store the buffers and peripheral state. The timer and ppi channels are used to 'emulate' idle line detection so that read operations
|
||||
/// can return early if there is no data to receive.
|
||||
pub fn new(
|
||||
state: &'d mut State<'d, U, T>,
|
||||
peri: impl Peripheral<P = U> + 'd,
|
||||
@ -178,6 +186,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Adjust the baud rate to the provided value.
|
||||
pub fn set_baudrate(&mut self, baudrate: Baudrate) {
|
||||
self.inner.with(|state| {
|
||||
let r = U::regs();
|
||||
|
@ -1,3 +1,4 @@
|
||||
//! General purpose input/output for nRF.
|
||||
#![macro_use]
|
||||
|
||||
use core::convert::Infallible;
|
||||
@ -26,8 +27,11 @@ pub enum Port {
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Pull {
|
||||
/// No pull.
|
||||
None,
|
||||
/// Internal pull-up resistor.
|
||||
Up,
|
||||
/// Internal pull-down resistor.
|
||||
Down,
|
||||
}
|
||||
|
||||
@ -37,6 +41,7 @@ pub struct Input<'d, T: Pin> {
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Input<'d, T> {
|
||||
/// Create GPIO input driver for a [Pin] with the provided [Pull] configuration.
|
||||
#[inline]
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, pull: Pull) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
@ -45,11 +50,13 @@ impl<'d, T: Pin> Input<'d, T> {
|
||||
Self { pin }
|
||||
}
|
||||
|
||||
/// Test if current pin level is high.
|
||||
#[inline]
|
||||
pub fn is_high(&self) -> bool {
|
||||
self.pin.is_high()
|
||||
}
|
||||
|
||||
/// Test if current pin level is low.
|
||||
#[inline]
|
||||
pub fn is_low(&self) -> bool {
|
||||
self.pin.is_low()
|
||||
@ -66,7 +73,9 @@ impl<'d, T: Pin> Input<'d, T> {
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Level {
|
||||
/// Logical low.
|
||||
Low,
|
||||
/// Logical high.
|
||||
High,
|
||||
}
|
||||
|
||||
@ -88,6 +97,7 @@ impl Into<bool> for Level {
|
||||
}
|
||||
}
|
||||
|
||||
/// Drive strength settings for an output pin.
|
||||
// These numbers match DRIVE_A exactly so hopefully the compiler will unify them.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
@ -117,6 +127,7 @@ pub struct Output<'d, T: Pin> {
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Output<'d, T> {
|
||||
/// Create GPIO output driver for a [Pin] with the provided [Level] and [OutputDriver] configuration.
|
||||
#[inline]
|
||||
pub fn new(pin: impl Peripheral<P = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self {
|
||||
let mut pin = Flex::new(pin);
|
||||
@ -264,11 +275,13 @@ impl<'d, T: Pin> Flex<'d, T> {
|
||||
self.pin.conf().reset();
|
||||
}
|
||||
|
||||
/// Test if current pin level is high.
|
||||
#[inline]
|
||||
pub fn is_high(&self) -> bool {
|
||||
!self.is_low()
|
||||
}
|
||||
|
||||
/// Test if current pin level is low.
|
||||
#[inline]
|
||||
pub fn is_low(&self) -> bool {
|
||||
self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0
|
||||
@ -374,6 +387,7 @@ pub(crate) mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
/// Interface for a Pin that can be configured by an [Input] or [Output] driver, or converted to an [AnyPin].
|
||||
pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'static {
|
||||
/// Number of the pin within the port (0..31)
|
||||
#[inline]
|
||||
@ -392,6 +406,7 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'stat
|
||||
}
|
||||
}
|
||||
|
||||
/// Peripheral port register value
|
||||
#[inline]
|
||||
fn psel_bits(&self) -> u32 {
|
||||
self.pin_port() as u32
|
||||
@ -406,12 +421,16 @@ pub trait Pin: Peripheral<P = Self> + Into<AnyPin> + sealed::Pin + Sized + 'stat
|
||||
}
|
||||
}
|
||||
|
||||
// Type-erased GPIO pin
|
||||
/// Type-erased GPIO pin
|
||||
pub struct AnyPin {
|
||||
pin_port: u8,
|
||||
}
|
||||
|
||||
impl AnyPin {
|
||||
/// Create an [AnyPin] for a specific pin.
|
||||
///
|
||||
/// # Safety
|
||||
/// - `pin_port` should not in use by another driver.
|
||||
#[inline]
|
||||
pub unsafe fn steal(pin_port: u8) -> Self {
|
||||
Self { pin_port }
|
||||
|
@ -3,7 +3,7 @@ use core::future::Future;
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use embassy_hal_common::{impl_peripheral, Peripheral, PeripheralRef};
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
|
@ -1,4 +1,4 @@
|
||||
//! Nvmcerature sensor interface.
|
||||
//! Non-Volatile Memory Controller (NVMC) module.
|
||||
|
||||
use core::{ptr, slice};
|
||||
|
||||
@ -10,13 +10,19 @@ use embedded_storage::nor_flash::{
|
||||
use crate::peripherals::NVMC;
|
||||
use crate::{pac, Peripheral};
|
||||
|
||||
/// Erase size of NVMC flash in bytes.
|
||||
pub const PAGE_SIZE: usize = 4096;
|
||||
|
||||
/// Size of NVMC flash in bytes.
|
||||
pub const FLASH_SIZE: usize = crate::chip::FLASH_SIZE;
|
||||
|
||||
/// Error type for NVMC operations.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Error {
|
||||
/// Opration using a location not in flash.
|
||||
OutOfBounds,
|
||||
/// Unaligned operation or using unaligned buffers.
|
||||
Unaligned,
|
||||
}
|
||||
|
||||
@ -29,11 +35,13 @@ impl NorFlashError for Error {
|
||||
}
|
||||
}
|
||||
|
||||
/// Non-Volatile Memory Controller (NVMC) that implements the `embedded-storage` traits.
|
||||
pub struct Nvmc<'d> {
|
||||
_p: PeripheralRef<'d, NVMC>,
|
||||
}
|
||||
|
||||
impl<'d> Nvmc<'d> {
|
||||
/// Create Nvmc driver.
|
||||
pub fn new(_p: impl Peripheral<P = NVMC> + 'd) -> Self {
|
||||
into_ref!(_p);
|
||||
Self { _p }
|
||||
|
@ -26,6 +26,7 @@ mod dppi;
|
||||
#[cfg(feature = "_ppi")]
|
||||
mod ppi;
|
||||
|
||||
/// An instance of the Programmable peripheral interconnect on nRF devices.
|
||||
pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize> {
|
||||
ch: PeripheralRef<'d, C>,
|
||||
#[cfg(feature = "_dppi")]
|
||||
@ -34,20 +35,32 @@ pub struct Ppi<'d, C: Channel, const EVENT_COUNT: usize, const TASK_COUNT: usize
|
||||
tasks: [Task; TASK_COUNT],
|
||||
}
|
||||
|
||||
#[cfg(feature = "_dppi")]
|
||||
const REGISTER_DPPI_CONFIG_OFFSET: usize = 0x80 / core::mem::size_of::<u32>();
|
||||
|
||||
/// Represents a task that a peripheral can do.
|
||||
/// When a task is subscribed to a PPI channel it will run when the channel is triggered by
|
||||
/// a published event.
|
||||
///
|
||||
/// The pointer is to a task register
|
||||
/// When a task is subscribed to a PPI channel, it will run when the channel is triggered by
|
||||
/// a published event.
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub struct Task(pub NonNull<u32>);
|
||||
pub struct Task(NonNull<u32>);
|
||||
|
||||
impl Task {
|
||||
/// Create a new `Task` from a task register pointer
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `ptr` must be a pointer to a valid `TASKS_*` register from an nRF peripheral.
|
||||
pub unsafe fn new_unchecked(ptr: NonNull<u32>) -> Self {
|
||||
Self(ptr)
|
||||
}
|
||||
|
||||
pub(crate) fn from_reg<T>(reg: &T) -> Self {
|
||||
Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
|
||||
}
|
||||
|
||||
/// Address of subscription register for this task.
|
||||
#[cfg(feature = "_dppi")]
|
||||
pub fn subscribe_reg(&self) -> *mut u32 {
|
||||
unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) }
|
||||
}
|
||||
@ -59,16 +72,27 @@ impl Task {
|
||||
unsafe impl Send for Task {}
|
||||
|
||||
/// Represents an event that a peripheral can publish.
|
||||
/// An event can be set to publish on a PPI channel when the event happens.
|
||||
///
|
||||
/// The pointer is to an event register
|
||||
/// An event can be set to publish on a PPI channel when the event happens.
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub struct Event(pub NonNull<u32>);
|
||||
pub struct Event(NonNull<u32>);
|
||||
|
||||
impl Event {
|
||||
/// Create a new `Event` from an event register pointer
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `ptr` must be a pointer to a valid `EVENTS_*` register from an nRF peripheral.
|
||||
pub unsafe fn new_unchecked(ptr: NonNull<u32>) -> Self {
|
||||
Self(ptr)
|
||||
}
|
||||
|
||||
pub(crate) fn from_reg<T>(reg: &T) -> Self {
|
||||
Self(unsafe { NonNull::new_unchecked(reg as *const _ as *mut _) })
|
||||
}
|
||||
|
||||
/// Address of publish register for this event.
|
||||
#[cfg(feature = "_dppi")]
|
||||
pub fn publish_reg(&self) -> *mut u32 {
|
||||
unsafe { self.0.as_ptr().add(REGISTER_DPPI_CONFIG_OFFSET) }
|
||||
}
|
||||
@ -87,21 +111,29 @@ pub(crate) mod sealed {
|
||||
pub trait Group {}
|
||||
}
|
||||
|
||||
/// Interface for PPI channels.
|
||||
pub trait Channel: sealed::Channel + Peripheral<P = Self> + Sized {
|
||||
/// Returns the number of the channel
|
||||
fn number(&self) -> usize;
|
||||
}
|
||||
|
||||
/// Interface for PPI channels that can be configured.
|
||||
pub trait ConfigurableChannel: Channel + Into<AnyConfigurableChannel> {
|
||||
/// Convert into a type erased configurable channel.
|
||||
fn degrade(self) -> AnyConfigurableChannel;
|
||||
}
|
||||
|
||||
/// Interface for PPI channels that cannot be configured.
|
||||
pub trait StaticChannel: Channel + Into<AnyStaticChannel> {
|
||||
/// Convert into a type erased static channel.
|
||||
fn degrade(self) -> AnyStaticChannel;
|
||||
}
|
||||
|
||||
/// Interface for a group of PPI channels.
|
||||
pub trait Group: sealed::Group + Sized {
|
||||
/// Returns the number of the group.
|
||||
fn number(&self) -> usize;
|
||||
/// Convert into a type erased group.
|
||||
fn degrade(self) -> AnyGroup {
|
||||
AnyGroup {
|
||||
number: self.number() as u8,
|
||||
@ -196,6 +228,7 @@ macro_rules! impl_ppi_channel {
|
||||
// ======================
|
||||
// groups
|
||||
|
||||
/// A type erased PPI group.
|
||||
pub struct AnyGroup {
|
||||
number: u8,
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ fn regs() -> &'static pac::ppi::RegisterBlock {
|
||||
|
||||
#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
|
||||
impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> {
|
||||
/// Configure PPI channel to trigger `task`.
|
||||
pub fn new_zero_to_one(ch: impl Peripheral<P = C> + 'd, task: Task) -> Self {
|
||||
into_ref!(ch);
|
||||
|
||||
@ -32,6 +33,7 @@ impl<'d, C: StaticChannel> Ppi<'d, C, 0, 1> {
|
||||
}
|
||||
|
||||
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
|
||||
/// Configure PPI channel to trigger `task` on `event`.
|
||||
pub fn new_one_to_one(ch: impl Peripheral<P = C> + 'd, event: Event, task: Task) -> Self {
|
||||
into_ref!(ch);
|
||||
|
||||
@ -46,6 +48,7 @@ impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 1> {
|
||||
|
||||
#[cfg(not(feature = "nrf51"))] // Not for nrf51 because of the fork task
|
||||
impl<'d, C: ConfigurableChannel> Ppi<'d, C, 1, 2> {
|
||||
/// Configure PPI channel to trigger `task1` and `task2` on `event`.
|
||||
pub fn new_one_to_two(ch: impl Peripheral<P = C> + 'd, event: Event, task1: Task, task2: Task) -> Self {
|
||||
into_ref!(ch);
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::gpio::sealed::Pin as _;
|
||||
|
@ -526,7 +526,7 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
|
||||
pub(crate) mod sealed {
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -4,7 +4,7 @@ use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::interrupt::InterruptExt;
|
||||
|
@ -4,7 +4,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::{impl_peripheral, into_ref, PeripheralRef};
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use futures::future::poll_fn;
|
||||
use pac::{saadc, SAADC};
|
||||
use saadc::ch::config::{GAIN_A, REFSEL_A, RESP_A, TACQ_A};
|
||||
|
@ -363,7 +363,7 @@ impl<'d, T: Instance> Drop for Spim<'d, T> {
|
||||
}
|
||||
|
||||
pub(crate) mod sealed {
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -4,7 +4,7 @@ use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use fixed::types::I30F2;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
|
@ -3,9 +3,9 @@ use core::sync::atomic::{compiler_fence, AtomicU32, AtomicU8, Ordering};
|
||||
use core::{mem, ptr};
|
||||
|
||||
use critical_section::CriticalSection;
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::blocking_mutex::CriticalSectionMutex as Mutex;
|
||||
use embassy_time::driver::{AlarmHandle, Driver};
|
||||
use embassy_util::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_util::blocking_mutex::CriticalSectionMutex as Mutex;
|
||||
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
use crate::{interrupt, pac};
|
||||
|
@ -5,7 +5,7 @@ use core::task::Poll;
|
||||
|
||||
use embassy_hal_common::drop::OnDrop;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::interrupt::{Interrupt, InterruptExt};
|
||||
@ -40,8 +40,8 @@ macro_rules! impl_timer {
|
||||
fn regs() -> &'static pac::timer0::RegisterBlock {
|
||||
unsafe { &*(pac::$pac_type::ptr() as *const pac::timer0::RegisterBlock) }
|
||||
}
|
||||
fn waker(n: usize) -> &'static ::embassy_util::waitqueue::AtomicWaker {
|
||||
use ::embassy_util::waitqueue::AtomicWaker;
|
||||
fn waker(n: usize) -> &'static ::embassy_sync::waitqueue::AtomicWaker {
|
||||
use ::embassy_sync::waitqueue::AtomicWaker;
|
||||
const NEW_AW: AtomicWaker = AtomicWaker::new();
|
||||
static WAKERS: [AtomicWaker; $ccs] = [NEW_AW; $ccs];
|
||||
&WAKERS[n]
|
||||
|
@ -13,9 +13,9 @@ use core::task::Poll;
|
||||
|
||||
use embassy_embedded_hal::SetConfig;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
#[cfg(feature = "time")]
|
||||
use embassy_time::{Duration, Instant};
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use futures::future::poll_fn;
|
||||
|
||||
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
|
||||
|
@ -932,7 +932,7 @@ impl<'d, U: Instance, T: TimerInstance> UarteRxWithIdle<'d, U, T> {
|
||||
pub(crate) mod sealed {
|
||||
use core::sync::atomic::AtomicU8;
|
||||
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@ -7,10 +7,10 @@ use core::task::Poll;
|
||||
|
||||
use cortex_m::peripheral::NVIC;
|
||||
use embassy_hal_common::{into_ref, PeripheralRef};
|
||||
use embassy_sync::waitqueue::AtomicWaker;
|
||||
pub use embassy_usb;
|
||||
use embassy_usb::driver::{self, EndpointError, Event, Unsupported};
|
||||
use embassy_usb::types::{EndpointAddress, EndpointInfo, EndpointType, UsbDirection};
|
||||
use embassy_util::waitqueue::AtomicWaker;
|
||||
use futures::future::poll_fn;
|
||||
use futures::Future;
|
||||
use pac::usbd::RegisterBlock;
|
||||
|
Reference in New Issue
Block a user