rp: remove take!, add bind_interrupts!
This commit is contained in:
parent
82f7e104d9
commit
14a5d03af2
@ -3,12 +3,12 @@ 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_hal_common::into_ref;
|
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, InterruptExt};
|
use crate::interrupt::{self, InterruptExt, ADC_IRQ_FIFO};
|
||||||
use crate::peripherals::ADC;
|
use crate::peripherals::ADC;
|
||||||
use crate::{pac, peripherals, Peripheral};
|
use crate::{pac, peripherals, Peripheral};
|
||||||
static WAKER: AtomicWaker = AtomicWaker::new();
|
static WAKER: AtomicWaker = AtomicWaker::new();
|
||||||
@ -47,10 +47,9 @@ impl<'d> Adc<'d> {
|
|||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
_inner: impl Peripheral<P = ADC> + 'd,
|
_inner: impl Peripheral<P = ADC> + 'd,
|
||||||
irq: impl Peripheral<P = interrupt::ADC_IRQ_FIFO> + 'd,
|
_irq: impl Binding<ADC_IRQ_FIFO, InterruptHandler>,
|
||||||
_config: Config,
|
_config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(irq);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let reset = Self::reset();
|
let reset = Self::reset();
|
||||||
crate::reset::reset(reset);
|
crate::reset::reset(reset);
|
||||||
@ -63,14 +62,10 @@ impl<'d> Adc<'d> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup IRQ
|
// Setup IRQ
|
||||||
irq.disable();
|
unsafe {
|
||||||
irq.set_handler(|_| unsafe {
|
ADC_IRQ_FIFO::steal().unpend();
|
||||||
let r = Self::regs();
|
ADC_IRQ_FIFO::steal().enable();
|
||||||
r.inte().write(|w| w.set_fifo(false));
|
};
|
||||||
WAKER.wake();
|
|
||||||
});
|
|
||||||
irq.unpend();
|
|
||||||
irq.enable();
|
|
||||||
|
|
||||||
Self { phantom: PhantomData }
|
Self { phantom: PhantomData }
|
||||||
}
|
}
|
||||||
@ -165,6 +160,18 @@ macro_rules! impl_pin {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct InterruptHandler {
|
||||||
|
_empty: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl interrupt::Handler<ADC_IRQ_FIFO> for InterruptHandler {
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
|
let r = Adc::regs();
|
||||||
|
r.inte().write(|w| w.set_fifo(false));
|
||||||
|
WAKER.wake();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl_pin!(PIN_26, 0);
|
impl_pin!(PIN_26, 0);
|
||||||
impl_pin!(PIN_27, 1);
|
impl_pin!(PIN_27, 1);
|
||||||
impl_pin!(PIN_28, 2);
|
impl_pin!(PIN_28, 2);
|
||||||
|
@ -2,7 +2,7 @@ use core::future;
|
|||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy_cortex_m::interrupt::InterruptExt;
|
use embassy_cortex_m::interrupt::{self, Binding, Interrupt, InterruptExt};
|
||||||
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;
|
||||||
@ -75,23 +75,21 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
|
|||||||
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 Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(scl, sda, irq);
|
into_ref!(scl, sda);
|
||||||
|
|
||||||
let i2c = Self::new_inner(peri, scl.map_into(), sda.map_into(), config);
|
let i2c = Self::new_inner(peri, scl.map_into(), sda.map_into(), config);
|
||||||
|
|
||||||
irq.set_handler(Self::on_interrupt);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let i2c = T::regs();
|
let i2c = T::regs();
|
||||||
|
|
||||||
// mask everything initially
|
// mask everything initially
|
||||||
i2c.ic_intr_mask().write_value(i2c::regs::IcIntrMask(0));
|
i2c.ic_intr_mask().write_value(i2c::regs::IcIntrMask(0));
|
||||||
|
T::Interrupt::steal().unpend();
|
||||||
|
T::Interrupt::steal().enable();
|
||||||
}
|
}
|
||||||
irq.unpend();
|
|
||||||
debug_assert!(!irq.is_pending());
|
|
||||||
irq.enable();
|
|
||||||
|
|
||||||
i2c
|
i2c
|
||||||
}
|
}
|
||||||
@ -115,14 +113,6 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mask interrupts and wake any task waiting for this interrupt
|
|
||||||
unsafe fn on_interrupt(_: *mut ()) {
|
|
||||||
let i2c = T::regs();
|
|
||||||
i2c.ic_intr_mask().write_value(pac::i2c::regs::IcIntrMask::default());
|
|
||||||
|
|
||||||
T::waker().wake();
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn read_async_internal(&mut self, buffer: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> {
|
async fn read_async_internal(&mut self, buffer: &mut [u8], restart: bool, send_stop: bool) -> Result<(), Error> {
|
||||||
if buffer.is_empty() {
|
if buffer.is_empty() {
|
||||||
return Err(Error::InvalidReadBufferLength);
|
return Err(Error::InvalidReadBufferLength);
|
||||||
@ -320,6 +310,20 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct InterruptHandler<T: Instance> {
|
||||||
|
_uart: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> {
|
||||||
|
// Mask interrupts and wake any task waiting for this interrupt
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
|
let i2c = T::regs();
|
||||||
|
i2c.ic_intr_mask().write_value(pac::i2c::regs::IcIntrMask::default());
|
||||||
|
|
||||||
|
T::waker().wake();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
|
impl<'d, T: Instance + 'd, M: Mode> I2c<'d, T, M> {
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
_peri: impl Peripheral<P = T> + 'd,
|
_peri: impl Peripheral<P = T> + 'd,
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
//! Interrupt management
|
//! Interrupt definitions and macros to bind them.
|
||||||
//!
|
pub use cortex_m::interrupt::{CriticalSection, Mutex};
|
||||||
//! This module implements an API for managing interrupts compatible with
|
|
||||||
//! nrf_softdevice::interrupt. Intended for switching between the two at compile-time.
|
|
||||||
|
|
||||||
// Re-exports
|
|
||||||
use embassy_cortex_m::interrupt::_export::declare;
|
use embassy_cortex_m::interrupt::_export::declare;
|
||||||
pub use embassy_cortex_m::interrupt::*;
|
pub use embassy_cortex_m::interrupt::{Binding, Handler, Interrupt, InterruptExt, Priority};
|
||||||
|
|
||||||
use crate::pac::Interrupt as InterruptEnum;
|
use crate::pac::Interrupt as InterruptEnum;
|
||||||
declare!(TIMER_IRQ_0);
|
declare!(TIMER_IRQ_0);
|
||||||
@ -40,3 +36,30 @@ declare!(SWI_IRQ_2);
|
|||||||
declare!(SWI_IRQ_3);
|
declare!(SWI_IRQ_3);
|
||||||
declare!(SWI_IRQ_4);
|
declare!(SWI_IRQ_4);
|
||||||
declare!(SWI_IRQ_5);
|
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 {}
|
||||||
|
)*
|
||||||
|
)*
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -3,7 +3,7 @@ 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::{Interrupt, InterruptExt};
|
use embassy_cortex_m::interrupt::{self, Binding, Interrupt, InterruptExt};
|
||||||
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};
|
||||||
@ -52,7 +52,7 @@ pub struct BufferedUartTx<'d, T: Instance> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn init_buffers<'d, T: Instance + 'd>(
|
pub(crate) fn init_buffers<'d, T: Instance + 'd>(
|
||||||
irq: PeripheralRef<'d, T::Interrupt>,
|
_irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
) {
|
) {
|
||||||
@ -79,24 +79,23 @@ pub(crate) fn init_buffers<'d, T: Instance + 'd>(
|
|||||||
w.set_rtim(true);
|
w.set_rtim(true);
|
||||||
w.set_txim(true);
|
w.set_txim(true);
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
irq.set_handler(on_interrupt::<T>);
|
T::Interrupt::steal().unpend();
|
||||||
irq.unpend();
|
T::Interrupt::steal().enable();
|
||||||
irq.enable();
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> BufferedUart<'d, T> {
|
impl<'d, T: Instance> BufferedUart<'d, T> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
_uart: impl Peripheral<P = T> + 'd,
|
_uart: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
||||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(irq, tx, rx);
|
into_ref!(tx, rx);
|
||||||
|
|
||||||
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), Some(rx.map_into()), None, None, config);
|
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), Some(rx.map_into()), None, None, config);
|
||||||
init_buffers::<T>(irq, tx_buffer, rx_buffer);
|
init_buffers::<T>(irq, tx_buffer, rx_buffer);
|
||||||
@ -109,7 +108,7 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
|
|||||||
|
|
||||||
pub fn new_with_rtscts(
|
pub fn new_with_rtscts(
|
||||||
_uart: impl Peripheral<P = T> + 'd,
|
_uart: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
tx: impl Peripheral<P = impl TxPin<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,
|
||||||
@ -118,7 +117,7 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
|
|||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(irq, tx, rx, cts, rts);
|
into_ref!(tx, rx, cts, rts);
|
||||||
|
|
||||||
super::Uart::<'d, T, Async>::init(
|
super::Uart::<'d, T, Async>::init(
|
||||||
Some(tx.map_into()),
|
Some(tx.map_into()),
|
||||||
@ -163,12 +162,12 @@ impl<'d, T: Instance> BufferedUart<'d, T> {
|
|||||||
impl<'d, T: Instance> BufferedUartRx<'d, T> {
|
impl<'d, T: Instance> BufferedUartRx<'d, T> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
_uart: impl Peripheral<P = T> + 'd,
|
_uart: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(irq, rx);
|
into_ref!(rx);
|
||||||
|
|
||||||
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), None, None, config);
|
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), None, None, config);
|
||||||
init_buffers::<T>(irq, &mut [], rx_buffer);
|
init_buffers::<T>(irq, &mut [], rx_buffer);
|
||||||
@ -178,13 +177,13 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
|
|||||||
|
|
||||||
pub fn new_with_rts(
|
pub fn new_with_rts(
|
||||||
_uart: impl Peripheral<P = T> + 'd,
|
_uart: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
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_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(irq, rx, rts);
|
into_ref!(rx, rts);
|
||||||
|
|
||||||
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), Some(rts.map_into()), None, config);
|
super::Uart::<'d, T, Async>::init(None, Some(rx.map_into()), Some(rts.map_into()), None, config);
|
||||||
init_buffers::<T>(irq, &mut [], rx_buffer);
|
init_buffers::<T>(irq, &mut [], rx_buffer);
|
||||||
@ -312,12 +311,12 @@ impl<'d, T: Instance> BufferedUartRx<'d, T> {
|
|||||||
impl<'d, T: Instance> BufferedUartTx<'d, T> {
|
impl<'d, T: Instance> BufferedUartTx<'d, T> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
_uart: impl Peripheral<P = T> + 'd,
|
_uart: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
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],
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(irq, tx);
|
into_ref!(tx);
|
||||||
|
|
||||||
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, None, config);
|
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, None, config);
|
||||||
init_buffers::<T>(irq, tx_buffer, &mut []);
|
init_buffers::<T>(irq, tx_buffer, &mut []);
|
||||||
@ -327,13 +326,13 @@ impl<'d, T: Instance> BufferedUartTx<'d, T> {
|
|||||||
|
|
||||||
pub fn new_with_cts(
|
pub fn new_with_cts(
|
||||||
_uart: impl Peripheral<P = T> + 'd,
|
_uart: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
||||||
cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
|
cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(irq, tx, cts);
|
into_ref!(tx, cts);
|
||||||
|
|
||||||
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, Some(cts.map_into()), config);
|
super::Uart::<'d, T, Async>::init(Some(tx.map_into()), None, None, Some(cts.map_into()), config);
|
||||||
init_buffers::<T>(irq, tx_buffer, &mut []);
|
init_buffers::<T>(irq, tx_buffer, &mut []);
|
||||||
@ -482,8 +481,17 @@ impl<'d, T: Instance> Drop for BufferedUartTx<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn on_interrupt<T: Instance>(_: *mut ()) {
|
pub struct BufferedInterruptHandler<T: Instance> {
|
||||||
|
_uart: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Instance> interrupt::Handler<T::Interrupt> for BufferedInterruptHandler<T> {
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
if r.uartdmacr().read().rxdmae() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let s = T::buffered_state();
|
let s = T::buffered_state();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -574,6 +582,7 @@ pub(crate) unsafe fn on_interrupt<T: Instance>(_: *mut ()) {
|
|||||||
// crossed. No need to disable it when the buffer becomes empty
|
// crossed. No need to disable it when the buffer becomes empty
|
||||||
// as it does re-trigger anymore once we have cleared it.
|
// as it does re-trigger anymore once we have cleared it.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl embedded_io::Error for Error {
|
impl embedded_io::Error for Error {
|
||||||
|
@ -3,7 +3,7 @@ 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::{Interrupt, InterruptExt};
|
use embassy_cortex_m::interrupt::{self, Binding, Interrupt, InterruptExt};
|
||||||
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;
|
||||||
@ -20,7 +20,7 @@ use crate::{pac, peripherals, Peripheral, RegExt};
|
|||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
mod buffered;
|
mod buffered;
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
pub use buffered::{BufferedUart, BufferedUartRx, BufferedUartTx};
|
pub use buffered::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, BufferedUartTx};
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub enum DataBits {
|
pub enum DataBits {
|
||||||
@ -203,11 +203,9 @@ impl<'d, T: Instance> UartTx<'d, T, Blocking> {
|
|||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
pub fn into_buffered(
|
pub fn into_buffered(
|
||||||
self,
|
self,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
) -> BufferedUartTx<'d, T> {
|
) -> BufferedUartTx<'d, T> {
|
||||||
into_ref!(irq);
|
|
||||||
|
|
||||||
buffered::init_buffers::<T>(irq, tx_buffer, &mut []);
|
buffered::init_buffers::<T>(irq, tx_buffer, &mut []);
|
||||||
|
|
||||||
BufferedUartTx { phantom: PhantomData }
|
BufferedUartTx { phantom: PhantomData }
|
||||||
@ -235,25 +233,24 @@ impl<'d, T: Instance, M: Mode> UartRx<'d, T, M> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
_uart: impl Peripheral<P = T> + 'd,
|
_uart: impl Peripheral<P = T> + 'd,
|
||||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
|
||||||
rx_dma: impl Peripheral<P = impl Channel> + 'd,
|
rx_dma: impl Peripheral<P = impl Channel> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(rx, irq, rx_dma);
|
into_ref!(rx, rx_dma);
|
||||||
Uart::<T, M>::init(None, Some(rx.map_into()), None, None, config);
|
Uart::<T, M>::init(None, Some(rx.map_into()), None, None, config);
|
||||||
Self::new_inner(Some(irq), Some(rx_dma.map_into()))
|
Self::new_inner(true, Some(rx_dma.map_into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(irq: Option<PeripheralRef<'d, T::Interrupt>>, rx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self {
|
fn new_inner(has_irq: bool, rx_dma: Option<PeripheralRef<'d, AnyChannel>>) -> Self {
|
||||||
debug_assert_eq!(irq.is_some(), rx_dma.is_some());
|
debug_assert_eq!(has_irq, rx_dma.is_some());
|
||||||
if let Some(irq) = irq {
|
if has_irq {
|
||||||
unsafe {
|
unsafe {
|
||||||
// disable all error interrupts initially
|
// disable all error interrupts initially
|
||||||
T::regs().uartimsc().write(|w| w.0 = 0);
|
T::regs().uartimsc().write(|w| w.0 = 0);
|
||||||
|
T::Interrupt::steal().unpend();
|
||||||
|
T::Interrupt::steal().enable();
|
||||||
}
|
}
|
||||||
irq.set_handler(on_interrupt::<T>);
|
|
||||||
irq.unpend();
|
|
||||||
irq.enable();
|
|
||||||
}
|
}
|
||||||
Self {
|
Self {
|
||||||
rx_dma,
|
rx_dma,
|
||||||
@ -299,6 +296,12 @@ impl<'d, T: Instance, M: Mode> Drop for UartRx<'d, T, M> {
|
|||||||
if let Some(_) = self.rx_dma {
|
if let Some(_) = self.rx_dma {
|
||||||
unsafe {
|
unsafe {
|
||||||
T::Interrupt::steal().disable();
|
T::Interrupt::steal().disable();
|
||||||
|
// clear dma flags. irq handlers use these to disambiguate among themselves.
|
||||||
|
T::regs().uartdmacr().write_clear(|reg| {
|
||||||
|
reg.set_rxdmae(true);
|
||||||
|
reg.set_txdmae(true);
|
||||||
|
reg.set_dmaonerr(true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,25 +315,32 @@ impl<'d, T: Instance> UartRx<'d, T, Blocking> {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(rx);
|
into_ref!(rx);
|
||||||
Uart::<T, Blocking>::init(None, Some(rx.map_into()), None, None, config);
|
Uart::<T, Blocking>::init(None, Some(rx.map_into()), None, None, config);
|
||||||
Self::new_inner(None, None)
|
Self::new_inner(false, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
pub fn into_buffered(
|
pub fn into_buffered(
|
||||||
self,
|
self,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
) -> BufferedUartRx<'d, T> {
|
) -> BufferedUartRx<'d, T> {
|
||||||
into_ref!(irq);
|
|
||||||
|
|
||||||
buffered::init_buffers::<T>(irq, &mut [], rx_buffer);
|
buffered::init_buffers::<T>(irq, &mut [], rx_buffer);
|
||||||
|
|
||||||
BufferedUartRx { phantom: PhantomData }
|
BufferedUartRx { phantom: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn on_interrupt<T: Instance>(_: *mut ()) {
|
pub struct InterruptHandler<T: Instance> {
|
||||||
|
_uart: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> {
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
let uart = T::regs();
|
let uart = T::regs();
|
||||||
|
if !uart.uartdmacr().read().rxdmae() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let state = T::dma_state();
|
let state = T::dma_state();
|
||||||
let errs = uart.uartris().read();
|
let errs = uart.uartris().read();
|
||||||
state.rx_errs.store(errs.0 as u16, Ordering::Relaxed);
|
state.rx_errs.store(errs.0 as u16, Ordering::Relaxed);
|
||||||
@ -339,6 +349,7 @@ unsafe fn on_interrupt<T: Instance>(_: *mut ()) {
|
|||||||
// flags would allow the dma transfer to continue, potentially signaling
|
// flags would allow the dma transfer to continue, potentially signaling
|
||||||
// completion before we can check for errors that happened *during* the transfer.
|
// completion before we can check for errors that happened *during* the transfer.
|
||||||
uart.uartimsc().write_clear(|w| w.0 = errs.0);
|
uart.uartimsc().write_clear(|w| w.0 = errs.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> UartRx<'d, T, Async> {
|
impl<'d, T: Instance> UartRx<'d, T, Async> {
|
||||||
@ -428,7 +439,17 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(tx, rx);
|
into_ref!(tx, rx);
|
||||||
Self::new_inner(uart, tx.map_into(), rx.map_into(), None, None, None, None, None, config)
|
Self::new_inner(
|
||||||
|
uart,
|
||||||
|
tx.map_into(),
|
||||||
|
rx.map_into(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
config,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new UART with hardware flow control (RTS/CTS)
|
/// Create a new UART with hardware flow control (RTS/CTS)
|
||||||
@ -447,7 +468,7 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> {
|
|||||||
rx.map_into(),
|
rx.map_into(),
|
||||||
Some(rts.map_into()),
|
Some(rts.map_into()),
|
||||||
Some(cts.map_into()),
|
Some(cts.map_into()),
|
||||||
None,
|
false,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
config,
|
config,
|
||||||
@ -457,12 +478,10 @@ impl<'d, T: Instance> Uart<'d, T, Blocking> {
|
|||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
pub fn into_buffered(
|
pub fn into_buffered(
|
||||||
self,
|
self,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
irq: impl Binding<T::Interrupt, BufferedInterruptHandler<T>>,
|
||||||
tx_buffer: &'d mut [u8],
|
tx_buffer: &'d mut [u8],
|
||||||
rx_buffer: &'d mut [u8],
|
rx_buffer: &'d mut [u8],
|
||||||
) -> BufferedUart<'d, T> {
|
) -> BufferedUart<'d, T> {
|
||||||
into_ref!(irq);
|
|
||||||
|
|
||||||
buffered::init_buffers::<T>(irq, tx_buffer, rx_buffer);
|
buffered::init_buffers::<T>(irq, tx_buffer, rx_buffer);
|
||||||
|
|
||||||
BufferedUart {
|
BufferedUart {
|
||||||
@ -478,19 +497,19 @@ impl<'d, T: Instance> Uart<'d, T, Async> {
|
|||||||
uart: impl Peripheral<P = T> + 'd,
|
uart: impl Peripheral<P = T> + 'd,
|
||||||
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
tx: impl Peripheral<P = impl TxPin<T>> + 'd,
|
||||||
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
rx: impl Peripheral<P = impl RxPin<T>> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
|
||||||
tx_dma: impl Peripheral<P = impl Channel> + 'd,
|
tx_dma: impl Peripheral<P = impl Channel> + 'd,
|
||||||
rx_dma: impl Peripheral<P = impl Channel> + 'd,
|
rx_dma: impl Peripheral<P = impl Channel> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(tx, rx, irq, tx_dma, rx_dma);
|
into_ref!(tx, rx, tx_dma, rx_dma);
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
uart,
|
uart,
|
||||||
tx.map_into(),
|
tx.map_into(),
|
||||||
rx.map_into(),
|
rx.map_into(),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
Some(irq),
|
true,
|
||||||
Some(tx_dma.map_into()),
|
Some(tx_dma.map_into()),
|
||||||
Some(rx_dma.map_into()),
|
Some(rx_dma.map_into()),
|
||||||
config,
|
config,
|
||||||
@ -504,19 +523,19 @@ impl<'d, T: Instance> Uart<'d, T, Async> {
|
|||||||
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,
|
||||||
cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
|
cts: impl Peripheral<P = impl CtsPin<T>> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl Binding<T::Interrupt, InterruptHandler<T>>,
|
||||||
tx_dma: impl Peripheral<P = impl Channel> + 'd,
|
tx_dma: impl Peripheral<P = impl Channel> + 'd,
|
||||||
rx_dma: impl Peripheral<P = impl Channel> + 'd,
|
rx_dma: impl Peripheral<P = impl Channel> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(tx, rx, cts, rts, irq, tx_dma, rx_dma);
|
into_ref!(tx, rx, cts, rts, tx_dma, rx_dma);
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
uart,
|
uart,
|
||||||
tx.map_into(),
|
tx.map_into(),
|
||||||
rx.map_into(),
|
rx.map_into(),
|
||||||
Some(rts.map_into()),
|
Some(rts.map_into()),
|
||||||
Some(cts.map_into()),
|
Some(cts.map_into()),
|
||||||
Some(irq),
|
true,
|
||||||
Some(tx_dma.map_into()),
|
Some(tx_dma.map_into()),
|
||||||
Some(rx_dma.map_into()),
|
Some(rx_dma.map_into()),
|
||||||
config,
|
config,
|
||||||
@ -531,7 +550,7 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
|
|||||||
mut rx: PeripheralRef<'d, AnyPin>,
|
mut rx: PeripheralRef<'d, AnyPin>,
|
||||||
mut rts: Option<PeripheralRef<'d, AnyPin>>,
|
mut rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
mut cts: Option<PeripheralRef<'d, AnyPin>>,
|
mut cts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
irq: Option<PeripheralRef<'d, T::Interrupt>>,
|
has_irq: bool,
|
||||||
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
tx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
||||||
rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
rx_dma: Option<PeripheralRef<'d, AnyChannel>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
@ -546,7 +565,7 @@ impl<'d, T: Instance + 'd, M: Mode> Uart<'d, T, M> {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
tx: UartTx::new_inner(tx_dma),
|
tx: UartTx::new_inner(tx_dma),
|
||||||
rx: UartRx::new_inner(irq, rx_dma),
|
rx: UartRx::new_inner(has_irq, rx_dma),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ 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_hal_common::into_ref;
|
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::{
|
||||||
@ -105,11 +105,11 @@ pub struct Driver<'d, T: Instance> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Driver<'d, T> {
|
impl<'d, T: Instance> Driver<'d, T> {
|
||||||
pub fn new(_usb: impl Peripheral<P = T> + 'd, irq: impl Peripheral<P = T::Interrupt> + 'd) -> Self {
|
pub fn new(_usb: impl Peripheral<P = T> + 'd, _irq: impl Binding<T::Interrupt, InterruptHandler<T>>) -> Self {
|
||||||
into_ref!(irq);
|
unsafe {
|
||||||
irq.set_handler(Self::on_interrupt);
|
T::Interrupt::steal().unpend();
|
||||||
irq.unpend();
|
T::Interrupt::steal().enable();
|
||||||
irq.enable();
|
}
|
||||||
|
|
||||||
let regs = T::regs();
|
let regs = T::regs();
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -149,47 +149,6 @@ impl<'d, T: Instance> Driver<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_interrupt(_: *mut ()) {
|
|
||||||
unsafe {
|
|
||||||
let regs = T::regs();
|
|
||||||
//let x = regs.istr().read().0;
|
|
||||||
//trace!("USB IRQ: {:08x}", x);
|
|
||||||
|
|
||||||
let ints = regs.ints().read();
|
|
||||||
|
|
||||||
if ints.bus_reset() {
|
|
||||||
regs.inte().write_clear(|w| w.set_bus_reset(true));
|
|
||||||
BUS_WAKER.wake();
|
|
||||||
}
|
|
||||||
if ints.dev_resume_from_host() {
|
|
||||||
regs.inte().write_clear(|w| w.set_dev_resume_from_host(true));
|
|
||||||
BUS_WAKER.wake();
|
|
||||||
}
|
|
||||||
if ints.dev_suspend() {
|
|
||||||
regs.inte().write_clear(|w| w.set_dev_suspend(true));
|
|
||||||
BUS_WAKER.wake();
|
|
||||||
}
|
|
||||||
if ints.setup_req() {
|
|
||||||
regs.inte().write_clear(|w| w.set_setup_req(true));
|
|
||||||
EP_OUT_WAKERS[0].wake();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ints.buff_status() {
|
|
||||||
let s = regs.buff_status().read();
|
|
||||||
regs.buff_status().write_value(s);
|
|
||||||
|
|
||||||
for i in 0..EP_COUNT {
|
|
||||||
if s.ep_in(i) {
|
|
||||||
EP_IN_WAKERS[i].wake();
|
|
||||||
}
|
|
||||||
if s.ep_out(i) {
|
|
||||||
EP_OUT_WAKERS[i].wake();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn alloc_endpoint<D: Dir>(
|
fn alloc_endpoint<D: Dir>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ep_type: EndpointType,
|
ep_type: EndpointType,
|
||||||
@ -288,6 +247,51 @@ impl<'d, T: Instance> Driver<'d, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct InterruptHandler<T: Instance> {
|
||||||
|
_uart: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> {
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
|
let regs = T::regs();
|
||||||
|
//let x = regs.istr().read().0;
|
||||||
|
//trace!("USB IRQ: {:08x}", x);
|
||||||
|
|
||||||
|
let ints = regs.ints().read();
|
||||||
|
|
||||||
|
if ints.bus_reset() {
|
||||||
|
regs.inte().write_clear(|w| w.set_bus_reset(true));
|
||||||
|
BUS_WAKER.wake();
|
||||||
|
}
|
||||||
|
if ints.dev_resume_from_host() {
|
||||||
|
regs.inte().write_clear(|w| w.set_dev_resume_from_host(true));
|
||||||
|
BUS_WAKER.wake();
|
||||||
|
}
|
||||||
|
if ints.dev_suspend() {
|
||||||
|
regs.inte().write_clear(|w| w.set_dev_suspend(true));
|
||||||
|
BUS_WAKER.wake();
|
||||||
|
}
|
||||||
|
if ints.setup_req() {
|
||||||
|
regs.inte().write_clear(|w| w.set_setup_req(true));
|
||||||
|
EP_OUT_WAKERS[0].wake();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ints.buff_status() {
|
||||||
|
let s = regs.buff_status().read();
|
||||||
|
regs.buff_status().write_value(s);
|
||||||
|
|
||||||
|
for i in 0..EP_COUNT {
|
||||||
|
if s.ep_in(i) {
|
||||||
|
EP_IN_WAKERS[i].wake();
|
||||||
|
}
|
||||||
|
if s.ep_out(i) {
|
||||||
|
EP_OUT_WAKERS[i].wake();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
|
impl<'d, T: Instance> driver::Driver<'d> for Driver<'d, T> {
|
||||||
type EndpointOut = Endpoint<'d, T, Out>;
|
type EndpointOut = Endpoint<'d, T, Out>;
|
||||||
type EndpointIn = Endpoint<'d, T, In>;
|
type EndpointIn = Endpoint<'d, T, In>;
|
||||||
|
@ -4,16 +4,19 @@
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::adc::{Adc, Config};
|
use embassy_rp::adc::{Adc, Config, InterruptHandler};
|
||||||
use embassy_rp::interrupt;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
ADC_IRQ_FIFO => InterruptHandler;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
let irq = interrupt::take!(ADC_IRQ_FIFO);
|
let mut adc = Adc::new(p.ADC, Irqs, Config::default());
|
||||||
let mut adc = Adc::new(p.ADC, irq, Config::default());
|
|
||||||
|
|
||||||
let mut p26 = p.PIN_26;
|
let mut p26 = p.PIN_26;
|
||||||
let mut p27 = p.PIN_27;
|
let mut p27 = p.PIN_27;
|
||||||
|
@ -4,12 +4,17 @@
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::i2c::{self, Config};
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::interrupt;
|
use embassy_rp::i2c::{self, Config, InterruptHandler};
|
||||||
|
use embassy_rp::peripherals::I2C1;
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use embedded_hal_async::i2c::I2c;
|
use embedded_hal_async::i2c::I2c;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
I2C1_IRQ => InterruptHandler<I2C1>;
|
||||||
|
});
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
mod mcp23017 {
|
mod mcp23017 {
|
||||||
pub const ADDR: u8 = 0x20; // default addr
|
pub const ADDR: u8 = 0x20; // default addr
|
||||||
@ -64,10 +69,9 @@ async fn main(_spawner: Spawner) {
|
|||||||
|
|
||||||
let sda = p.PIN_14;
|
let sda = p.PIN_14;
|
||||||
let scl = p.PIN_15;
|
let scl = p.PIN_15;
|
||||||
let irq = interrupt::take!(I2C1_IRQ);
|
|
||||||
|
|
||||||
info!("set up i2c ");
|
info!("set up i2c ");
|
||||||
let mut i2c = i2c::I2c::new_async(p.I2C1, scl, sda, irq, Config::default());
|
let mut i2c = i2c::I2c::new_async(p.I2C1, scl, sda, Irqs, Config::default());
|
||||||
|
|
||||||
use mcp23017::*;
|
use mcp23017::*;
|
||||||
|
|
||||||
|
@ -5,13 +5,17 @@
|
|||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_executor::_export::StaticCell;
|
use embassy_executor::_export::StaticCell;
|
||||||
use embassy_rp::interrupt;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::peripherals::UART0;
|
use embassy_rp::peripherals::UART0;
|
||||||
use embassy_rp::uart::{BufferedUart, BufferedUartRx, Config};
|
use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use embedded_io::asynch::{Read, Write};
|
use embedded_io::asynch::{Read, Write};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UART0_IRQ => BufferedInterruptHandler<UART0>;
|
||||||
|
});
|
||||||
|
|
||||||
macro_rules! singleton {
|
macro_rules! singleton {
|
||||||
($val:expr) => {{
|
($val:expr) => {{
|
||||||
type T = impl Sized;
|
type T = impl Sized;
|
||||||
@ -26,10 +30,9 @@ async fn main(spawner: Spawner) {
|
|||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
let (tx_pin, rx_pin, uart) = (p.PIN_0, p.PIN_1, p.UART0);
|
let (tx_pin, rx_pin, uart) = (p.PIN_0, p.PIN_1, p.UART0);
|
||||||
|
|
||||||
let irq = interrupt::take!(UART0_IRQ);
|
|
||||||
let tx_buf = &mut singleton!([0u8; 16])[..];
|
let tx_buf = &mut singleton!([0u8; 16])[..];
|
||||||
let rx_buf = &mut singleton!([0u8; 16])[..];
|
let rx_buf = &mut singleton!([0u8; 16])[..];
|
||||||
let uart = BufferedUart::new(uart, irq, tx_pin, rx_pin, tx_buf, rx_buf, Config::default());
|
let uart = BufferedUart::new(uart, Irqs, tx_pin, rx_pin, tx_buf, rx_buf, Config::default());
|
||||||
let (rx, mut tx) = uart.split();
|
let (rx, mut tx) = uart.split();
|
||||||
|
|
||||||
unwrap!(spawner.spawn(reader(rx)));
|
unwrap!(spawner.spawn(reader(rx)));
|
||||||
|
@ -7,24 +7,22 @@
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::interrupt;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::peripherals::UART1;
|
use embassy_rp::peripherals::UART1;
|
||||||
use embassy_rp::uart::{Async, Config, UartRx, UartTx};
|
use embassy_rp::uart::{Async, Config, InterruptHandler, UartRx, UartTx};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UART1_IRQ => InterruptHandler<UART1>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
let mut uart_tx = UartTx::new(p.UART0, p.PIN_0, p.DMA_CH0, Config::default());
|
let mut uart_tx = UartTx::new(p.UART0, p.PIN_0, p.DMA_CH0, Config::default());
|
||||||
let uart_rx = UartRx::new(
|
let uart_rx = UartRx::new(p.UART1, p.PIN_5, Irqs, p.DMA_CH1, Config::default());
|
||||||
p.UART1,
|
|
||||||
p.PIN_5,
|
|
||||||
interrupt::take!(UART1_IRQ),
|
|
||||||
p.DMA_CH1,
|
|
||||||
Config::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
unwrap!(spawner.spawn(reader(uart_rx)));
|
unwrap!(spawner.spawn(reader(uart_rx)));
|
||||||
|
|
||||||
|
@ -6,8 +6,9 @@ use defmt::*;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_net::tcp::TcpSocket;
|
use embassy_net::tcp::TcpSocket;
|
||||||
use embassy_net::{Stack, StackResources};
|
use embassy_net::{Stack, StackResources};
|
||||||
use embassy_rp::usb::Driver;
|
use embassy_rp::peripherals::USB;
|
||||||
use embassy_rp::{interrupt, peripherals};
|
use embassy_rp::usb::{Driver, InterruptHandler};
|
||||||
|
use embassy_rp::{bind_interrupts, peripherals};
|
||||||
use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState};
|
use embassy_usb::class::cdc_ncm::embassy_net::{Device, Runner, State as NetState};
|
||||||
use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
|
use embassy_usb::class::cdc_ncm::{CdcNcmClass, State};
|
||||||
use embassy_usb::{Builder, Config, UsbDevice};
|
use embassy_usb::{Builder, Config, UsbDevice};
|
||||||
@ -15,6 +16,10 @@ use embedded_io::asynch::Write;
|
|||||||
use static_cell::StaticCell;
|
use static_cell::StaticCell;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
USBCTRL_IRQ => InterruptHandler<USB>;
|
||||||
|
});
|
||||||
|
|
||||||
type MyDriver = Driver<'static, peripherals::USB>;
|
type MyDriver = Driver<'static, peripherals::USB>;
|
||||||
|
|
||||||
macro_rules! singleton {
|
macro_rules! singleton {
|
||||||
@ -48,8 +53,7 @@ async fn main(spawner: Spawner) {
|
|||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
// Create the driver, from the HAL.
|
// Create the driver, from the HAL.
|
||||||
let irq = interrupt::take!(USBCTRL_IRQ);
|
let driver = Driver::new(p.USB, Irqs);
|
||||||
let driver = Driver::new(p.USB, irq);
|
|
||||||
|
|
||||||
// Create embassy-usb Config
|
// Create embassy-usb Config
|
||||||
let mut config = Config::new(0xc0de, 0xcafe);
|
let mut config = Config::new(0xc0de, 0xcafe);
|
||||||
|
@ -3,12 +3,16 @@
|
|||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::interrupt;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::peripherals::USB;
|
use embassy_rp::peripherals::USB;
|
||||||
use embassy_rp::usb::Driver;
|
use embassy_rp::usb::{Driver, InterruptHandler};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
USBCTRL_IRQ => InterruptHandler<USB>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::task]
|
#[embassy_executor::task]
|
||||||
async fn logger_task(driver: Driver<'static, USB>) {
|
async fn logger_task(driver: Driver<'static, USB>) {
|
||||||
embassy_usb_logger::run!(1024, log::LevelFilter::Info, driver);
|
embassy_usb_logger::run!(1024, log::LevelFilter::Info, driver);
|
||||||
@ -17,8 +21,7 @@ async fn logger_task(driver: Driver<'static, USB>) {
|
|||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
let irq = interrupt::take!(USBCTRL_IRQ);
|
let driver = Driver::new(p.USB, Irqs);
|
||||||
let driver = Driver::new(p.USB, irq);
|
|
||||||
spawner.spawn(logger_task(driver)).unwrap();
|
spawner.spawn(logger_task(driver)).unwrap();
|
||||||
|
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
|
@ -5,13 +5,18 @@
|
|||||||
use defmt::{info, panic};
|
use defmt::{info, panic};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
use embassy_rp::interrupt;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::usb::{Driver, Instance};
|
use embassy_rp::peripherals::USB;
|
||||||
|
use embassy_rp::usb::{Driver, Instance, InterruptHandler};
|
||||||
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
|
use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
|
||||||
use embassy_usb::driver::EndpointError;
|
use embassy_usb::driver::EndpointError;
|
||||||
use embassy_usb::{Builder, Config};
|
use embassy_usb::{Builder, Config};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
USBCTRL_IRQ => InterruptHandler<USB>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
info!("Hello there!");
|
info!("Hello there!");
|
||||||
@ -19,8 +24,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
|
|
||||||
// Create the driver, from the HAL.
|
// Create the driver, from the HAL.
|
||||||
let irq = interrupt::take!(USBCTRL_IRQ);
|
let driver = Driver::new(p.USB, Irqs);
|
||||||
let driver = Driver::new(p.USB, irq);
|
|
||||||
|
|
||||||
// Create embassy-usb Config
|
// Create embassy-usb Config
|
||||||
let mut config = Config::new(0xc0de, 0xcafe);
|
let mut config = Config::new(0xc0de, 0xcafe);
|
||||||
|
@ -4,13 +4,18 @@
|
|||||||
|
|
||||||
use defmt::{assert_eq, panic, *};
|
use defmt::{assert_eq, panic, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::gpio::{Level, Output};
|
use embassy_rp::gpio::{Level, Output};
|
||||||
use embassy_rp::interrupt;
|
use embassy_rp::peripherals::UART0;
|
||||||
use embassy_rp::uart::{BufferedUart, BufferedUartRx, Config, Error, Instance, Parity};
|
use embassy_rp::uart::{BufferedInterruptHandler, BufferedUart, BufferedUartRx, Config, Error, Instance, Parity};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use embedded_io::asynch::{Read, ReadExactError, Write};
|
use embedded_io::asynch::{Read, ReadExactError, Write};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UART0_IRQ => BufferedInterruptHandler<UART0>;
|
||||||
|
});
|
||||||
|
|
||||||
async fn read<const N: usize>(uart: &mut BufferedUart<'_, impl Instance>) -> Result<[u8; N], Error> {
|
async fn read<const N: usize>(uart: &mut BufferedUart<'_, impl Instance>) -> Result<[u8; N], Error> {
|
||||||
let mut buf = [255; N];
|
let mut buf = [255; N];
|
||||||
match uart.read_exact(&mut buf).await {
|
match uart.read_exact(&mut buf).await {
|
||||||
@ -60,13 +65,12 @@ async fn main(_spawner: Spawner) {
|
|||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
let (mut tx, mut rx, mut uart) = (p.PIN_0, p.PIN_1, p.UART0);
|
let (mut tx, mut rx, mut uart) = (p.PIN_0, p.PIN_1, p.UART0);
|
||||||
let mut irq = interrupt::take!(UART0_IRQ);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
let tx_buf = &mut [0u8; 16];
|
let tx_buf = &mut [0u8; 16];
|
||||||
let rx_buf = &mut [0u8; 16];
|
let rx_buf = &mut [0u8; 16];
|
||||||
let mut uart = BufferedUart::new(&mut uart, &mut irq, &mut tx, &mut rx, tx_buf, rx_buf, config);
|
let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config);
|
||||||
|
|
||||||
// Make sure we send more bytes than fits in the FIFO, to test the actual
|
// Make sure we send more bytes than fits in the FIFO, to test the actual
|
||||||
// bufferedUart.
|
// bufferedUart.
|
||||||
@ -86,7 +90,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let config = Config::default();
|
let config = Config::default();
|
||||||
let tx_buf = &mut [0u8; 16];
|
let tx_buf = &mut [0u8; 16];
|
||||||
let rx_buf = &mut [0u8; 16];
|
let rx_buf = &mut [0u8; 16];
|
||||||
let mut uart = BufferedUart::new(&mut uart, &mut irq, &mut tx, &mut rx, tx_buf, rx_buf, config);
|
let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config);
|
||||||
|
|
||||||
// Make sure we send more bytes than fits in the FIFO, to test the actual
|
// Make sure we send more bytes than fits in the FIFO, to test the actual
|
||||||
// bufferedUart.
|
// bufferedUart.
|
||||||
@ -121,7 +125,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
config.baudrate = 1000;
|
config.baudrate = 1000;
|
||||||
let tx_buf = &mut [0u8; 16];
|
let tx_buf = &mut [0u8; 16];
|
||||||
let rx_buf = &mut [0u8; 16];
|
let rx_buf = &mut [0u8; 16];
|
||||||
let mut uart = BufferedUart::new(&mut uart, &mut irq, &mut tx, &mut rx, tx_buf, rx_buf, config);
|
let mut uart = BufferedUart::new(&mut uart, Irqs, &mut tx, &mut rx, tx_buf, rx_buf, config);
|
||||||
|
|
||||||
// break on empty buffer
|
// break on empty buffer
|
||||||
uart.send_break(20).await;
|
uart.send_break(20).await;
|
||||||
@ -155,7 +159,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
config.baudrate = 1000;
|
config.baudrate = 1000;
|
||||||
config.parity = Parity::ParityEven;
|
config.parity = Parity::ParityEven;
|
||||||
let rx_buf = &mut [0u8; 16];
|
let rx_buf = &mut [0u8; 16];
|
||||||
let mut uart = BufferedUartRx::new(&mut uart, &mut irq, &mut rx, rx_buf, config);
|
let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config);
|
||||||
|
|
||||||
async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u32) {
|
async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u32) {
|
||||||
send(pin, v, Some(parity != 0)).await;
|
send(pin, v, Some(parity != 0)).await;
|
||||||
@ -202,7 +206,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.baudrate = 1000;
|
config.baudrate = 1000;
|
||||||
let rx_buf = &mut [0u8; 16];
|
let rx_buf = &mut [0u8; 16];
|
||||||
let mut uart = BufferedUartRx::new(&mut uart, &mut irq, &mut rx, rx_buf, config);
|
let mut uart = BufferedUartRx::new(&mut uart, Irqs, &mut rx, rx_buf, config);
|
||||||
|
|
||||||
async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) {
|
async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) {
|
||||||
if good {
|
if good {
|
||||||
|
@ -4,12 +4,17 @@
|
|||||||
|
|
||||||
use defmt::{assert_eq, *};
|
use defmt::{assert_eq, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::gpio::{Level, Output};
|
use embassy_rp::gpio::{Level, Output};
|
||||||
use embassy_rp::interrupt;
|
use embassy_rp::peripherals::UART0;
|
||||||
use embassy_rp::uart::{Async, Config, Error, Instance, Parity, Uart, UartRx};
|
use embassy_rp::uart::{Async, Config, Error, Instance, InterruptHandler, Parity, Uart, UartRx};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UART0_IRQ => InterruptHandler<UART0>;
|
||||||
|
});
|
||||||
|
|
||||||
async fn read<const N: usize>(uart: &mut Uart<'_, impl Instance, Async>) -> Result<[u8; N], Error> {
|
async fn read<const N: usize>(uart: &mut Uart<'_, impl Instance, Async>) -> Result<[u8; N], Error> {
|
||||||
let mut buf = [255; N];
|
let mut buf = [255; N];
|
||||||
uart.read(&mut buf).await?;
|
uart.read(&mut buf).await?;
|
||||||
@ -51,7 +56,6 @@ async fn main(_spawner: Spawner) {
|
|||||||
info!("Hello World!");
|
info!("Hello World!");
|
||||||
|
|
||||||
let (mut tx, mut rx, mut uart) = (p.PIN_0, p.PIN_1, p.UART0);
|
let (mut tx, mut rx, mut uart) = (p.PIN_0, p.PIN_1, p.UART0);
|
||||||
let mut irq = interrupt::take!(UART0_IRQ);
|
|
||||||
|
|
||||||
// We can't send too many bytes, they have to fit in the FIFO.
|
// We can't send too many bytes, they have to fit in the FIFO.
|
||||||
// This is because we aren't sending+receiving at the same time.
|
// This is because we aren't sending+receiving at the same time.
|
||||||
@ -61,7 +65,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
&mut uart,
|
&mut uart,
|
||||||
&mut tx,
|
&mut tx,
|
||||||
&mut rx,
|
&mut rx,
|
||||||
&mut irq,
|
Irqs,
|
||||||
&mut p.DMA_CH0,
|
&mut p.DMA_CH0,
|
||||||
&mut p.DMA_CH1,
|
&mut p.DMA_CH1,
|
||||||
config,
|
config,
|
||||||
@ -82,7 +86,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
&mut uart,
|
&mut uart,
|
||||||
&mut tx,
|
&mut tx,
|
||||||
&mut rx,
|
&mut rx,
|
||||||
&mut irq,
|
Irqs,
|
||||||
&mut p.DMA_CH0,
|
&mut p.DMA_CH0,
|
||||||
&mut p.DMA_CH1,
|
&mut p.DMA_CH1,
|
||||||
config,
|
config,
|
||||||
@ -111,7 +115,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
&mut uart,
|
&mut uart,
|
||||||
&mut tx,
|
&mut tx,
|
||||||
&mut rx,
|
&mut rx,
|
||||||
&mut irq,
|
Irqs,
|
||||||
&mut p.DMA_CH0,
|
&mut p.DMA_CH0,
|
||||||
&mut p.DMA_CH1,
|
&mut p.DMA_CH1,
|
||||||
config,
|
config,
|
||||||
@ -154,7 +158,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.baudrate = 1000;
|
config.baudrate = 1000;
|
||||||
config.parity = Parity::ParityEven;
|
config.parity = Parity::ParityEven;
|
||||||
let mut uart = UartRx::new(&mut uart, &mut rx, &mut irq, &mut p.DMA_CH0, config);
|
let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config);
|
||||||
|
|
||||||
async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u32) {
|
async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, parity: u32) {
|
||||||
send(pin, v, Some(parity != 0)).await;
|
send(pin, v, Some(parity != 0)).await;
|
||||||
@ -199,7 +203,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
// choose a very slow baud rate to make tests reliable even with O0
|
// choose a very slow baud rate to make tests reliable even with O0
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
config.baudrate = 1000;
|
config.baudrate = 1000;
|
||||||
let mut uart = UartRx::new(&mut uart, &mut rx, &mut irq, &mut p.DMA_CH0, config);
|
let mut uart = UartRx::new(&mut uart, &mut rx, Irqs, &mut p.DMA_CH0, config);
|
||||||
|
|
||||||
async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) {
|
async fn chr(pin: &mut Output<'_, impl embassy_rp::gpio::Pin>, v: u8, good: bool) {
|
||||||
if good {
|
if good {
|
||||||
|
@ -4,11 +4,16 @@
|
|||||||
|
|
||||||
use defmt::{assert_eq, *};
|
use defmt::{assert_eq, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::interrupt;
|
use embassy_rp::bind_interrupts;
|
||||||
use embassy_rp::uart::{Config, Uart};
|
use embassy_rp::peripherals::UART0;
|
||||||
|
use embassy_rp::uart::{BufferedInterruptHandler, Config, Uart};
|
||||||
use embedded_io::asynch::{Read, Write};
|
use embedded_io::asynch::{Read, Write};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UART0_IRQ => BufferedInterruptHandler<UART0>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_rp::init(Default::default());
|
let p = embassy_rp::init(Default::default());
|
||||||
@ -29,11 +34,10 @@ async fn main(_spawner: Spawner) {
|
|||||||
uart.blocking_read(&mut buf).unwrap();
|
uart.blocking_read(&mut buf).unwrap();
|
||||||
assert_eq!(buf, data);
|
assert_eq!(buf, data);
|
||||||
|
|
||||||
let irq = interrupt::take!(UART0_IRQ);
|
|
||||||
let tx_buf = &mut [0u8; 16];
|
let tx_buf = &mut [0u8; 16];
|
||||||
let rx_buf = &mut [0u8; 16];
|
let rx_buf = &mut [0u8; 16];
|
||||||
|
|
||||||
let mut uart = uart.into_buffered(irq, tx_buf, rx_buf);
|
let mut uart = uart.into_buffered(Irqs, tx_buf, rx_buf);
|
||||||
|
|
||||||
// Make sure we send more bytes than fits in the FIFO, to test the actual
|
// Make sure we send more bytes than fits in the FIFO, to test the actual
|
||||||
// bufferedUart.
|
// bufferedUart.
|
||||||
|
Loading…
Reference in New Issue
Block a user