Update drivers to owned irqs.
This commit is contained in:
parent
4b8d8ba87e
commit
af5454fbfe
@ -17,10 +17,10 @@ use embedded_hal::digital::v2::OutputPin;
|
|||||||
|
|
||||||
use crate::hal::gpio::{Floating, Input, Output, Pin as GpioPin, Port as GpioPort, PushPull};
|
use crate::hal::gpio::{Floating, Input, Output, Pin as GpioPin, Port as GpioPort, PushPull};
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
use crate::interrupt::CriticalSection;
|
use crate::interrupt::{CriticalSection, OwnedInterrupt};
|
||||||
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
|
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
|
||||||
use crate::pac::UARTE1;
|
use crate::pac::UARTE1;
|
||||||
use crate::pac::{uarte0, Interrupt, UARTE0};
|
use crate::pac::{uarte0, UARTE0};
|
||||||
|
|
||||||
// Re-export SVD variants to allow user to directly set values
|
// Re-export SVD variants to allow user to directly set values
|
||||||
pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
|
pub use uarte0::{baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity};
|
||||||
@ -141,8 +141,9 @@ pub struct BufferedUarte<T: Instance> {
|
|||||||
// public because it needs to be used in Instance::{get_state, set_state}, but
|
// public because it needs to be used in Instance::{get_state, set_state}, but
|
||||||
// should not be used outside the module
|
// should not be used outside the module
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct UarteState<T> {
|
pub struct UarteState<T: Instance> {
|
||||||
inner: T,
|
inner: T,
|
||||||
|
irq: T::Interrupt,
|
||||||
|
|
||||||
rx: RingBuf,
|
rx: RingBuf,
|
||||||
rx_state: RxState,
|
rx_state: RxState,
|
||||||
@ -164,7 +165,13 @@ fn port_bit(port: GpioPort) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Instance> BufferedUarte<T> {
|
impl<T: Instance> BufferedUarte<T> {
|
||||||
pub fn new(uarte: T, mut pins: Pins, parity: Parity, baudrate: Baudrate) -> Self {
|
pub fn new(
|
||||||
|
uarte: T,
|
||||||
|
irq: T::Interrupt,
|
||||||
|
mut pins: Pins,
|
||||||
|
parity: Parity,
|
||||||
|
baudrate: Baudrate,
|
||||||
|
) -> Self {
|
||||||
// Select pins
|
// Select pins
|
||||||
uarte.psel.rxd.write(|w| {
|
uarte.psel.rxd.write(|w| {
|
||||||
let w = unsafe { w.pin().bits(pins.rxd.pin()) };
|
let w = unsafe { w.pin().bits(pins.rxd.pin()) };
|
||||||
@ -222,6 +229,7 @@ impl<T: Instance> BufferedUarte<T> {
|
|||||||
started: false,
|
started: false,
|
||||||
state: UnsafeCell::new(UarteState {
|
state: UnsafeCell::new(UarteState {
|
||||||
inner: uarte,
|
inner: uarte,
|
||||||
|
irq,
|
||||||
|
|
||||||
rx: RingBuf::new(),
|
rx: RingBuf::new(),
|
||||||
rx_state: RxState::Idle,
|
rx_state: RxState::Idle,
|
||||||
@ -287,9 +295,12 @@ impl<T: Instance> AsyncWrite for BufferedUarte<T> {
|
|||||||
|
|
||||||
impl<T: Instance> UarteState<T> {
|
impl<T: Instance> UarteState<T> {
|
||||||
pub fn start(self: Pin<&mut Self>) {
|
pub fn start(self: Pin<&mut Self>) {
|
||||||
interrupt::set_priority(T::interrupt(), interrupt::Priority::Level7);
|
self.irq.set_handler(|| unsafe {
|
||||||
interrupt::enable(T::interrupt());
|
interrupt::free(|cs| T::get_state(cs).as_mut().unwrap().on_interrupt());
|
||||||
interrupt::pend(T::interrupt());
|
});
|
||||||
|
|
||||||
|
self.irq.pend();
|
||||||
|
self.irq.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
|
fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> {
|
||||||
@ -324,7 +335,7 @@ impl<T: Instance> UarteState<T> {
|
|||||||
let this = unsafe { self.get_unchecked_mut() };
|
let this = unsafe { self.get_unchecked_mut() };
|
||||||
trace!("consume {:?}", amt);
|
trace!("consume {:?}", amt);
|
||||||
this.rx.pop(amt);
|
this.rx.pop(amt);
|
||||||
interrupt::pend(T::interrupt());
|
this.irq.pend();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> {
|
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> {
|
||||||
@ -350,7 +361,7 @@ impl<T: Instance> UarteState<T> {
|
|||||||
// before any DMA action has started
|
// before any DMA action has started
|
||||||
compiler_fence(Ordering::SeqCst);
|
compiler_fence(Ordering::SeqCst);
|
||||||
|
|
||||||
interrupt::pend(T::interrupt());
|
this.irq.pend();
|
||||||
|
|
||||||
Poll::Ready(Ok(n))
|
Poll::Ready(Ok(n))
|
||||||
}
|
}
|
||||||
@ -509,7 +520,7 @@ mod private {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Instance: Deref<Target = uarte0::RegisterBlock> + Sized + private::Sealed {
|
pub trait Instance: Deref<Target = uarte0::RegisterBlock> + Sized + private::Sealed {
|
||||||
fn interrupt() -> Interrupt;
|
type Interrupt: OwnedInterrupt;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self>;
|
fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self>;
|
||||||
@ -518,25 +529,12 @@ pub trait Instance: Deref<Target = uarte0::RegisterBlock> + Sized + private::Sea
|
|||||||
fn set_state(_cs: &CriticalSection, state: *mut UarteState<Self>);
|
fn set_state(_cs: &CriticalSection, state: *mut UarteState<Self>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[interrupt]
|
|
||||||
unsafe fn UARTE0_UART0() {
|
|
||||||
interrupt::free(|cs| UARTE0::get_state(cs).as_mut().unwrap().on_interrupt());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
|
|
||||||
#[interrupt]
|
|
||||||
unsafe fn UARTE1() {
|
|
||||||
interrupt::free(|cs| UARTE1::get_state(cs).as_mut().unwrap().on_interrupt());
|
|
||||||
}
|
|
||||||
|
|
||||||
static mut UARTE0_STATE: *mut UarteState<UARTE0> = ptr::null_mut();
|
static mut UARTE0_STATE: *mut UarteState<UARTE0> = ptr::null_mut();
|
||||||
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
|
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
|
||||||
static mut UARTE1_STATE: *mut UarteState<UARTE1> = ptr::null_mut();
|
static mut UARTE1_STATE: *mut UarteState<UARTE1> = ptr::null_mut();
|
||||||
|
|
||||||
impl Instance for UARTE0 {
|
impl Instance for UARTE0 {
|
||||||
fn interrupt() -> Interrupt {
|
type Interrupt = interrupt::UARTE0_UART0Interrupt;
|
||||||
Interrupt::UARTE0_UART0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> {
|
fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> {
|
||||||
unsafe { UARTE0_STATE } // Safe because of CriticalSection
|
unsafe { UARTE0_STATE } // Safe because of CriticalSection
|
||||||
@ -548,9 +546,7 @@ impl Instance for UARTE0 {
|
|||||||
|
|
||||||
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
|
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
|
||||||
impl Instance for UARTE1 {
|
impl Instance for UARTE1 {
|
||||||
fn interrupt() -> Interrupt {
|
type Interrupt = interrupt::UARTE1Interrupt;
|
||||||
Interrupt::UARTE1
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> {
|
fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> {
|
||||||
unsafe { UARTE1_STATE } // Safe because of CriticalSection
|
unsafe { UARTE1_STATE } // Safe because of CriticalSection
|
||||||
|
@ -7,6 +7,7 @@ use embassy::util::Signal;
|
|||||||
|
|
||||||
use crate::hal::gpio::{Input, Level, Output, Pin, Port};
|
use crate::hal::gpio::{Input, Level, Output, Pin, Port};
|
||||||
use crate::interrupt;
|
use crate::interrupt;
|
||||||
|
use crate::interrupt::OwnedInterrupt;
|
||||||
use crate::pac::generic::Reg;
|
use crate::pac::generic::Reg;
|
||||||
use crate::pac::gpiote::_TASKS_OUT;
|
use crate::pac::gpiote::_TASKS_OUT;
|
||||||
#[cfg(any(feature = "52833", feature = "52840"))]
|
#[cfg(any(feature = "52833", feature = "52840"))]
|
||||||
@ -58,7 +59,7 @@ pub enum NewChannelError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Gpiote {
|
impl Gpiote {
|
||||||
pub fn new(gpiote: GPIOTE) -> Self {
|
pub fn new(gpiote: GPIOTE, irq: interrupt::GPIOTEInterrupt) -> Self {
|
||||||
#[cfg(any(feature = "52833", feature = "52840"))]
|
#[cfg(any(feature = "52833", feature = "52840"))]
|
||||||
let ports = unsafe { &[&*P0::ptr(), &*P1::ptr()] };
|
let ports = unsafe { &[&*P0::ptr(), &*P1::ptr()] };
|
||||||
#[cfg(not(any(feature = "52833", feature = "52840")))]
|
#[cfg(not(any(feature = "52833", feature = "52840")))]
|
||||||
@ -74,8 +75,9 @@ impl Gpiote {
|
|||||||
// Enable interrupts
|
// Enable interrupts
|
||||||
gpiote.events_port.write(|w| w);
|
gpiote.events_port.write(|w| w);
|
||||||
gpiote.intenset.write(|w| w.port().set());
|
gpiote.intenset.write(|w| w.port().set());
|
||||||
interrupt::unpend(interrupt::GPIOTE);
|
irq.set_handler(Self::on_irq);
|
||||||
interrupt::enable(interrupt::GPIOTE);
|
irq.unpend();
|
||||||
|
irq.enable();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
inner: gpiote,
|
inner: gpiote,
|
||||||
@ -293,6 +295,39 @@ impl Gpiote {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe fn on_irq() {
|
||||||
|
let s = &(*INSTANCE);
|
||||||
|
|
||||||
|
for i in 0..8 {
|
||||||
|
if s.inner.events_in[i].read().bits() != 0 {
|
||||||
|
s.inner.events_in[i].write(|w| w);
|
||||||
|
s.channel_signals[i].signal(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.inner.events_port.read().bits() != 0 {
|
||||||
|
s.inner.events_port.write(|w| w);
|
||||||
|
|
||||||
|
#[cfg(any(feature = "52833", feature = "52840"))]
|
||||||
|
let ports = &[&*P0::ptr(), &*P1::ptr()];
|
||||||
|
#[cfg(not(any(feature = "52833", feature = "52840")))]
|
||||||
|
let ports = &[&*P0::ptr()];
|
||||||
|
|
||||||
|
let mut work = true;
|
||||||
|
while work {
|
||||||
|
work = false;
|
||||||
|
for (port, &p) in ports.iter().enumerate() {
|
||||||
|
for pin in BitIter(p.latch.read().bits()) {
|
||||||
|
work = true;
|
||||||
|
p.pin_cnf[pin as usize].modify(|_, w| w.sense().disabled());
|
||||||
|
p.latch.write(|w| w.bits(1 << pin));
|
||||||
|
s.port_signals[port * 32 + pin as usize].signal(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PortInputFuture<'a, T> {
|
pub struct PortInputFuture<'a, T> {
|
||||||
@ -413,40 +448,6 @@ impl<'a> OutputChannel<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[interrupt]
|
|
||||||
unsafe fn GPIOTE() {
|
|
||||||
let s = &(*INSTANCE);
|
|
||||||
|
|
||||||
for i in 0..8 {
|
|
||||||
if s.inner.events_in[i].read().bits() != 0 {
|
|
||||||
s.inner.events_in[i].write(|w| w);
|
|
||||||
s.channel_signals[i].signal(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.inner.events_port.read().bits() != 0 {
|
|
||||||
s.inner.events_port.write(|w| w);
|
|
||||||
|
|
||||||
#[cfg(any(feature = "52833", feature = "52840"))]
|
|
||||||
let ports = &[&*P0::ptr(), &*P1::ptr()];
|
|
||||||
#[cfg(not(any(feature = "52833", feature = "52840")))]
|
|
||||||
let ports = &[&*P0::ptr()];
|
|
||||||
|
|
||||||
let mut work = true;
|
|
||||||
while work {
|
|
||||||
work = false;
|
|
||||||
for (port, &p) in ports.iter().enumerate() {
|
|
||||||
for pin in BitIter(p.latch.read().bits()) {
|
|
||||||
work = true;
|
|
||||||
p.pin_cnf[pin as usize].modify(|_, w| w.sense().disabled());
|
|
||||||
p.latch.write(|w| w.bits(1 << pin));
|
|
||||||
s.port_signals[port * 32 + pin as usize].signal(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BitIter(u32);
|
struct BitIter(u32);
|
||||||
|
|
||||||
impl Iterator for BitIter {
|
impl Iterator for BitIter {
|
||||||
|
@ -51,8 +51,8 @@ pub use nrf52840_hal as hal;
|
|||||||
// This mod MUST go first, so that the others see its macros.
|
// This mod MUST go first, so that the others see its macros.
|
||||||
pub(crate) mod fmt;
|
pub(crate) mod fmt;
|
||||||
|
|
||||||
//pub mod buffered_uarte;
|
pub mod buffered_uarte;
|
||||||
//pub mod gpiote;
|
pub mod gpiote;
|
||||||
pub mod interrupt;
|
pub mod interrupt;
|
||||||
#[cfg(feature = "52840")]
|
#[cfg(feature = "52840")]
|
||||||
pub mod qspi;
|
pub mod qspi;
|
||||||
|
@ -7,18 +7,20 @@ mod example_common;
|
|||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
|
use defmt::panic;
|
||||||
use nrf52840_hal::gpio;
|
use nrf52840_hal::gpio;
|
||||||
|
|
||||||
use embassy::executor::{task, Executor};
|
use embassy::executor::{task, Executor};
|
||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_nrf::gpiote;
|
use embassy_nrf::gpiote;
|
||||||
|
use embassy_nrf::interrupt;
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
async fn run() {
|
async fn run() {
|
||||||
let p = unwrap!(embassy_nrf::pac::Peripherals::take());
|
let p = unwrap!(embassy_nrf::pac::Peripherals::take());
|
||||||
let port0 = gpio::p0::Parts::new(p.P0);
|
let port0 = gpio::p0::Parts::new(p.P0);
|
||||||
|
|
||||||
let g = gpiote::Gpiote::new(p.GPIOTE);
|
let g = gpiote::Gpiote::new(p.GPIOTE, interrupt::take!(GPIOTE));
|
||||||
|
|
||||||
info!("Starting!");
|
info!("Starting!");
|
||||||
|
|
||||||
|
@ -8,11 +8,13 @@ use example_common::*;
|
|||||||
|
|
||||||
use core::mem;
|
use core::mem;
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
|
use defmt::panic;
|
||||||
use nrf52840_hal::gpio;
|
use nrf52840_hal::gpio;
|
||||||
|
|
||||||
use embassy::executor::{task, Executor};
|
use embassy::executor::{task, Executor};
|
||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_nrf::gpiote::{Gpiote, PortInputPolarity};
|
use embassy_nrf::gpiote::{Gpiote, PortInputPolarity};
|
||||||
|
use embassy_nrf::interrupt;
|
||||||
|
|
||||||
async fn button(g: &Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) {
|
async fn button(g: &Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) {
|
||||||
loop {
|
loop {
|
||||||
@ -28,7 +30,7 @@ async fn run() {
|
|||||||
let p = unwrap!(embassy_nrf::pac::Peripherals::take());
|
let p = unwrap!(embassy_nrf::pac::Peripherals::take());
|
||||||
let port0 = gpio::p0::Parts::new(p.P0);
|
let port0 = gpio::p0::Parts::new(p.P0);
|
||||||
|
|
||||||
let g = Gpiote::new(p.GPIOTE);
|
let g = Gpiote::new(p.GPIOTE, interrupt::take!(GPIOTE));
|
||||||
info!(
|
info!(
|
||||||
"sizeof Signal<()> = {:usize}",
|
"sizeof Signal<()> = {:usize}",
|
||||||
mem::size_of::<embassy::util::Signal<()>>()
|
mem::size_of::<embassy::util::Signal<()>>()
|
||||||
|
@ -7,6 +7,7 @@ mod example_common;
|
|||||||
use example_common::*;
|
use example_common::*;
|
||||||
|
|
||||||
use cortex_m_rt::entry;
|
use cortex_m_rt::entry;
|
||||||
|
use defmt::panic;
|
||||||
use futures::pin_mut;
|
use futures::pin_mut;
|
||||||
use nrf52840_hal::gpio;
|
use nrf52840_hal::gpio;
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ use embassy::executor::{task, Executor};
|
|||||||
use embassy::io::{AsyncBufRead, AsyncBufReadExt, AsyncWrite, AsyncWriteExt};
|
use embassy::io::{AsyncBufRead, AsyncBufReadExt, AsyncWrite, AsyncWriteExt};
|
||||||
use embassy::util::Forever;
|
use embassy::util::Forever;
|
||||||
use embassy_nrf::buffered_uarte;
|
use embassy_nrf::buffered_uarte;
|
||||||
|
use embassy_nrf::interrupt;
|
||||||
|
|
||||||
#[task]
|
#[task]
|
||||||
async fn run() {
|
async fn run() {
|
||||||
@ -31,8 +33,10 @@ async fn run() {
|
|||||||
rts: None,
|
rts: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let irq = interrupt::take!(UARTE0_UART0);
|
||||||
let u = buffered_uarte::BufferedUarte::new(
|
let u = buffered_uarte::BufferedUarte::new(
|
||||||
p.UARTE0,
|
p.UARTE0,
|
||||||
|
irq,
|
||||||
pins,
|
pins,
|
||||||
buffered_uarte::Parity::EXCLUDED,
|
buffered_uarte::Parity::EXCLUDED,
|
||||||
buffered_uarte::Baudrate::BAUD115200,
|
buffered_uarte::Baudrate::BAUD115200,
|
||||||
|
Loading…
Reference in New Issue
Block a user