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::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
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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!");
|
||||
|
||||
|
@ -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<()>>()
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user