From 55faaba1b953cc057e9884a8242fb6f756fd685b Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Wed, 31 May 2023 03:53:30 +0100 Subject: [PATCH] Bump dependencies versions & update accordingly --- Cargo.toml | 37 ++--- examples/pico_spi_pio_sd_card.rs | 154 +++++++----------- src/lib.rs | 265 +++++++++++++++---------------- 3 files changed, 199 insertions(+), 257 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 489f62d..ce955f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,30 +10,27 @@ repository = "https://github.com/rp-rs/spi-pio-rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cortex-m = "0.7.3" -eh1_0_alpha = { version = "=1.0.0-alpha.9", package = "embedded-hal", optional = true } -embedded-hal = "0.2.6" -nb = "1.0.0" -pio = "0.2.0" -pio-proc = "0.2.0" -rp2040-hal = "0.8.0" -fugit = "0.3.5" -defmt = { version = "0.3.0", optional = true } +cortex-m = "0.7.7" +eh1_0_alpha = { version = "1.0.0-rc.1", package = "embedded-hal", optional = true } +embedded-hal = "0.2.7" +nb = "1.1.0" +pio = "0.2.1" +pio-proc = "0.2.2" +rp2040-hal = "0.9.0" +fugit = "0.3.7" +defmt = { version = "0.3.5", optional = true } [dev-dependencies] -rp2040-hal = { version = "0.8.0", features = ["defmt"] } +rp2040-hal = { version = "0.9.0", features = ["defmt"] } rp-pico = "*" panic-halt = "0.2.0" -embedded-hal = "0.2.5" +embedded-hal = "0.2.7" cortex-m-rt = "0.7" -nb = "1.0" -embedded-sdmmc = "0.4.0" -pio = "0.2.0" -pio-proc = "0.2.1" -critical-section = "1.0.0" +nb = "1.1" +embedded-sdmmc = "0.5.0" +pio = "0.2.1" +pio-proc = "0.2.2" +critical-section = "1.1.2" -defmt = "0.3.0" +defmt = "0.3.5" defmt-rtt = "0.4.0" - -[patch.crates-io] -rp2040-hal = { git = "https://github.com/rp-rs/rp-hal" } diff --git a/examples/pico_spi_pio_sd_card.rs b/examples/pico_spi_pio_sd_card.rs index 7c613c2..2efadd3 100644 --- a/examples/pico_spi_pio_sd_card.rs +++ b/examples/pico_spi_pio_sd_card.rs @@ -39,37 +39,6 @@ //! //! $ mkfs.fat /dev/sdj1 //! -//! In the following ASCII art the SD card is also connected to 5 strong pull up -//! resistors. I've found varying values for these, from 50kOhm, 10kOhm -//! down to 5kOhm. -//! Stronger pull up resistors will eat more amperes, but also allow faster -//! data rates. -//! -//! ```text -//! +3.3V -//! Pull Ups ->|||| -//! 4x[5kOhm] -//! ||| \ -//! _______________ ||| \ -//! | DAT2/NC 9\---o|| \ _|USB|_ -//! | S DAT3/CS 1|---o+----+------SS--\ |1 R 40| -//! | D CMD/DI 2|----o----+-----MOSI-+-\ |2 P 39| -//! | VSS1 3|-- GND | | | GND-|3 38|- GND -//! | C VDD 4|-- +3.3V | /--SCK--+-+----SPI0 SCK-|4 P 37| -//! | A CLK/SCK 5|---------+-/ | \----SPI0 TX--|5 I 36|- +3.3V -//! | R VSS2 6|-- GND | /--MISO-+------SPI0 RX--|6 C | -//! | D DAT0/DO 7|---------o-/ \------SPI0 CSn-|7 O | -//! | DAT1/IRQ 8|-[5k]- +3.3V | | -//! """""""""""""""" | | -//! | | -//! ......... -//! |20 21| -//! """"""" -//! Symbols: -//! - (+) crossing lines, not connected -//! - (o) connected lines -//! ``` -//! //! The example can either be used with a probe to receive debug output //! and also the LED is used as status output. There are different blinking //! patterns. @@ -104,7 +73,7 @@ use defmt_rtt as _; use panic_halt as _; // Pull in any important traits -use rp_pico::hal::prelude::*; +use rp_pico::hal::{gpio::PullUp, prelude::*}; // Embed the `Hz` function/trait: use fugit::RateExtU32; @@ -117,18 +86,22 @@ use rp_pico::hal::pac; // higher-level drivers. use rp_pico::hal; +// Provides `.delay_ms(…)`. +use embedded_hal::blocking::delay::DelayMs; +// Provides gpio generic operations. +use embedded_hal::digital::v2::OutputPin; + // Link in the embedded_sdmmc crate. // The `SdMmcSpi` is used for block level access to the card. // And the `Controller` gives access to the FAT filesystem functions. -use embedded_sdmmc::{Controller, SdMmcSpi, TimeSource, Timestamp, VolumeIdx}; +use embedded_sdmmc::{SdCard, TimeSource, Timestamp, VolumeIdx}; // Get the file open mode enum: use embedded_sdmmc::filesystem::Mode; /// A dummy timesource, which is mostly important for creating files. #[derive(Default)] -pub struct DummyTimesource(); - +pub struct DummyTimesource; impl TimeSource for DummyTimesource { // In theory you could use the RTC of the rp2040 here, if you had // any external time synchronizing device. @@ -152,11 +125,10 @@ const BLINK_ERR_2_SHORT: [u8; 4] = [1u8, 0u8, 1u8, 0u8]; const BLINK_ERR_3_SHORT: [u8; 6] = [1u8, 0u8, 1u8, 0u8, 1u8, 0u8]; const BLINK_ERR_4_SHORT: [u8; 8] = [1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8]; const BLINK_ERR_5_SHORT: [u8; 10] = [1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8]; -const BLINK_ERR_6_SHORT: [u8; 12] = [1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8, 1u8, 0u8]; fn blink_signals( - pin: &mut dyn embedded_hal::digital::v2::OutputPin, - delay: &mut cortex_m::delay::Delay, + pin: &mut impl OutputPin, + mut delay: impl DelayMs, sig: &[u8], ) { for bit in sig { @@ -179,8 +151,8 @@ fn blink_signals( } fn blink_signals_loop( - pin: &mut dyn embedded_hal::digital::v2::OutputPin, - delay: &mut cortex_m::delay::Delay, + pin: &mut impl OutputPin, + mut delay: impl DelayMs, sig: &[u8], ) -> ! { loop { @@ -191,11 +163,9 @@ fn blink_signals_loop( #[entry] fn main() -> ! { - info!("Program start"); - // Grab our singleton objects let mut pac = pac::Peripherals::take().unwrap(); - let core = pac::CorePeripherals::take().unwrap(); + let _core = pac::CorePeripherals::take().unwrap(); // Set up the watchdog driver - needed by the clock setup code let mut watchdog = hal::Watchdog::new(pac.WATCHDOG); @@ -230,13 +200,16 @@ fn main() -> ! { let mut led_pin = pins.led.into_push_pull_output(); // Setup a delay for the LED blink signals: - let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); + let mut timer = rp_pico::hal::timer::Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); + + // Enable internal pull up on MISO + let gpio4 = pins.gpio4.into_pull_type::(); // These are implicitly used by the spi driver if they are in the correct mode let (mut pio, sm0, _, _, _) = pac.PIO0.split(&mut pac.RESETS); let spi: spi_pio::Spi<'_, _, _, _, _, _, 8> = spi_pio::Spi::new( (&mut pio, sm0), - (pins.gpio4, pins.gpio3, pins.gpio2), + (gpio4, pins.gpio3, pins.gpio2), embedded_hal::spi::MODE_0, 16u32.MHz(), clocks.peripheral_clock.freq(), @@ -247,83 +220,64 @@ fn main() -> ! { // Exchange the uninitialised SPI driver for an initialised one - info!("Aquire SPI SD/MMC BlockDevice..."); - let mut sdspi = SdMmcSpi::new(spi, spi_cs); - - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); - - // Next we need to aquire the block device and initialize the - // communication with the SD card. - let block = match sdspi.acquire() { - Ok(block) => block, - Err(e) => { - error!("Error retrieving card size: {}", defmt::Debug2Format(&e)); - blink_signals_loop(&mut led_pin, &mut delay, &BLINK_ERR_2_SHORT); - } - }; - - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); - info!("Init SD card controller..."); - let mut cont = Controller::new(block, DummyTimesource::default()); - - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); + let sdcard = SdCard::new(spi, spi_cs, timer); info!("OK!\nCard size..."); - match cont.device().card_size_bytes() { + match sdcard.num_bytes() { Ok(size) => info!("card size is {} bytes", size), Err(e) => { error!("Error retrieving card size: {}", defmt::Debug2Format(&e)); - blink_signals_loop(&mut led_pin, &mut delay, &BLINK_ERR_3_SHORT); + blink_signals_loop(&mut led_pin, timer, &BLINK_ERR_2_SHORT); } } - - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); + blink_signals(&mut led_pin, timer, &BLINK_OK_LONG); info!("Getting Volume 0..."); - let mut volume = match cont.get_volume(VolumeIdx(0)) { + let mut volume_mgr = embedded_sdmmc::VolumeManager::new(sdcard, DummyTimesource); + let mut volume = match volume_mgr.get_volume(VolumeIdx(0)) { Ok(v) => v, Err(e) => { error!("Error getting volume 0: {}", defmt::Debug2Format(&e)); - blink_signals_loop(&mut led_pin, &mut delay, &BLINK_ERR_4_SHORT); + blink_signals_loop(&mut led_pin, timer, &BLINK_ERR_3_SHORT); } }; - - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); + blink_signals(&mut led_pin, timer, &BLINK_OK_LONG); // After we have the volume (partition) of the drive we got to open the // root directory: - let dir = match cont.open_root_dir(&volume) { + let dir = match volume_mgr.open_root_dir(&volume) { Ok(dir) => dir, Err(e) => { error!("Error opening root dir: {}", defmt::Debug2Format(&e)); - blink_signals_loop(&mut led_pin, &mut delay, &BLINK_ERR_5_SHORT); + blink_signals_loop(&mut led_pin, timer, &BLINK_ERR_4_SHORT); } }; info!("Root directory opened!"); - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); + blink_signals(&mut led_pin, timer, &BLINK_OK_LONG); // This shows how to iterate through the directory and how // to get the file names (and print them in hope they are UTF-8 compatible): - cont.iterate_dir(&volume, &dir, |ent| { - info!( - "/{}.{}", - core::str::from_utf8(ent.name.base_name()).unwrap(), - core::str::from_utf8(ent.name.extension()).unwrap() - ); - }) - .unwrap(); - - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); + volume_mgr + .iterate_dir(&volume, &dir, |ent| { + info!( + "/{}.{}", + core::str::from_utf8(ent.name.base_name()).unwrap(), + core::str::from_utf8(ent.name.extension()).unwrap() + ); + }) + .unwrap(); + + blink_signals(&mut led_pin, timer, &BLINK_OK_LONG); let mut successful_read = false; // Next we going to read a file from the SD card: - if let Ok(mut file) = cont.open_file_in_dir(&mut volume, &dir, "O.TST", Mode::ReadOnly) { + if let Ok(mut file) = volume_mgr.open_file_in_dir(&mut volume, &dir, "O.TST", Mode::ReadOnly) { let mut buf = [0u8; 32]; - let read_count = cont.read(&volume, &mut file, &mut buf).unwrap(); - cont.close_file(&volume, file).unwrap(); + let read_count = volume_mgr.read(&volume, &mut file, &mut buf).unwrap(); + volume_mgr.close_file(&volume, file).unwrap(); if read_count >= 2 { info!("READ {} bytes: {}", read_count, buf); @@ -337,22 +291,24 @@ fn main() -> ! { } } - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); + blink_signals(&mut led_pin, timer, &BLINK_OK_LONG); - match cont.open_file_in_dir(&mut volume, &dir, "O.TST", Mode::ReadWriteCreateOrTruncate) { + match volume_mgr.open_file_in_dir(&mut volume, &dir, "O.TST", Mode::ReadWriteCreateOrTruncate) { Ok(mut file) => { - cont.write(&mut volume, &mut file, b"\x42\x1E").unwrap(); - cont.close_file(&volume, file).unwrap(); + volume_mgr + .write(&mut volume, &mut file, b"\x42\x1E") + .unwrap(); + volume_mgr.close_file(&volume, file).unwrap(); } Err(e) => { error!("Error opening file 'O.TST': {}", defmt::Debug2Format(&e)); - blink_signals_loop(&mut led_pin, &mut delay, &BLINK_ERR_6_SHORT); + blink_signals_loop(&mut led_pin, timer, &BLINK_ERR_5_SHORT); } } - cont.free(); + volume_mgr.free(); - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_LONG); + blink_signals(&mut led_pin, timer, &BLINK_OK_LONG); if successful_read { info!("Successfully read previously written file 'O.TST'"); @@ -363,11 +319,11 @@ fn main() -> ! { loop { if successful_read { - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_SHORT_SHORT_LONG); + blink_signals(&mut led_pin, timer, &BLINK_OK_SHORT_SHORT_LONG); } else { - blink_signals(&mut led_pin, &mut delay, &BLINK_OK_SHORT_LONG); + blink_signals(&mut led_pin, timer, &BLINK_OK_SHORT_LONG); } - delay.delay_ms(1000); + timer.delay_ms(1000); } } diff --git a/src/lib.rs b/src/lib.rs index df850b5..34ae64d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ #![no_std] +use core::marker::PhantomData; + use embedded_hal::{ blocking::spi, spi::{Phase, Polarity}, @@ -6,20 +8,21 @@ use embedded_hal::{ use fugit::HertzU32; use pio::{Instruction, InstructionOperands}; use rp2040_hal::{ - gpio::{Disabled, DisabledConfig, Function, FunctionConfig, Pin, PinId, ValidPinMode}, + gpio::{ + AnyPin, FunctionNull, FunctionSioInput, FunctionSioOutput, Pin, SpecificPin, ValidFunction, + }, pio::{ PIOExt, PinDir, PinState, Rx, ShiftDirection, StateMachine, StateMachineIndex, Tx, UninitStateMachine, PIO, }, + typelevel::Is, }; #[cfg(not(feature = "defmt"))] mod defmt { #[macro_export] macro_rules! info { - ($($_:tt)*) => {{ - compile_error!("woops"); - }}; + ($($_:tt)*) => {{}}; } #[macro_export] macro_rules! error { @@ -30,70 +33,55 @@ mod defmt { pub use super::{error, info}; } +/// Alias to the Pin tuple used in `Spi<…>` +pub type Pins = ( + Pin<::Id,

::PinFunction, ::Pull>, + Pin<::Id,

::PinFunction, ::Pull>, + Pin<::Id,

::PinFunction, ::Pull>, +); + +/// PIO based Spi driver. pub struct Spi<'pio, P, SMI, MISO, MOSI, SCLK, const DS: u8> where - P: PIOExt + FunctionConfig, + P: PIOExt, SMI: StateMachineIndex, - MISO: PinId, - MOSI: PinId, - SCLK: PinId, - Function

: ValidPinMode + ValidPinMode + ValidPinMode, + MISO: AnyPin, + MOSI: AnyPin, + SCLK: AnyPin, { _pio: &'pio mut PIO

, _sm: StateMachine<(P, SMI), rp2040_hal::pio::Running>, tx: Tx<(P, SMI)>, rx: Rx<(P, SMI)>, - #[allow(clippy::type_complexity)] - _pins: ( - Pin>, - Pin>, - Pin>, - ), + _pins: Pins, + _old_pins_states: PhantomData<(MISO, MOSI, SCLK)>, } -type NewErr = ( - UninitStateMachine<(P, SMI)>, - Pin>, - Pin>, - Pin>, -); +/// Alias for the tuple returned by `Spi::new` on error. +type NewErr = (UninitStateMachine<(P, SMI)>, (MISO, MOSI, SCLK)); impl<'pio, P, SMI, MISO, MOSI, SCLK, const DS: u8> Spi<'pio, P, SMI, MISO, MOSI, SCLK, DS> where - P: PIOExt + FunctionConfig, + P: PIOExt, SMI: StateMachineIndex, - MISO: PinId, - MOSI: PinId, - SCLK: PinId, - Function

: ValidPinMode + ValidPinMode + ValidPinMode, + MISO: AnyPin, + MOSI: AnyPin, + SCLK: AnyPin, { #[allow(clippy::type_complexity)] - pub fn new( + pub fn new( (pio, sm): (&'pio mut PIO

, UninitStateMachine<(P, SMI)>), - (miso, mosi, mut sclk): ( - Pin>, - Pin>, - Pin>, - ), + (miso, mosi, sclk): (MISO, MOSI, SCLK), mode: embedded_hal::spi::Mode, bus_freq: HertzU32, clock_freq: HertzU32, - ) -> Result< - Self, - NewErr< - P, - SMI, - MISO, - MOSI, - SCLK, - MisoDisabledConfig, - MosiDisabledConfig, - SclkDisabledConfig, - >, - > + ) -> Result> where - MisoDisabledConfig: DisabledConfig, - MosiDisabledConfig: DisabledConfig, - SclkDisabledConfig: DisabledConfig, + MISO: AnyPin + Is>, + MOSI: AnyPin + Is>, + SCLK: AnyPin + Is>, + MISO::Id: ValidFunction + ValidFunction, + MOSI::Id: ValidFunction + ValidFunction, + SCLK::Id: ValidFunction + ValidFunction, { let program = pio_proc::pio_asm!( ".side_set 1 opt" @@ -121,13 +109,13 @@ where let installed = match pio.install(&program) { Ok(inst) => inst, - Err(_) => return Err((sm, miso, mosi, sclk)), + Err(_) => return Err((sm, (miso, mosi, sclk))), }; entry_point += i32::from(installed.offset()); if entry_point > 32 { // TODO: this should check against a value from the PIO, not a hardcoded value. defmt::error!("Entry point set beyond pio's memory."); - return Err((sm, miso, mosi, sclk)); + return Err((sm, (miso, mosi, sclk))); } let entry_point = entry_point as u8; @@ -141,7 +129,7 @@ where if !(1..=65536).contains(&int) || (int == 65536 && frac != 0) { defmt::error!("The ratio between the bus frequency and the system clock must be within [1.0, 65536.0]."); pio.uninstall(installed); - return Err((sm, miso, mosi, sclk)); + return Err((sm, (miso, mosi, sclk))); } // 65536.0 is represented as 0 in the pio's clock divider if int == 65536 { @@ -151,11 +139,17 @@ where let int: u16 = int as u16; let frac: u8 = frac as u8; + let mosi = mosi.into(); + let miso = miso.into(); + let mut sclk = sclk.into(); + let mosi_pin_id = mosi.id(); + let miso_pin_id = miso.id(); + let sclk_pin_id = sclk.id(); let (mut sm, rx, tx) = rp2040_hal::pio::PIOBuilder::from_program(installed) .buffers(rp2040_hal::pio::Buffers::RxTx) - .out_pins(MOSI::DYN.num, 1) - .in_pin_base(MISO::DYN.num) - .side_set_pin_base(SCLK::DYN.num) + .out_pins(mosi_pin_id.num, 1) + .in_pin_base(miso_pin_id.num) + .side_set_pin_base(sclk_pin_id.num) .autopull(true) .autopush(true) // msb/lsb first can be selected here @@ -172,21 +166,21 @@ where sclk.set_output_override(rp2040_hal::gpio::OutputOverride::DontInvert); } let sclk = sclk.into_push_pull_output_in_state(rp2040_hal::gpio::PinState::Low); - let miso = miso.into_floating_input(); + let miso = miso.into_function::(); let mosi = mosi.into_push_pull_output_in_state(rp2040_hal::gpio::PinState::Low); sm.set_pins([ - (MOSI::DYN.num, PinState::Low), - (SCLK::DYN.num, PinState::Low), + (mosi_pin_id.num, PinState::Low), + (sclk_pin_id.num, PinState::Low), ]); sm.set_pindirs([ - (MISO::DYN.num, PinDir::Input), - (MOSI::DYN.num, PinDir::Output), - (SCLK::DYN.num, PinDir::Output), + (miso_pin_id.num, PinDir::Input), + (mosi_pin_id.num, PinDir::Output), + (sclk_pin_id.num, PinDir::Output), ]); - let miso = miso.into_mode(); - let mosi = mosi.into_mode(); - let sclk = sclk.into_mode(); + let miso = miso.into_function(); + let mosi = mosi.into_function(); + let sclk = sclk.into_function(); sm.exec_instruction(Instruction { operands: InstructionOperands::JMP { @@ -204,77 +198,74 @@ where tx, rx, _pins: (miso, mosi, sclk), + _old_pins_states: PhantomData, }) } } macro_rules! impl_write { - ($type:ty, $fn:ident, [$($nr:expr),+]) => { - $( - impl<'pio, P, SMI, MISO, MOSI, SCLK> embedded_hal::spi::FullDuplex<$type> - for Spi<'pio, P, SMI, MISO, MOSI, SCLK, $nr> - where - P: PIOExt + FunctionConfig, - SMI: StateMachineIndex, - MISO: PinId, - MOSI: PinId, - SCLK: PinId, - Function

: ValidPinMode + ValidPinMode + ValidPinMode, - { - type Error = core::convert::Infallible; + ($type:ty, $fn:ident, [$($nr:expr),+]) => { + $( + impl<'pio, P, SMI, MISO, MOSI, SCLK> embedded_hal::spi::FullDuplex<$type> + for Spi<'pio, P, SMI, MISO, MOSI, SCLK, $nr> + where + P: PIOExt, + SMI: StateMachineIndex, + MISO: AnyPin, + MOSI: AnyPin, + SCLK: AnyPin, + { + type Error = core::convert::Infallible; - fn read(&mut self) -> nb::Result<$type, Self::Error> { - if let Some(r) = self.rx.read() { - Ok(r as $type) - } else { - Err(nb::Error::WouldBlock) - } - } + fn read(&mut self) -> nb::Result<$type, Self::Error> { + if let Some(r) = self.rx.read() { + Ok(r as $type) + } else { + Err(nb::Error::WouldBlock) + } + } - fn send(&mut self, word: $type) -> nb::Result<(), Self::Error> { - if self.tx.$fn(word) { - Ok(()) - } else { - Err(nb::Error::WouldBlock) + fn send(&mut self, word: $type) -> nb::Result<(), Self::Error> { + if self.tx.$fn(word) { + Ok(()) + } else { + Err(nb::Error::WouldBlock) + } + } } - } - } - impl<'pio, P, SMI, MISO, MOSI, SCLK> spi::write::Default<$type> - for Spi<'pio, P, SMI, MISO, MOSI, SCLK, $nr> - where - P: PIOExt + FunctionConfig, - SMI: StateMachineIndex, - MISO: PinId, - MOSI: PinId, - SCLK: PinId, - Function

: ValidPinMode + ValidPinMode + ValidPinMode, - { - } - impl<'pio, P, SMI, MISO, MOSI, SCLK> spi::transfer::Default<$type> - for Spi<'pio, P, SMI, MISO, MOSI, SCLK, $nr> - where - P: PIOExt + FunctionConfig, - SMI: StateMachineIndex, - MISO: PinId, - MOSI: PinId, - SCLK: PinId, - Function

: ValidPinMode + ValidPinMode + ValidPinMode, - { - } - impl<'pio, P, SMI, MISO, MOSI, SCLK> spi::write_iter::Default<$type> - for Spi<'pio, P, SMI, MISO, MOSI, SCLK, $nr> - where - P: PIOExt + FunctionConfig, - SMI: StateMachineIndex, - MISO: PinId, - MOSI: PinId, - SCLK: PinId, - Function

: ValidPinMode + ValidPinMode + ValidPinMode, - { - } - )+ - }; -} + impl<'pio, P, SMI, MISO, MOSI, SCLK> spi::write::Default<$type> + for Spi<'pio, P, SMI, MISO, MOSI, SCLK, $nr> + where + P: PIOExt, + SMI: StateMachineIndex, + MISO: AnyPin, + MOSI: AnyPin, + SCLK: AnyPin, + { + } + impl<'pio, P, SMI, MISO, MOSI, SCLK> spi::transfer::Default<$type> + for Spi<'pio, P, SMI, MISO, MOSI, SCLK, $nr> + where + P: PIOExt, + SMI: StateMachineIndex, + MISO: AnyPin, + MOSI: AnyPin, + SCLK: AnyPin, + { + } + impl<'pio, P, SMI, MISO, MOSI, SCLK> spi::write_iter::Default<$type> + for Spi<'pio, P, SMI, MISO, MOSI, SCLK, $nr> + where + P: PIOExt, + SMI: StateMachineIndex, + MISO: AnyPin, + MOSI: AnyPin, + SCLK: AnyPin, + { + } + )+ + }; + } impl_write!(u8, write_u8_replicated, [1, 2, 3, 4, 5, 6, 7, 8]); impl_write!(u16, write_u16_replicated, [9, 10, 11, 12, 13, 14, 15, 16]); impl_write!( @@ -283,15 +274,14 @@ impl_write!( [17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32] ); -impl<'pio, P, SMI, MISO, MOSI, SCLK, const DS: u8> rp2040_hal::dma::ReadTarget +unsafe impl<'pio, P, SMI, MISO, MOSI, SCLK, const DS: u8> rp2040_hal::dma::ReadTarget for Spi<'pio, P, SMI, MISO, MOSI, SCLK, DS> where - P: PIOExt + FunctionConfig, + P: PIOExt, SMI: StateMachineIndex, - MISO: PinId, - MOSI: PinId, - SCLK: PinId, - Function

: ValidPinMode + ValidPinMode + ValidPinMode, + MISO: AnyPin, + MOSI: AnyPin, + SCLK: AnyPin, { type ReceivedWord = u32; @@ -307,15 +297,14 @@ where self.rx.rx_increment() } } -impl<'pio, P, SMI, MISO, MOSI, SCLK, const DS: u8> rp2040_hal::dma::WriteTarget +unsafe impl<'pio, P, SMI, MISO, MOSI, SCLK, const DS: u8> rp2040_hal::dma::WriteTarget for Spi<'pio, P, SMI, MISO, MOSI, SCLK, DS> where - P: PIOExt + FunctionConfig, + P: PIOExt, SMI: StateMachineIndex, - MISO: PinId, - MOSI: PinId, - SCLK: PinId, - Function

: ValidPinMode + ValidPinMode + ValidPinMode, + MISO: AnyPin, + MOSI: AnyPin, + SCLK: AnyPin, { type TransmittedWord = u32;