mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-26 20:00:27 +00:00
Merge pull request #4685 from Abrahamh08/main
feat(nrf/spim): erase Instance type from Spim
This commit is contained in:
commit
9158bfde62
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
<!-- next-header -->
|
||||
## Unreleased - ReleaseDate
|
||||
|
||||
- changed: erase Instance type from Spim
|
||||
- changed: nrf54l: Disable glitch detection and enable DC/DC in init.
|
||||
- changed: Add embassy-net-driver-channel implementation for IEEE 802.15.4
|
||||
- changed: add persist() method for gpio and ppi
|
||||
|
@ -99,13 +99,16 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl
|
||||
}
|
||||
|
||||
/// SPIM driver.
|
||||
pub struct Spim<'d, T: Instance> {
|
||||
_p: Peri<'d, T>,
|
||||
pub struct Spim<'d> {
|
||||
r: pac::spim::Spim,
|
||||
irq: interrupt::Interrupt,
|
||||
state: &'static State,
|
||||
_p: PhantomData<&'d ()>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Spim<'d, T> {
|
||||
impl<'d> Spim<'d> {
|
||||
/// Create a new SPIM driver.
|
||||
pub fn new(
|
||||
pub fn new<T: Instance>(
|
||||
spim: Peri<'d, T>,
|
||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||
sck: Peri<'d, impl GpioPin>,
|
||||
@ -117,7 +120,7 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
}
|
||||
|
||||
/// Create a new SPIM driver, capable of TX only (MOSI only).
|
||||
pub fn new_txonly(
|
||||
pub fn new_txonly<T: Instance>(
|
||||
spim: Peri<'d, T>,
|
||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||
sck: Peri<'d, impl GpioPin>,
|
||||
@ -128,7 +131,7 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
}
|
||||
|
||||
/// Create a new SPIM driver, capable of RX only (MISO only).
|
||||
pub fn new_rxonly(
|
||||
pub fn new_rxonly<T: Instance>(
|
||||
spim: Peri<'d, T>,
|
||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||
sck: Peri<'d, impl GpioPin>,
|
||||
@ -139,7 +142,7 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
}
|
||||
|
||||
/// Create a new SPIM driver, capable of TX only (MOSI only), without SCK pin.
|
||||
pub fn new_txonly_nosck(
|
||||
pub fn new_txonly_nosck<T: Instance>(
|
||||
spim: Peri<'d, T>,
|
||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||
mosi: Peri<'d, impl GpioPin>,
|
||||
@ -148,8 +151,8 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
Self::new_inner(spim, None, None, Some(mosi.into()), config)
|
||||
}
|
||||
|
||||
fn new_inner(
|
||||
spim: Peri<'d, T>,
|
||||
fn new_inner<T: Instance>(
|
||||
_spim: Peri<'d, T>,
|
||||
sck: Option<Peri<'d, AnyPin>>,
|
||||
miso: Option<Peri<'d, AnyPin>>,
|
||||
mosi: Option<Peri<'d, AnyPin>>,
|
||||
@ -201,7 +204,12 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
// Enable SPIM instance.
|
||||
r.enable().write(|w| w.set_enable(vals::Enable::ENABLED));
|
||||
|
||||
let mut spim = Self { _p: spim };
|
||||
let mut spim = Self {
|
||||
r: T::regs(),
|
||||
irq: T::Interrupt::IRQ,
|
||||
state: T::state(),
|
||||
_p: PhantomData {},
|
||||
};
|
||||
|
||||
// Apply runtime peripheral configuration
|
||||
Self::set_config(&mut spim, &config).unwrap();
|
||||
@ -218,7 +226,7 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
fn prepare_dma_transfer(&mut self, rx: *mut [u8], tx: *const [u8], offset: usize, length: usize) {
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
|
||||
let r = T::regs();
|
||||
let r = self.r;
|
||||
|
||||
fn xfer_params(ptr: u32, total: usize, offset: usize, length: usize) -> (u32, usize) {
|
||||
if total > offset {
|
||||
@ -246,7 +254,7 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
|
||||
#[cfg(feature = "_nrf52832_anomaly_109")]
|
||||
if offset == 0 {
|
||||
let s = T::state();
|
||||
let s = self.state;
|
||||
|
||||
r.events_started().write_value(0);
|
||||
|
||||
@ -279,7 +287,7 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
}
|
||||
|
||||
// Wait for 'end' event.
|
||||
while T::regs().events_end().read() == 0 {}
|
||||
while self.r.events_end().read() == 0 {}
|
||||
|
||||
compiler_fence(Ordering::SeqCst);
|
||||
}
|
||||
@ -315,7 +323,7 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
#[cfg(feature = "_nrf52832_anomaly_109")]
|
||||
if offset == 0 {
|
||||
poll_fn(|cx| {
|
||||
let s = T::state();
|
||||
let s = self.state;
|
||||
|
||||
s.waker.register(cx.waker());
|
||||
|
||||
@ -326,8 +334,8 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
|
||||
// Wait for 'end' event.
|
||||
poll_fn(|cx| {
|
||||
T::state().waker.register(cx.waker());
|
||||
if T::regs().events_end().read() != 0 {
|
||||
self.state.waker.register(cx.waker());
|
||||
if self.r.events_end().read() != 0 {
|
||||
return Poll::Ready(());
|
||||
}
|
||||
|
||||
@ -430,9 +438,9 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
|
||||
#[cfg(feature = "_nrf52832_anomaly_109")]
|
||||
fn nrf52832_dma_workaround_status(&mut self) -> Poll<()> {
|
||||
let r = T::regs();
|
||||
let r = self.r;
|
||||
if r.events_started().read() != 0 {
|
||||
let s = T::state();
|
||||
let s = self.state;
|
||||
|
||||
// Handle the first "fake" transmission
|
||||
r.events_started().write_value(0);
|
||||
@ -451,14 +459,14 @@ impl<'d, T: Instance> Spim<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Drop for Spim<'d, T> {
|
||||
impl<'d> Drop for Spim<'d> {
|
||||
fn drop(&mut self) {
|
||||
trace!("spim drop");
|
||||
|
||||
// TODO check for abort, wait for xxxstopped
|
||||
|
||||
// disable!
|
||||
let r = T::regs();
|
||||
let r = self.r;
|
||||
r.enable().write(|w| w.set_enable(vals::Enable::DISABLED));
|
||||
|
||||
gpio::deconfigure_pin(r.psel().sck().read());
|
||||
@ -466,7 +474,7 @@ impl<'d, T: Instance> Drop for Spim<'d, T> {
|
||||
gpio::deconfigure_pin(r.psel().mosi().read());
|
||||
|
||||
// Disable all events interrupts
|
||||
T::Interrupt::disable();
|
||||
cortex_m::peripheral::NVIC::mask(self.irq);
|
||||
|
||||
trace!("spim drop: done");
|
||||
}
|
||||
@ -526,7 +534,7 @@ macro_rules! impl_spim {
|
||||
mod eh02 {
|
||||
use super::*;
|
||||
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::spi::Transfer<u8> for Spim<'d, T> {
|
||||
impl<'d> embedded_hal_02::blocking::spi::Transfer<u8> for Spim<'d> {
|
||||
type Error = Error;
|
||||
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
|
||||
self.blocking_transfer_in_place(words)?;
|
||||
@ -534,7 +542,7 @@ mod eh02 {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal_02::blocking::spi::Write<u8> for Spim<'d, T> {
|
||||
impl<'d> embedded_hal_02::blocking::spi::Write<u8> for Spim<'d> {
|
||||
type Error = Error;
|
||||
|
||||
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
|
||||
@ -551,11 +559,11 @@ impl embedded_hal_1::spi::Error for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal_1::spi::ErrorType for Spim<'d, T> {
|
||||
impl<'d> embedded_hal_1::spi::ErrorType for Spim<'d> {
|
||||
type Error = Error;
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal_1::spi::SpiBus<u8> for Spim<'d, T> {
|
||||
impl<'d> embedded_hal_1::spi::SpiBus<u8> for Spim<'d> {
|
||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(())
|
||||
}
|
||||
@ -577,7 +585,7 @@ impl<'d, T: Instance> embedded_hal_1::spi::SpiBus<u8> for Spim<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> {
|
||||
impl<'d> embedded_hal_async::spi::SpiBus<u8> for Spim<'d> {
|
||||
async fn flush(&mut self) -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
@ -599,11 +607,11 @@ impl<'d, T: Instance> embedded_hal_async::spi::SpiBus<u8> for Spim<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> SetConfig for Spim<'d, T> {
|
||||
impl<'d> SetConfig for Spim<'d> {
|
||||
type Config = Config;
|
||||
type ConfigError = ();
|
||||
fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError> {
|
||||
let r = T::regs();
|
||||
let r = self.r;
|
||||
// Configure mode.
|
||||
let mode = config.mode;
|
||||
r.config().write(|w| {
|
||||
|
@ -25,7 +25,7 @@ bind_interrupts!(struct Irqs {
|
||||
async fn net_task(
|
||||
mut runner: embassy_net::Runner<
|
||||
'static,
|
||||
Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>,
|
||||
Enc28j60<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Output<'static>>,
|
||||
>,
|
||||
) -> ! {
|
||||
runner.run().await
|
||||
|
@ -27,7 +27,7 @@ bind_interrupts!(struct Irqs {
|
||||
async fn wifi_task(
|
||||
runner: hosted::Runner<
|
||||
'static,
|
||||
ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>,
|
||||
ExclusiveDevice<Spim<'static>, Output<'static>, Delay>,
|
||||
Input<'static>,
|
||||
Output<'static>,
|
||||
>,
|
||||
|
@ -22,7 +22,7 @@ bind_interrupts!(struct Irqs {
|
||||
RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>;
|
||||
});
|
||||
|
||||
type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>, Output<'static>>;
|
||||
type MyDriver = Enc28j60<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Output<'static>>;
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn net_task(mut runner: embassy_net::Runner<'static, MyDriver>) -> ! {
|
||||
|
@ -29,7 +29,7 @@ const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
|
||||
async fn wifi_task(
|
||||
runner: hosted::Runner<
|
||||
'static,
|
||||
ExclusiveDevice<Spim<'static, peripherals::SPI3>, Output<'static>, Delay>,
|
||||
ExclusiveDevice<Spim<'static>, Output<'static>, Delay>,
|
||||
Input<'static>,
|
||||
Output<'static>,
|
||||
>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user