nrf/uart: switch to new interrupt binding.
This commit is contained in:
parent
42c13c8c3d
commit
9cf000ef4e
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
|
use core::marker::PhantomData;
|
||||||
use core::slice;
|
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;
|
||||||
@ -23,7 +24,7 @@ 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::InterruptExt;
|
use crate::interrupt::{self, InterruptExt};
|
||||||
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,
|
||||||
};
|
};
|
||||||
@ -71,211 +72,13 @@ impl State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Buffered UARTE driver.
|
/// Interrupt handler.
|
||||||
pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> {
|
pub struct InterruptHandler<U: UarteInstance> {
|
||||||
_peri: PeripheralRef<'d, U>,
|
_phantom: PhantomData<U>,
|
||||||
timer: Timer<'d, T>,
|
|
||||||
_ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>,
|
|
||||||
_ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>,
|
|
||||||
_ppi_group: PpiGroup<'d, AnyGroup>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, U: UarteInstance, T: TimerInstance> Unpin for BufferedUarte<'d, U, T> {}
|
impl<U: UarteInstance> interrupt::Handler<U::Interrupt> for InterruptHandler<U> {
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
|
||||||
/// Create a new BufferedUarte without hardware flow control.
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if `rx_buffer.len()` is odd.
|
|
||||||
pub fn new(
|
|
||||||
uarte: impl Peripheral<P = U> + 'd,
|
|
||||||
timer: impl Peripheral<P = T> + 'd,
|
|
||||||
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
|
|
||||||
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
|
|
||||||
ppi_group: impl Peripheral<P = impl Group> + 'd,
|
|
||||||
irq: impl Peripheral<P = U::Interrupt> + 'd,
|
|
||||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
|
||||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
|
||||||
config: Config,
|
|
||||||
rx_buffer: &'d mut [u8],
|
|
||||||
tx_buffer: &'d mut [u8],
|
|
||||||
) -> Self {
|
|
||||||
into_ref!(rxd, txd, ppi_ch1, ppi_ch2, ppi_group);
|
|
||||||
Self::new_inner(
|
|
||||||
uarte,
|
|
||||||
timer,
|
|
||||||
ppi_ch1.map_into(),
|
|
||||||
ppi_ch2.map_into(),
|
|
||||||
ppi_group.map_into(),
|
|
||||||
irq,
|
|
||||||
rxd.map_into(),
|
|
||||||
txd.map_into(),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
config,
|
|
||||||
rx_buffer,
|
|
||||||
tx_buffer,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new BufferedUarte with hardware flow control (RTS/CTS)
|
|
||||||
///
|
|
||||||
/// # Panics
|
|
||||||
///
|
|
||||||
/// Panics if `rx_buffer.len()` is odd.
|
|
||||||
pub fn new_with_rtscts(
|
|
||||||
uarte: impl Peripheral<P = U> + 'd,
|
|
||||||
timer: impl Peripheral<P = T> + 'd,
|
|
||||||
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
|
|
||||||
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
|
|
||||||
ppi_group: impl Peripheral<P = impl Group> + 'd,
|
|
||||||
irq: impl Peripheral<P = U::Interrupt> + 'd,
|
|
||||||
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
|
||||||
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
|
||||||
cts: impl Peripheral<P = impl GpioPin> + 'd,
|
|
||||||
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
|
||||||
config: Config,
|
|
||||||
rx_buffer: &'d mut [u8],
|
|
||||||
tx_buffer: &'d mut [u8],
|
|
||||||
) -> Self {
|
|
||||||
into_ref!(rxd, txd, cts, rts, ppi_ch1, ppi_ch2, ppi_group);
|
|
||||||
Self::new_inner(
|
|
||||||
uarte,
|
|
||||||
timer,
|
|
||||||
ppi_ch1.map_into(),
|
|
||||||
ppi_ch2.map_into(),
|
|
||||||
ppi_group.map_into(),
|
|
||||||
irq,
|
|
||||||
rxd.map_into(),
|
|
||||||
txd.map_into(),
|
|
||||||
Some(cts.map_into()),
|
|
||||||
Some(rts.map_into()),
|
|
||||||
config,
|
|
||||||
rx_buffer,
|
|
||||||
tx_buffer,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn new_inner(
|
|
||||||
peri: impl Peripheral<P = U> + 'd,
|
|
||||||
timer: impl Peripheral<P = T> + 'd,
|
|
||||||
ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>,
|
|
||||||
ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>,
|
|
||||||
ppi_group: PeripheralRef<'d, AnyGroup>,
|
|
||||||
irq: impl Peripheral<P = U::Interrupt> + 'd,
|
|
||||||
rxd: PeripheralRef<'d, AnyPin>,
|
|
||||||
txd: PeripheralRef<'d, AnyPin>,
|
|
||||||
cts: Option<PeripheralRef<'d, AnyPin>>,
|
|
||||||
rts: Option<PeripheralRef<'d, AnyPin>>,
|
|
||||||
config: Config,
|
|
||||||
rx_buffer: &'d mut [u8],
|
|
||||||
tx_buffer: &'d mut [u8],
|
|
||||||
) -> Self {
|
|
||||||
into_ref!(peri, timer, irq);
|
|
||||||
|
|
||||||
assert!(rx_buffer.len() % 2 == 0);
|
|
||||||
|
|
||||||
let r = U::regs();
|
|
||||||
|
|
||||||
rxd.conf().write(|w| w.input().connect().drive().h0h1());
|
|
||||||
r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
|
|
||||||
|
|
||||||
txd.set_high();
|
|
||||||
txd.conf().write(|w| w.dir().output().drive().h0h1());
|
|
||||||
r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) });
|
|
||||||
|
|
||||||
if let Some(pin) = &cts {
|
|
||||||
pin.conf().write(|w| w.input().connect().drive().h0h1());
|
|
||||||
}
|
|
||||||
r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
|
|
||||||
|
|
||||||
if let Some(pin) = &rts {
|
|
||||||
pin.set_high();
|
|
||||||
pin.conf().write(|w| w.dir().output().drive().h0h1());
|
|
||||||
}
|
|
||||||
r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
|
|
||||||
|
|
||||||
// Initialize state
|
|
||||||
let s = U::buffered_state();
|
|
||||||
s.tx_count.store(0, Ordering::Relaxed);
|
|
||||||
s.rx_bufs.store(0, Ordering::Relaxed);
|
|
||||||
let len = tx_buffer.len();
|
|
||||||
unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
|
|
||||||
let len = rx_buffer.len();
|
|
||||||
unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
|
|
||||||
|
|
||||||
// Configure
|
|
||||||
r.config.write(|w| {
|
|
||||||
w.hwfc().bit(false);
|
|
||||||
w.parity().variant(config.parity);
|
|
||||||
w
|
|
||||||
});
|
|
||||||
r.baudrate.write(|w| w.baudrate().variant(config.baudrate));
|
|
||||||
|
|
||||||
// clear errors
|
|
||||||
let errors = r.errorsrc.read().bits();
|
|
||||||
r.errorsrc.write(|w| unsafe { w.bits(errors) });
|
|
||||||
|
|
||||||
r.events_rxstarted.reset();
|
|
||||||
r.events_txstarted.reset();
|
|
||||||
r.events_error.reset();
|
|
||||||
r.events_endrx.reset();
|
|
||||||
r.events_endtx.reset();
|
|
||||||
|
|
||||||
// Enable interrupts
|
|
||||||
r.intenclr.write(|w| unsafe { w.bits(!0) });
|
|
||||||
r.intenset.write(|w| {
|
|
||||||
w.endtx().set();
|
|
||||||
w.rxstarted().set();
|
|
||||||
w.error().set();
|
|
||||||
w
|
|
||||||
});
|
|
||||||
|
|
||||||
// Enable UARTE instance
|
|
||||||
apply_workaround_for_enable_anomaly(&r);
|
|
||||||
r.enable.write(|w| w.enable().enabled());
|
|
||||||
|
|
||||||
// Configure byte counter.
|
|
||||||
let mut timer = Timer::new_counter(timer);
|
|
||||||
timer.cc(1).write(rx_buffer.len() as u32 * 2);
|
|
||||||
timer.cc(1).short_compare_clear();
|
|
||||||
timer.clear();
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
let mut ppi_ch1 = Ppi::new_one_to_one(ppi_ch1, Event::from_reg(&r.events_rxdrdy), timer.task_count());
|
|
||||||
ppi_ch1.enable();
|
|
||||||
|
|
||||||
s.rx_ppi_ch.store(ppi_ch2.number() as u8, Ordering::Relaxed);
|
|
||||||
let mut ppi_group = PpiGroup::new(ppi_group);
|
|
||||||
let mut ppi_ch2 = Ppi::new_one_to_two(
|
|
||||||
ppi_ch2,
|
|
||||||
Event::from_reg(&r.events_endrx),
|
|
||||||
Task::from_reg(&r.tasks_startrx),
|
|
||||||
ppi_group.task_disable_all(),
|
|
||||||
);
|
|
||||||
ppi_ch2.disable();
|
|
||||||
ppi_group.add_channel(&ppi_ch2);
|
|
||||||
|
|
||||||
irq.disable();
|
|
||||||
irq.set_handler(Self::on_interrupt);
|
|
||||||
irq.pend();
|
|
||||||
irq.enable();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
_peri: peri,
|
|
||||||
timer,
|
|
||||||
_ppi_ch1: ppi_ch1,
|
|
||||||
_ppi_ch2: ppi_ch2,
|
|
||||||
_ppi_group: ppi_group,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pend_irq() {
|
|
||||||
unsafe { <U::Interrupt as Interrupt>::steal() }.pend()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_interrupt(_: *mut ()) {
|
|
||||||
//trace!("irq: start");
|
//trace!("irq: start");
|
||||||
let r = U::regs();
|
let r = U::regs();
|
||||||
let s = U::buffered_state();
|
let s = U::buffered_state();
|
||||||
@ -374,6 +177,206 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
|
|||||||
|
|
||||||
//trace!("irq: end");
|
//trace!("irq: end");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Buffered UARTE driver.
|
||||||
|
pub struct BufferedUarte<'d, U: UarteInstance, T: TimerInstance> {
|
||||||
|
_peri: PeripheralRef<'d, U>,
|
||||||
|
timer: Timer<'d, T>,
|
||||||
|
_ppi_ch1: Ppi<'d, AnyConfigurableChannel, 1, 1>,
|
||||||
|
_ppi_ch2: Ppi<'d, AnyConfigurableChannel, 1, 2>,
|
||||||
|
_ppi_group: PpiGroup<'d, AnyGroup>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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 BufferedUarte without hardware flow control.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if `rx_buffer.len()` is odd.
|
||||||
|
pub fn new(
|
||||||
|
uarte: impl Peripheral<P = U> + 'd,
|
||||||
|
timer: impl Peripheral<P = T> + 'd,
|
||||||
|
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
|
||||||
|
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
|
||||||
|
ppi_group: impl Peripheral<P = impl Group> + 'd,
|
||||||
|
_irq: impl interrupt::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
|
||||||
|
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
|
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
|
config: Config,
|
||||||
|
rx_buffer: &'d mut [u8],
|
||||||
|
tx_buffer: &'d mut [u8],
|
||||||
|
) -> Self {
|
||||||
|
into_ref!(rxd, txd, ppi_ch1, ppi_ch2, ppi_group);
|
||||||
|
Self::new_inner(
|
||||||
|
uarte,
|
||||||
|
timer,
|
||||||
|
ppi_ch1.map_into(),
|
||||||
|
ppi_ch2.map_into(),
|
||||||
|
ppi_group.map_into(),
|
||||||
|
rxd.map_into(),
|
||||||
|
txd.map_into(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
config,
|
||||||
|
rx_buffer,
|
||||||
|
tx_buffer,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new BufferedUarte with hardware flow control (RTS/CTS)
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if `rx_buffer.len()` is odd.
|
||||||
|
pub fn new_with_rtscts(
|
||||||
|
uarte: impl Peripheral<P = U> + 'd,
|
||||||
|
timer: impl Peripheral<P = T> + 'd,
|
||||||
|
ppi_ch1: impl Peripheral<P = impl ConfigurableChannel> + 'd,
|
||||||
|
ppi_ch2: impl Peripheral<P = impl ConfigurableChannel> + 'd,
|
||||||
|
ppi_group: impl Peripheral<P = impl Group> + 'd,
|
||||||
|
_irq: impl interrupt::Binding<U::Interrupt, InterruptHandler<U>> + 'd,
|
||||||
|
rxd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
|
txd: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
|
cts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
|
rts: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
|
config: Config,
|
||||||
|
rx_buffer: &'d mut [u8],
|
||||||
|
tx_buffer: &'d mut [u8],
|
||||||
|
) -> Self {
|
||||||
|
into_ref!(rxd, txd, cts, rts, ppi_ch1, ppi_ch2, ppi_group);
|
||||||
|
Self::new_inner(
|
||||||
|
uarte,
|
||||||
|
timer,
|
||||||
|
ppi_ch1.map_into(),
|
||||||
|
ppi_ch2.map_into(),
|
||||||
|
ppi_group.map_into(),
|
||||||
|
rxd.map_into(),
|
||||||
|
txd.map_into(),
|
||||||
|
Some(cts.map_into()),
|
||||||
|
Some(rts.map_into()),
|
||||||
|
config,
|
||||||
|
rx_buffer,
|
||||||
|
tx_buffer,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_inner(
|
||||||
|
peri: impl Peripheral<P = U> + 'd,
|
||||||
|
timer: impl Peripheral<P = T> + 'd,
|
||||||
|
ppi_ch1: PeripheralRef<'d, AnyConfigurableChannel>,
|
||||||
|
ppi_ch2: PeripheralRef<'d, AnyConfigurableChannel>,
|
||||||
|
ppi_group: PeripheralRef<'d, AnyGroup>,
|
||||||
|
rxd: PeripheralRef<'d, AnyPin>,
|
||||||
|
txd: PeripheralRef<'d, AnyPin>,
|
||||||
|
cts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
|
rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
|
config: Config,
|
||||||
|
rx_buffer: &'d mut [u8],
|
||||||
|
tx_buffer: &'d mut [u8],
|
||||||
|
) -> Self {
|
||||||
|
into_ref!(peri, timer);
|
||||||
|
|
||||||
|
assert!(rx_buffer.len() % 2 == 0);
|
||||||
|
|
||||||
|
let r = U::regs();
|
||||||
|
|
||||||
|
rxd.conf().write(|w| w.input().connect().drive().h0h1());
|
||||||
|
r.psel.rxd.write(|w| unsafe { w.bits(rxd.psel_bits()) });
|
||||||
|
|
||||||
|
txd.set_high();
|
||||||
|
txd.conf().write(|w| w.dir().output().drive().h0h1());
|
||||||
|
r.psel.txd.write(|w| unsafe { w.bits(txd.psel_bits()) });
|
||||||
|
|
||||||
|
if let Some(pin) = &cts {
|
||||||
|
pin.conf().write(|w| w.input().connect().drive().h0h1());
|
||||||
|
}
|
||||||
|
r.psel.cts.write(|w| unsafe { w.bits(cts.psel_bits()) });
|
||||||
|
|
||||||
|
if let Some(pin) = &rts {
|
||||||
|
pin.set_high();
|
||||||
|
pin.conf().write(|w| w.dir().output().drive().h0h1());
|
||||||
|
}
|
||||||
|
r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
|
||||||
|
|
||||||
|
// Initialize state
|
||||||
|
let s = U::buffered_state();
|
||||||
|
s.tx_count.store(0, Ordering::Relaxed);
|
||||||
|
s.rx_bufs.store(0, Ordering::Relaxed);
|
||||||
|
let len = tx_buffer.len();
|
||||||
|
unsafe { s.tx_buf.init(tx_buffer.as_mut_ptr(), len) };
|
||||||
|
let len = rx_buffer.len();
|
||||||
|
unsafe { s.rx_buf.init(rx_buffer.as_mut_ptr(), len) };
|
||||||
|
|
||||||
|
// Configure
|
||||||
|
r.config.write(|w| {
|
||||||
|
w.hwfc().bit(false);
|
||||||
|
w.parity().variant(config.parity);
|
||||||
|
w
|
||||||
|
});
|
||||||
|
r.baudrate.write(|w| w.baudrate().variant(config.baudrate));
|
||||||
|
|
||||||
|
// clear errors
|
||||||
|
let errors = r.errorsrc.read().bits();
|
||||||
|
r.errorsrc.write(|w| unsafe { w.bits(errors) });
|
||||||
|
|
||||||
|
r.events_rxstarted.reset();
|
||||||
|
r.events_txstarted.reset();
|
||||||
|
r.events_error.reset();
|
||||||
|
r.events_endrx.reset();
|
||||||
|
r.events_endtx.reset();
|
||||||
|
|
||||||
|
// Enable interrupts
|
||||||
|
r.intenclr.write(|w| unsafe { w.bits(!0) });
|
||||||
|
r.intenset.write(|w| {
|
||||||
|
w.endtx().set();
|
||||||
|
w.rxstarted().set();
|
||||||
|
w.error().set();
|
||||||
|
w
|
||||||
|
});
|
||||||
|
|
||||||
|
// Enable UARTE instance
|
||||||
|
apply_workaround_for_enable_anomaly(&r);
|
||||||
|
r.enable.write(|w| w.enable().enabled());
|
||||||
|
|
||||||
|
// Configure byte counter.
|
||||||
|
let mut timer = Timer::new_counter(timer);
|
||||||
|
timer.cc(1).write(rx_buffer.len() as u32 * 2);
|
||||||
|
timer.cc(1).short_compare_clear();
|
||||||
|
timer.clear();
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
let mut ppi_ch1 = Ppi::new_one_to_one(ppi_ch1, Event::from_reg(&r.events_rxdrdy), timer.task_count());
|
||||||
|
ppi_ch1.enable();
|
||||||
|
|
||||||
|
s.rx_ppi_ch.store(ppi_ch2.number() as u8, Ordering::Relaxed);
|
||||||
|
let mut ppi_group = PpiGroup::new(ppi_group);
|
||||||
|
let mut ppi_ch2 = Ppi::new_one_to_two(
|
||||||
|
ppi_ch2,
|
||||||
|
Event::from_reg(&r.events_endrx),
|
||||||
|
Task::from_reg(&r.tasks_startrx),
|
||||||
|
ppi_group.task_disable_all(),
|
||||||
|
);
|
||||||
|
ppi_ch2.disable();
|
||||||
|
ppi_group.add_channel(&ppi_ch2);
|
||||||
|
|
||||||
|
unsafe { U::Interrupt::steal() }.pend();
|
||||||
|
unsafe { U::Interrupt::steal() }.enable();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
_peri: peri,
|
||||||
|
timer,
|
||||||
|
_ppi_ch1: ppi_ch1,
|
||||||
|
_ppi_ch2: ppi_ch2,
|
||||||
|
_ppi_group: ppi_group,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pend_irq() {
|
||||||
|
unsafe { <U::Interrupt as Interrupt>::steal() }.pend()
|
||||||
|
}
|
||||||
|
|
||||||
/// Adjust the baud rate to the provided value.
|
/// Adjust the baud rate to the provided value.
|
||||||
pub fn set_baudrate(&mut self, baudrate: Baudrate) {
|
pub fn set_baudrate(&mut self, baudrate: Baudrate) {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
|
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;
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ 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::{Interrupt, InterruptExt};
|
use crate::interrupt::{self, Interrupt, InterruptExt};
|
||||||
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;
|
||||||
@ -62,6 +63,27 @@ pub enum Error {
|
|||||||
BufferNotInRAM,
|
BufferNotInRAM,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Interrupt handler.
|
||||||
|
pub struct InterruptHandler<T: Instance> {
|
||||||
|
_phantom: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Instance> interrupt::Handler<T::Interrupt> for InterruptHandler<T> {
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
|
let r = T::regs();
|
||||||
|
let s = T::state();
|
||||||
|
|
||||||
|
if r.events_endrx.read().bits() != 0 {
|
||||||
|
s.endrx_waker.wake();
|
||||||
|
r.intenclr.write(|w| w.endrx().clear());
|
||||||
|
}
|
||||||
|
if r.events_endtx.read().bits() != 0 {
|
||||||
|
s.endtx_waker.wake();
|
||||||
|
r.intenclr.write(|w| w.endtx().clear());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UARTE driver.
|
/// UARTE driver.
|
||||||
pub struct Uarte<'d, T: Instance> {
|
pub struct Uarte<'d, T: Instance> {
|
||||||
tx: UarteTx<'d, T>,
|
tx: UarteTx<'d, T>,
|
||||||
@ -86,19 +108,19 @@ 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 Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::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,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(rxd, txd);
|
into_ref!(rxd, txd);
|
||||||
Self::new_inner(uarte, irq, rxd.map_into(), txd.map_into(), None, None, config)
|
Self::new_inner(uarte, rxd.map_into(), txd.map_into(), None, None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::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,
|
||||||
@ -108,7 +130,6 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
|||||||
into_ref!(rxd, txd, cts, rts);
|
into_ref!(rxd, txd, cts, rts);
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
uarte,
|
uarte,
|
||||||
irq,
|
|
||||||
rxd.map_into(),
|
rxd.map_into(),
|
||||||
txd.map_into(),
|
txd.map_into(),
|
||||||
Some(cts.map_into()),
|
Some(cts.map_into()),
|
||||||
@ -119,14 +140,13 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
|||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
uarte: impl Peripheral<P = T> + 'd,
|
uarte: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
|
||||||
rxd: PeripheralRef<'d, AnyPin>,
|
rxd: PeripheralRef<'d, AnyPin>,
|
||||||
txd: PeripheralRef<'d, AnyPin>,
|
txd: PeripheralRef<'d, AnyPin>,
|
||||||
cts: Option<PeripheralRef<'d, AnyPin>>,
|
cts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
rts: Option<PeripheralRef<'d, AnyPin>>,
|
rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(uarte, irq);
|
into_ref!(uarte);
|
||||||
|
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
@ -148,9 +168,8 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
|||||||
}
|
}
|
||||||
r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
|
r.psel.rts.write(|w| unsafe { w.bits(rts.psel_bits()) });
|
||||||
|
|
||||||
irq.set_handler(Self::on_interrupt);
|
unsafe { T::Interrupt::steal() }.unpend();
|
||||||
irq.unpend();
|
unsafe { T::Interrupt::steal() }.enable();
|
||||||
irq.enable();
|
|
||||||
|
|
||||||
let hardware_flow_control = match (rts.is_some(), cts.is_some()) {
|
let hardware_flow_control = match (rts.is_some(), cts.is_some()) {
|
||||||
(false, false) => false,
|
(false, false) => false,
|
||||||
@ -238,20 +257,6 @@ impl<'d, T: Instance> Uarte<'d, T> {
|
|||||||
Event::from_reg(&r.events_endtx)
|
Event::from_reg(&r.events_endtx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_interrupt(_: *mut ()) {
|
|
||||||
let r = T::regs();
|
|
||||||
let s = T::state();
|
|
||||||
|
|
||||||
if r.events_endrx.read().bits() != 0 {
|
|
||||||
s.endrx_waker.wake();
|
|
||||||
r.intenclr.write(|w| w.endrx().clear());
|
|
||||||
}
|
|
||||||
if r.events_endtx.read().bits() != 0 {
|
|
||||||
s.endtx_waker.wake();
|
|
||||||
r.intenclr.write(|w| w.endtx().clear());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read bytes until the buffer is filled.
|
/// Read bytes until the buffer is filled.
|
||||||
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
pub async fn read(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
|
||||||
self.rx.read(buffer).await
|
self.rx.read(buffer).await
|
||||||
@ -308,34 +313,33 @@ 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 Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::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 {
|
||||||
into_ref!(txd);
|
into_ref!(txd);
|
||||||
Self::new_inner(uarte, irq, txd.map_into(), None, config)
|
Self::new_inner(uarte, txd.map_into(), None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::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,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(txd, cts);
|
into_ref!(txd, cts);
|
||||||
Self::new_inner(uarte, irq, txd.map_into(), Some(cts.map_into()), config)
|
Self::new_inner(uarte, txd.map_into(), Some(cts.map_into()), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
uarte: impl Peripheral<P = T> + 'd,
|
uarte: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
|
||||||
txd: PeripheralRef<'d, AnyPin>,
|
txd: PeripheralRef<'d, AnyPin>,
|
||||||
cts: Option<PeripheralRef<'d, AnyPin>>,
|
cts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(uarte, irq);
|
into_ref!(uarte);
|
||||||
|
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
@ -354,9 +358,8 @@ impl<'d, T: Instance> UarteTx<'d, T> {
|
|||||||
let hardware_flow_control = cts.is_some();
|
let hardware_flow_control = cts.is_some();
|
||||||
configure(r, config, hardware_flow_control);
|
configure(r, config, hardware_flow_control);
|
||||||
|
|
||||||
irq.set_handler(Uarte::<T>::on_interrupt);
|
unsafe { T::Interrupt::steal() }.unpend();
|
||||||
irq.unpend();
|
unsafe { T::Interrupt::steal() }.enable();
|
||||||
irq.enable();
|
|
||||||
|
|
||||||
let s = T::state();
|
let s = T::state();
|
||||||
s.tx_rx_refcount.store(1, Ordering::Relaxed);
|
s.tx_rx_refcount.store(1, Ordering::Relaxed);
|
||||||
@ -506,34 +509,33 @@ 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 Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::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 {
|
||||||
into_ref!(rxd);
|
into_ref!(rxd);
|
||||||
Self::new_inner(uarte, irq, rxd.map_into(), None, config)
|
Self::new_inner(uarte, rxd.map_into(), None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::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,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(rxd, rts);
|
into_ref!(rxd, rts);
|
||||||
Self::new_inner(uarte, irq, rxd.map_into(), Some(rts.map_into()), config)
|
Self::new_inner(uarte, rxd.map_into(), Some(rts.map_into()), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
uarte: impl Peripheral<P = T> + 'd,
|
uarte: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
|
||||||
rxd: PeripheralRef<'d, AnyPin>,
|
rxd: PeripheralRef<'d, AnyPin>,
|
||||||
rts: Option<PeripheralRef<'d, AnyPin>>,
|
rts: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(uarte, irq);
|
into_ref!(uarte);
|
||||||
|
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
@ -549,9 +551,8 @@ impl<'d, T: Instance> UarteRx<'d, T> {
|
|||||||
r.psel.txd.write(|w| w.connect().disconnected());
|
r.psel.txd.write(|w| w.connect().disconnected());
|
||||||
r.psel.cts.write(|w| w.connect().disconnected());
|
r.psel.cts.write(|w| w.connect().disconnected());
|
||||||
|
|
||||||
irq.set_handler(Uarte::<T>::on_interrupt);
|
unsafe { T::Interrupt::steal() }.unpend();
|
||||||
irq.unpend();
|
unsafe { T::Interrupt::steal() }.enable();
|
||||||
irq.enable();
|
|
||||||
|
|
||||||
let hardware_flow_control = rts.is_some();
|
let hardware_flow_control = rts.is_some();
|
||||||
configure(r, config, hardware_flow_control);
|
configure(r, config, hardware_flow_control);
|
||||||
|
@ -4,11 +4,15 @@
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::buffered_uarte::BufferedUarte;
|
use embassy_nrf::buffered_uarte::{self, BufferedUarte};
|
||||||
use embassy_nrf::{interrupt, uarte};
|
use embassy_nrf::{bind_interrupts, peripherals, uarte};
|
||||||
use embedded_io::asynch::Write;
|
use embedded_io::asynch::Write;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_nrf::init(Default::default());
|
let p = embassy_nrf::init(Default::default());
|
||||||
@ -19,14 +23,13 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut tx_buffer = [0u8; 4096];
|
let mut tx_buffer = [0u8; 4096];
|
||||||
let mut rx_buffer = [0u8; 4096];
|
let mut rx_buffer = [0u8; 4096];
|
||||||
|
|
||||||
let irq = interrupt::take!(UARTE0_UART0);
|
|
||||||
let mut u = BufferedUarte::new(
|
let mut u = BufferedUarte::new(
|
||||||
p.UARTE0,
|
p.UARTE0,
|
||||||
p.TIMER0,
|
p.TIMER0,
|
||||||
p.PPI_CH0,
|
p.PPI_CH0,
|
||||||
p.PPI_CH1,
|
p.PPI_CH1,
|
||||||
p.PPI_GROUP0,
|
p.PPI_GROUP0,
|
||||||
irq,
|
Irqs,
|
||||||
p.P0_08,
|
p.P0_08,
|
||||||
p.P0_06,
|
p.P0_06,
|
||||||
config,
|
config,
|
||||||
|
@ -4,9 +4,13 @@
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::{interrupt, uarte};
|
use embassy_nrf::{bind_interrupts, peripherals, uarte};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UARTE0_UART0 => uarte::InterruptHandler<peripherals::UARTE0>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_nrf::init(Default::default());
|
let p = embassy_nrf::init(Default::default());
|
||||||
@ -14,8 +18,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
config.parity = uarte::Parity::EXCLUDED;
|
config.parity = uarte::Parity::EXCLUDED;
|
||||||
config.baudrate = uarte::Baudrate::BAUD115200;
|
config.baudrate = uarte::Baudrate::BAUD115200;
|
||||||
|
|
||||||
let irq = interrupt::take!(UARTE0_UART0);
|
let mut uart = uarte::Uarte::new(p.UARTE0, Irqs, p.P0_08, p.P0_06, config);
|
||||||
let mut uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
|
|
||||||
|
|
||||||
info!("uarte initialized!");
|
info!("uarte initialized!");
|
||||||
|
|
||||||
|
@ -4,9 +4,14 @@
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::{interrupt, uarte};
|
use embassy_nrf::peripherals::UARTE0;
|
||||||
|
use embassy_nrf::{bind_interrupts, uarte};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UARTE0_UART0 => uarte::InterruptHandler<UARTE0>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_nrf::init(Default::default());
|
let p = embassy_nrf::init(Default::default());
|
||||||
@ -14,8 +19,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
config.parity = uarte::Parity::EXCLUDED;
|
config.parity = uarte::Parity::EXCLUDED;
|
||||||
config.baudrate = uarte::Baudrate::BAUD115200;
|
config.baudrate = uarte::Baudrate::BAUD115200;
|
||||||
|
|
||||||
let irq = interrupt::take!(UARTE0_UART0);
|
let uart = uarte::Uarte::new(p.UARTE0, Irqs, p.P0_08, p.P0_06, config);
|
||||||
let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
|
|
||||||
let (mut tx, mut rx) = uart.split_with_idle(p.TIMER0, p.PPI_CH0, p.PPI_CH1);
|
let (mut tx, mut rx) = uart.split_with_idle(p.TIMER0, p.PPI_CH0, p.PPI_CH1);
|
||||||
|
|
||||||
info!("uarte initialized!");
|
info!("uarte initialized!");
|
||||||
|
@ -6,13 +6,17 @@ use defmt::*;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::peripherals::UARTE0;
|
use embassy_nrf::peripherals::UARTE0;
|
||||||
use embassy_nrf::uarte::UarteRx;
|
use embassy_nrf::uarte::UarteRx;
|
||||||
use embassy_nrf::{interrupt, uarte};
|
use embassy_nrf::{bind_interrupts, uarte};
|
||||||
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex;
|
||||||
use embassy_sync::channel::Channel;
|
use embassy_sync::channel::Channel;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new();
|
static CHANNEL: Channel<ThreadModeRawMutex, [u8; 8], 1> = Channel::new();
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UARTE0_UART0 => uarte::InterruptHandler<UARTE0>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(spawner: Spawner) {
|
async fn main(spawner: Spawner) {
|
||||||
let p = embassy_nrf::init(Default::default());
|
let p = embassy_nrf::init(Default::default());
|
||||||
@ -20,8 +24,7 @@ async fn main(spawner: Spawner) {
|
|||||||
config.parity = uarte::Parity::EXCLUDED;
|
config.parity = uarte::Parity::EXCLUDED;
|
||||||
config.baudrate = uarte::Baudrate::BAUD115200;
|
config.baudrate = uarte::Baudrate::BAUD115200;
|
||||||
|
|
||||||
let irq = interrupt::take!(UARTE0_UART0);
|
let uart = uarte::Uarte::new(p.UARTE0, Irqs, p.P0_08, p.P0_06, config);
|
||||||
let uart = uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, config);
|
|
||||||
let (mut tx, rx) = uart.split();
|
let (mut tx, rx) = uart.split();
|
||||||
|
|
||||||
info!("uarte initialized!");
|
info!("uarte initialized!");
|
||||||
|
@ -4,9 +4,14 @@
|
|||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::{interrupt, uarte};
|
use embassy_nrf::peripherals::SERIAL0;
|
||||||
|
use embassy_nrf::{bind_interrupts, uarte};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
SERIAL0 => uarte::InterruptHandler<SERIAL0>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_nrf::init(Default::default());
|
let p = embassy_nrf::init(Default::default());
|
||||||
@ -14,8 +19,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
config.parity = uarte::Parity::EXCLUDED;
|
config.parity = uarte::Parity::EXCLUDED;
|
||||||
config.baudrate = uarte::Baudrate::BAUD115200;
|
config.baudrate = uarte::Baudrate::BAUD115200;
|
||||||
|
|
||||||
let irq = interrupt::take!(SERIAL0);
|
let mut uart = uarte::Uarte::new(p.SERIAL0, Irqs, p.P1_00, p.P1_01, config);
|
||||||
let mut uart = uarte::Uarte::new(p.SERIAL0, irq, p.P1_00, p.P1_01, config);
|
|
||||||
|
|
||||||
info!("uarte initialized!");
|
info!("uarte initialized!");
|
||||||
|
|
||||||
|
@ -5,10 +5,14 @@
|
|||||||
use defmt::{assert_eq, *};
|
use defmt::{assert_eq, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
use embassy_nrf::buffered_uarte::BufferedUarte;
|
use embassy_nrf::buffered_uarte::{self, BufferedUarte};
|
||||||
use embassy_nrf::{interrupt, uarte};
|
use embassy_nrf::{bind_interrupts, peripherals, uarte};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let p = embassy_nrf::init(Default::default());
|
let p = embassy_nrf::init(Default::default());
|
||||||
@ -25,7 +29,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
p.PPI_CH0,
|
p.PPI_CH0,
|
||||||
p.PPI_CH1,
|
p.PPI_CH1,
|
||||||
p.PPI_GROUP0,
|
p.PPI_GROUP0,
|
||||||
interrupt::take!(UARTE0_UART0),
|
Irqs,
|
||||||
p.P1_03,
|
p.P1_03,
|
||||||
p.P1_02,
|
p.P1_02,
|
||||||
config.clone(),
|
config.clone(),
|
||||||
|
@ -7,14 +7,19 @@ use core::ptr::NonNull;
|
|||||||
|
|
||||||
use defmt::{assert_eq, *};
|
use defmt::{assert_eq, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::buffered_uarte::BufferedUarte;
|
use embassy_nrf::buffered_uarte::{self, BufferedUarte};
|
||||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||||
use embassy_nrf::ppi::{Event, Ppi, Task};
|
use embassy_nrf::ppi::{Event, Ppi, Task};
|
||||||
use embassy_nrf::uarte::Uarte;
|
use embassy_nrf::uarte::Uarte;
|
||||||
use embassy_nrf::{interrupt, pac, uarte};
|
use embassy_nrf::{bind_interrupts, pac, peripherals, uarte};
|
||||||
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 {
|
||||||
|
UARTE0_UART0 => buffered_uarte::InterruptHandler<peripherals::UARTE0>;
|
||||||
|
UARTE1 => uarte::InterruptHandler<peripherals::UARTE1>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_spawner: Spawner) {
|
async fn main(_spawner: Spawner) {
|
||||||
let mut p = embassy_nrf::init(Default::default());
|
let mut p = embassy_nrf::init(Default::default());
|
||||||
@ -33,7 +38,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
p.PPI_CH0,
|
p.PPI_CH0,
|
||||||
p.PPI_CH1,
|
p.PPI_CH1,
|
||||||
p.PPI_GROUP0,
|
p.PPI_GROUP0,
|
||||||
interrupt::take!(UARTE0_UART0),
|
Irqs,
|
||||||
p.P1_03,
|
p.P1_03,
|
||||||
p.P1_04,
|
p.P1_04,
|
||||||
config.clone(),
|
config.clone(),
|
||||||
@ -49,7 +54,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
// Tx spam in a loop.
|
// Tx spam in a loop.
|
||||||
const NSPAM: usize = 17;
|
const NSPAM: usize = 17;
|
||||||
static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
|
static mut TX_BUF: [u8; NSPAM] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
|
||||||
let _spam = Uarte::new(p.UARTE1, interrupt::take!(UARTE1), p.P1_01, p.P1_02, config.clone());
|
let _spam = Uarte::new(p.UARTE1, Irqs, p.P1_01, p.P1_02, config.clone());
|
||||||
let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) };
|
let spam_peri: pac::UARTE1 = unsafe { mem::transmute(()) };
|
||||||
let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) };
|
let event = unsafe { Event::new_unchecked(NonNull::new_unchecked(&spam_peri.events_endtx as *const _ as _)) };
|
||||||
let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) };
|
let task = unsafe { Task::new_unchecked(NonNull::new_unchecked(&spam_peri.tasks_starttx as *const _ as _)) };
|
||||||
|
Loading…
Reference in New Issue
Block a user