nrf/spim: switch to new interrupt binding.
This commit is contained in:
parent
2dc5608203
commit
a32e82029a
@ -3,6 +3,7 @@
|
|||||||
#![macro_use]
|
#![macro_use]
|
||||||
|
|
||||||
use core::future::poll_fn;
|
use core::future::poll_fn;
|
||||||
|
use core::marker::PhantomData;
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ pub use pac::spim0::frequency::FREQUENCY_A as Frequency;
|
|||||||
use crate::chip::FORCE_COPY_BUFFER_SIZE;
|
use crate::chip::FORCE_COPY_BUFFER_SIZE;
|
||||||
use crate::gpio::sealed::Pin as _;
|
use crate::gpio::sealed::Pin as _;
|
||||||
use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
|
use crate::gpio::{self, AnyPin, Pin as GpioPin, PselBits};
|
||||||
use crate::interrupt::{Interrupt, InterruptExt};
|
use crate::interrupt::{self, Interrupt, InterruptExt};
|
||||||
use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut};
|
use crate::util::{slice_in_ram_or, slice_ptr_parts, slice_ptr_parts_mut};
|
||||||
use crate::{pac, Peripheral};
|
use crate::{pac, Peripheral};
|
||||||
|
|
||||||
@ -31,11 +32,6 @@ pub enum Error {
|
|||||||
BufferNotInRAM,
|
BufferNotInRAM,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SPIM driver.
|
|
||||||
pub struct Spim<'d, T: Instance> {
|
|
||||||
_p: PeripheralRef<'d, T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// SPIM configuration.
|
/// SPIM configuration.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
@ -62,11 +58,33 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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_end.read().bits() != 0 {
|
||||||
|
s.end_waker.wake();
|
||||||
|
r.intenclr.write(|w| w.end().clear());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// SPIM driver.
|
||||||
|
pub struct Spim<'d, T: Instance> {
|
||||||
|
_p: PeripheralRef<'d, T>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Spim<'d, T> {
|
impl<'d, T: Instance> Spim<'d, T> {
|
||||||
/// Create a new SPIM driver.
|
/// Create a new SPIM driver.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
spim: impl Peripheral<P = T> + 'd,
|
spim: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
miso: impl Peripheral<P = impl GpioPin> + 'd,
|
miso: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
mosi: impl Peripheral<P = impl GpioPin> + 'd,
|
mosi: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
@ -75,7 +93,6 @@ impl<'d, T: Instance> Spim<'d, T> {
|
|||||||
into_ref!(sck, miso, mosi);
|
into_ref!(sck, miso, mosi);
|
||||||
Self::new_inner(
|
Self::new_inner(
|
||||||
spim,
|
spim,
|
||||||
irq,
|
|
||||||
sck.map_into(),
|
sck.map_into(),
|
||||||
Some(miso.map_into()),
|
Some(miso.map_into()),
|
||||||
Some(mosi.map_into()),
|
Some(mosi.map_into()),
|
||||||
@ -86,36 +103,35 @@ impl<'d, T: Instance> Spim<'d, T> {
|
|||||||
/// Create a new SPIM driver, capable of TX only (MOSI only).
|
/// Create a new SPIM driver, capable of TX only (MOSI only).
|
||||||
pub fn new_txonly(
|
pub fn new_txonly(
|
||||||
spim: impl Peripheral<P = T> + 'd,
|
spim: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
mosi: impl Peripheral<P = impl GpioPin> + 'd,
|
mosi: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(sck, mosi);
|
into_ref!(sck, mosi);
|
||||||
Self::new_inner(spim, irq, sck.map_into(), None, Some(mosi.map_into()), config)
|
Self::new_inner(spim, sck.map_into(), None, Some(mosi.map_into()), config)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new SPIM driver, capable of RX only (MISO only).
|
/// Create a new SPIM driver, capable of RX only (MISO only).
|
||||||
pub fn new_rxonly(
|
pub fn new_rxonly(
|
||||||
spim: impl Peripheral<P = T> + 'd,
|
spim: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
_irq: impl interrupt::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||||
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
sck: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
miso: impl Peripheral<P = impl GpioPin> + 'd,
|
miso: impl Peripheral<P = impl GpioPin> + 'd,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(sck, miso);
|
into_ref!(sck, miso);
|
||||||
Self::new_inner(spim, irq, sck.map_into(), Some(miso.map_into()), None, config)
|
Self::new_inner(spim, sck.map_into(), Some(miso.map_into()), None, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_inner(
|
fn new_inner(
|
||||||
spim: impl Peripheral<P = T> + 'd,
|
spim: impl Peripheral<P = T> + 'd,
|
||||||
irq: impl Peripheral<P = T::Interrupt> + 'd,
|
|
||||||
sck: PeripheralRef<'d, AnyPin>,
|
sck: PeripheralRef<'d, AnyPin>,
|
||||||
miso: Option<PeripheralRef<'d, AnyPin>>,
|
miso: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
mosi: Option<PeripheralRef<'d, AnyPin>>,
|
mosi: Option<PeripheralRef<'d, AnyPin>>,
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
into_ref!(spim, irq);
|
into_ref!(spim);
|
||||||
|
|
||||||
let r = T::regs();
|
let r = T::regs();
|
||||||
|
|
||||||
@ -191,23 +207,12 @@ impl<'d, T: Instance> Spim<'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: spim }
|
Self { _p: spim }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_interrupt(_: *mut ()) {
|
|
||||||
let r = T::regs();
|
|
||||||
let s = T::state();
|
|
||||||
|
|
||||||
if r.events_end.read().bits() != 0 {
|
|
||||||
s.end_waker.wake();
|
|
||||||
r.intenclr.write(|w| w.end().clear());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prepare(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
|
fn prepare(&mut self, rx: *mut [u8], tx: *const [u8]) -> Result<(), Error> {
|
||||||
slice_in_ram_or(tx, Error::BufferNotInRAM)?;
|
slice_in_ram_or(tx, Error::BufferNotInRAM)?;
|
||||||
// NOTE: RAM slice check for rx is not necessary, as a mutable
|
// NOTE: RAM slice check for rx is not necessary, as a mutable
|
||||||
|
@ -11,11 +11,15 @@ use defmt::*;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_lora::sx126x::*;
|
use embassy_lora::sx126x::*;
|
||||||
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull};
|
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull};
|
||||||
use embassy_nrf::{interrupt, spim};
|
use embassy_nrf::{bind_interrupts, peripherals, spim};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor};
|
use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 => spim::InterruptHandler<peripherals::TWISPI1>;
|
||||||
|
});
|
||||||
|
|
||||||
#[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());
|
||||||
@ -23,8 +27,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
spi_config.frequency = spim::Frequency::M16;
|
spi_config.frequency = spim::Frequency::M16;
|
||||||
|
|
||||||
let mut radio = {
|
let mut radio = {
|
||||||
let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
|
let spim = spim::Spim::new(p.TWISPI1, Irqs, p.P1_11, p.P1_13, p.P1_12, spi_config);
|
||||||
let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config);
|
|
||||||
|
|
||||||
let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
|
let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
|
||||||
let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
|
let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
|
||||||
|
@ -12,13 +12,17 @@ use defmt::*;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_lora::sx126x::*;
|
use embassy_lora::sx126x::*;
|
||||||
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull};
|
use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pin as _, Pull};
|
||||||
use embassy_nrf::{interrupt, spim};
|
use embassy_nrf::{bind_interrupts, peripherals, spim};
|
||||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||||
use embassy_sync::pubsub::{PubSubChannel, Publisher};
|
use embassy_sync::pubsub::{PubSubChannel, Publisher};
|
||||||
use embassy_time::{Duration, Timer};
|
use embassy_time::{Duration, Timer};
|
||||||
use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig};
|
use lorawan_device::async_device::radio::{Bandwidth, CodingRate, PhyRxTx, RfConfig, SpreadingFactor, TxConfig};
|
||||||
use {defmt_rtt as _, panic_probe as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1 => spim::InterruptHandler<peripherals::TWISPI1>;
|
||||||
|
});
|
||||||
|
|
||||||
// Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection)
|
// Message bus: queue of 2, 1 subscriber (Lora P2P), 2 publishers (temperature, motion detection)
|
||||||
static MESSAGE_BUS: PubSubChannel<CriticalSectionRawMutex, Message, 2, 1, 2> = PubSubChannel::new();
|
static MESSAGE_BUS: PubSubChannel<CriticalSectionRawMutex, Message, 2, 1, 2> = PubSubChannel::new();
|
||||||
|
|
||||||
@ -58,8 +62,7 @@ async fn main(spawner: Spawner) {
|
|||||||
spi_config.frequency = spim::Frequency::M16;
|
spi_config.frequency = spim::Frequency::M16;
|
||||||
|
|
||||||
let mut radio = {
|
let mut radio = {
|
||||||
let irq = interrupt::take!(SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1);
|
let spim = spim::Spim::new(p.TWISPI1, Irqs, p.P1_11, p.P1_13, p.P1_12, spi_config);
|
||||||
let spim = spim::Spim::new(p.TWISPI1, irq, p.P1_11, p.P1_13, p.P1_12, spi_config);
|
|
||||||
|
|
||||||
let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
|
let cs = Output::new(p.P1_10.degrade(), Level::High, OutputDrive::Standard);
|
||||||
let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
|
let reset = Output::new(p.P1_06.degrade(), Level::High, OutputDrive::Standard);
|
||||||
|
@ -5,9 +5,13 @@
|
|||||||
use defmt::{info, unwrap};
|
use defmt::{info, unwrap};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
use embassy_nrf::gpio::{Level, Output, OutputDrive};
|
||||||
use embassy_nrf::{interrupt, spim};
|
use embassy_nrf::{bind_interrupts, peripherals, spim};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
SPIM3 => spim::InterruptHandler<peripherals::SPI3>;
|
||||||
|
});
|
||||||
|
|
||||||
#[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());
|
||||||
@ -16,8 +20,7 @@ async fn main(_spawner: Spawner) {
|
|||||||
let mut config = spim::Config::default();
|
let mut config = spim::Config::default();
|
||||||
config.frequency = spim::Frequency::M16;
|
config.frequency = spim::Frequency::M16;
|
||||||
|
|
||||||
let irq = interrupt::take!(SPIM3);
|
let mut spim = spim::Spim::new(p.SPI3, Irqs, p.P0_29, p.P0_28, p.P0_30, config);
|
||||||
let mut spim = spim::Spim::new(p.SPI3, irq, p.P0_29, p.P0_28, p.P0_30, config);
|
|
||||||
|
|
||||||
let mut ncs = Output::new(p.P0_31, Level::High, OutputDrive::Standard);
|
let mut ncs = Output::new(p.P0_31, Level::High, OutputDrive::Standard);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user