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::interrupt;
use crate::interrupt::CriticalSection;
use crate::interrupt::{CriticalSection, OwnedInterrupt};
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
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
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
// should not be used outside the module
#[doc(hidden)]
pub struct UarteState<T> {
pub struct UarteState<T: Instance> {
inner: T,
irq: T::Interrupt,
rx: RingBuf,
rx_state: RxState,
@ -164,7 +165,13 @@ fn port_bit(port: GpioPort) -> bool {
}
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
uarte.psel.rxd.write(|w| {
let w = unsafe { w.pin().bits(pins.rxd.pin()) };
@ -222,6 +229,7 @@ impl<T: Instance> BufferedUarte<T> {
started: false,
state: UnsafeCell::new(UarteState {
inner: uarte,
irq,
rx: RingBuf::new(),
rx_state: RxState::Idle,
@ -287,9 +295,12 @@ impl<T: Instance> AsyncWrite for BufferedUarte<T> {
impl<T: Instance> UarteState<T> {
pub fn start(self: Pin<&mut Self>) {
interrupt::set_priority(T::interrupt(), interrupt::Priority::Level7);
interrupt::enable(T::interrupt());
interrupt::pend(T::interrupt());
self.irq.set_handler(|| unsafe {
interrupt::free(|cs| T::get_state(cs).as_mut().unwrap().on_interrupt());
});
self.irq.pend();
self.irq.enable();
}
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() };
trace!("consume {:?}", 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>> {
@ -350,7 +361,7 @@ impl<T: Instance> UarteState<T> {
// before any DMA action has started
compiler_fence(Ordering::SeqCst);
interrupt::pend(T::interrupt());
this.irq.pend();
Poll::Ready(Ok(n))
}
@ -509,7 +520,7 @@ mod private {
}
pub trait Instance: Deref<Target = uarte0::RegisterBlock> + Sized + private::Sealed {
fn interrupt() -> Interrupt;
type Interrupt: OwnedInterrupt;
#[doc(hidden)]
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>);
}
#[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();
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
static mut UARTE1_STATE: *mut UarteState<UARTE1> = ptr::null_mut();
impl Instance for UARTE0 {
fn interrupt() -> Interrupt {
Interrupt::UARTE0_UART0
}
type Interrupt = interrupt::UARTE0_UART0Interrupt;
fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> {
unsafe { UARTE0_STATE } // Safe because of CriticalSection
@ -548,9 +546,7 @@ impl Instance for UARTE0 {
#[cfg(any(feature = "52833", feature = "52840", feature = "9160"))]
impl Instance for UARTE1 {
fn interrupt() -> Interrupt {
Interrupt::UARTE1
}
type Interrupt = interrupt::UARTE1Interrupt;
fn get_state(_cs: &CriticalSection) -> *mut UarteState<Self> {
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::interrupt;
use crate::interrupt::OwnedInterrupt;
use crate::pac::generic::Reg;
use crate::pac::gpiote::_TASKS_OUT;
#[cfg(any(feature = "52833", feature = "52840"))]
@ -58,7 +59,7 @@ pub enum NewChannelError {
}
impl Gpiote {
pub fn new(gpiote: GPIOTE) -> Self {
pub fn new(gpiote: GPIOTE, irq: interrupt::GPIOTEInterrupt) -> Self {
#[cfg(any(feature = "52833", feature = "52840"))]
let ports = unsafe { &[&*P0::ptr(), &*P1::ptr()] };
#[cfg(not(any(feature = "52833", feature = "52840")))]
@ -74,8 +75,9 @@ impl Gpiote {
// Enable interrupts
gpiote.events_port.write(|w| w);
gpiote.intenset.write(|w| w.port().set());
interrupt::unpend(interrupt::GPIOTE);
interrupt::enable(interrupt::GPIOTE);
irq.set_handler(Self::on_irq);
irq.unpend();
irq.enable();
Self {
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> {
@ -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);
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.
pub(crate) mod fmt;
//pub mod buffered_uarte;
//pub mod gpiote;
pub mod buffered_uarte;
pub mod gpiote;
pub mod interrupt;
#[cfg(feature = "52840")]
pub mod qspi;

View file

@ -7,18 +7,20 @@ mod example_common;
use example_common::*;
use cortex_m_rt::entry;
use defmt::panic;
use nrf52840_hal::gpio;
use embassy::executor::{task, Executor};
use embassy::util::Forever;
use embassy_nrf::gpiote;
use embassy_nrf::interrupt;
#[task]
async fn run() {
let p = unwrap!(embassy_nrf::pac::Peripherals::take());
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!");

View file

@ -8,11 +8,13 @@ use example_common::*;
use core::mem;
use cortex_m_rt::entry;
use defmt::panic;
use nrf52840_hal::gpio;
use embassy::executor::{task, Executor};
use embassy::util::Forever;
use embassy_nrf::gpiote::{Gpiote, PortInputPolarity};
use embassy_nrf::interrupt;
async fn button(g: &Gpiote, n: usize, pin: gpio::Pin<gpio::Input<gpio::PullUp>>) {
loop {
@ -28,7 +30,7 @@ async fn run() {
let p = unwrap!(embassy_nrf::pac::Peripherals::take());
let port0 = gpio::p0::Parts::new(p.P0);
let g = Gpiote::new(p.GPIOTE);
let g = Gpiote::new(p.GPIOTE, interrupt::take!(GPIOTE));
info!(
"sizeof Signal<()> = {:usize}",
mem::size_of::<embassy::util::Signal<()>>()

View file

@ -7,6 +7,7 @@ mod example_common;
use example_common::*;
use cortex_m_rt::entry;
use defmt::panic;
use futures::pin_mut;
use nrf52840_hal::gpio;
@ -14,6 +15,7 @@ use embassy::executor::{task, Executor};
use embassy::io::{AsyncBufRead, AsyncBufReadExt, AsyncWrite, AsyncWriteExt};
use embassy::util::Forever;
use embassy_nrf::buffered_uarte;
use embassy_nrf::interrupt;
#[task]
async fn run() {
@ -31,8 +33,10 @@ async fn run() {
rts: None,
};
let irq = interrupt::take!(UARTE0_UART0);
let u = buffered_uarte::BufferedUarte::new(
p.UARTE0,
irq,
pins,
buffered_uarte::Parity::EXCLUDED,
buffered_uarte::Baudrate::BAUD115200,