Update drivers to owned irqs.

This commit is contained in:
Dario Nieuwenhuis 2020-12-29 01:53:17 +01:00
parent 4b8d8ba87e
commit af5454fbfe
6 changed files with 73 additions and 68 deletions

View file

@ -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

View file

@ -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 {

View file

@ -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;

View file

@ -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!");

View file

@ -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<()>>()

View file

@ -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,