nrf/twim: switch to new interrupt binding.
This commit is contained in:
parent
9f5762d365
commit
9e58d9274c
3 changed files with 39 additions and 26 deletions
|
@ -3,6 +3,7 @@
|
||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
use core::future::{poll_fn, Future};
|
use core::future::{poll_fn, Future};
|
||||||
|
use core::marker::PhantomData;
|
||||||
use core::sync::atomic::compiler_fence;
|
use core::sync::atomic::compiler_fence;
|
||||||
use core::sync::atomic::Ordering::SeqCst;
|
use core::sync::atomic::Ordering::SeqCst;
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
@ -15,7 +16,7 @@ use embassy_time::{Duration, Instant};
|
||||||
|
|
||||||
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
|
use crate::chip::{EASY_DMA_SIZE, FORCE_COPY_BUFFER_SIZE};
|
||||||
use crate::gpio::Pin as GpioPin;
|
use crate::gpio::Pin as GpioPin;
|
||||||
use crate::interrupt::{Interrupt, InterruptExt};
|
use crate::interrupt::{self, Interrupt, InterruptExt};
|
||||||
use crate::util::{slice_in_ram, slice_in_ram_or};
|
use crate::util::{slice_in_ram, slice_in_ram_or};
|
||||||
use crate::{gpio, pac, Peripheral};
|
use crate::{gpio, pac, Peripheral};
|
||||||
|
|
||||||
|
@ -92,6 +93,27 @@ pub enum Error {
|
||||||
Timeout,
|
Timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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_stopped.read().bits() != 0 {
|
||||||
|
s.end_waker.wake();
|
||||||
|
r.intenclr.write(|w| w.stopped().clear());
|
||||||
|
}
|
||||||
|
if r.events_error.read().bits() != 0 {
|
||||||
|
s.end_waker.wake();
|
||||||
|
r.intenclr.write(|w| w.error().clear());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// TWI driver.
|
/// TWI driver.
|
||||||
pub struct Twim<'d, T: Instance> {
|
pub struct Twim<'d, T: Instance> {
|
||||||
_p: PeripheralRef<'d, T>,
|
_p: PeripheralRef<'d, T>,
|
||||||
|
@ -101,12 +123,12 @@ impl<'d, T: Instance> Twim<'d, T> {
|
||||||
/// Create a new TWI driver.
|
/// Create a new TWI driver.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
twim: impl Peripheral<P = T> + 'd,
|
twim: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
sda: impl Peripheral<P = impl GpioPin> + 'd,
|
sda: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
scl: impl Peripheral<P = impl GpioPin> + 'd,
|
scl: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(twim, irq, sda, scl);
|
into_ref!(twim, sda, scl);
|
||||||
|
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
|
@ -152,27 +174,12 @@ impl<'d, T: Instance> Twim<'d, T> {
|
||||||
// Disable all events interrupts
|
// Disable all events interrupts
|
||||||
r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) });
|
r.intenclr.write(|w| unsafe { w.bits(0xFFFF_FFFF) });
|
||||||
|
|
||||||
irq.set_handler(Self::on_interrupt);
|
unsafe { T::Interrupt::steal() }.unpend();
|
||||||
irq.unpend();
|
unsafe { T::Interrupt::steal() }.enable();
|
||||||
irq.enable();
|
|
||||||
|
|
||||||
Self { _p: twim }
|
Self { _p: twim }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_interrupt(_: *mut ()) {
|
|
||||||
let r = T::regs();
|
|
||||||
let s = T::state();
|
|
||||||
|
|
||||||
if r.events_stopped.read().bits() != 0 {
|
|
||||||
s.end_waker.wake();
|
|
||||||
r.intenclr.write(|w| w.stopped().clear());
|
|
||||||
}
|
|
||||||
if r.events_error.read().bits() != 0 {
|
|
||||||
s.end_waker.wake();
|
|
||||||
r.intenclr.write(|w| w.error().clear());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set TX buffer, checking that it is in RAM and has suitable length.
|
/// Set TX buffer, checking that it is in RAM and has suitable length.
|
||||||
unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
unsafe fn set_tx_buffer(&mut self, buffer: &[u8]) -> Result<(), Error> {
|
||||||
slice_in_ram_or(buffer, Error::BufferNotInRAM)?;
|
slice_in_ram_or(buffer, Error::BufferNotInRAM)?;
|
||||||
|
|
|
@ -8,19 +8,22 @@
|
||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::interrupt;
|
|
||||||
use embassy_nrf::twim::{self, Twim};
|
use embassy_nrf::twim::{self, Twim};
|
||||||
|
use embassy_nrf::{bind_interrupts, peripherals};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
const ADDRESS: u8 = 0x50;
|
const ADDRESS: u8 = 0x50;
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler<peripherals::TWISPI0>;
|
||||||
|
});
|
||||||
|
|
||||||
#[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());
|
||||||
info!("Initializing TWI...");
|
info!("Initializing TWI...");
|
||||||
let config = twim::Config::default();
|
let config = twim::Config::default();
|
||||||
let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
|
let mut twi = Twim::new(p.TWISPI0, Irqs, p.P0_03, p.P0_04, config);
|
||||||
let mut twi = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
|
|
||||||
|
|
||||||
info!("Reading...");
|
info!("Reading...");
|
||||||
|
|
||||||
|
|
|
@ -12,25 +12,28 @@ use core::mem;
|
||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::interrupt;
|
|
||||||
use embassy_nrf::twim::{self, Twim};
|
use embassy_nrf::twim::{self, Twim};
|
||||||
|
use embassy_nrf::{bind_interrupts, peripherals};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
const ADDRESS: u8 = 0x50;
|
const ADDRESS: u8 = 0x50;
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0 => twim::InterruptHandler<peripherals::TWISPI0>;
|
||||||
|
});
|
||||||
|
|
||||||
#[embassy_executor::main]
|
#[embassy_executor::main]
|
||||||
async fn main(_p: Spawner) {
|
async fn main(_p: Spawner) {
|
||||||
let mut p = embassy_nrf::init(Default::default());
|
let mut p = embassy_nrf::init(Default::default());
|
||||||
info!("Started!");
|
info!("Started!");
|
||||||
let mut irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
info!("Initializing TWI...");
|
info!("Initializing TWI...");
|
||||||
let config = twim::Config::default();
|
let config = twim::Config::default();
|
||||||
|
|
||||||
// Create the TWIM instance with borrowed singletons, so they're not consumed.
|
// Create the TWIM instance with borrowed singletons, so they're not consumed.
|
||||||
let mut twi = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config);
|
let mut twi = Twim::new(&mut p.TWISPI0, Irqs, &mut p.P0_03, &mut p.P0_04, config);
|
||||||
|
|
||||||
info!("Reading...");
|
info!("Reading...");
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue