From 95aeedf97fa3d5846d14253f3cc95817384837f6 Mon Sep 17 00:00:00 2001 From: chrysn Date: Sun, 5 Jan 2025 22:23:05 +0100 Subject: [PATCH] tests/spi: Test SpiBus --- tests/spi/Cargo.toml | 1 + tests/spi/src/lib.rs | 51 ++++++++++++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/tests/spi/Cargo.toml b/tests/spi/Cargo.toml index 19550df..d771c6a 100644 --- a/tests/spi/Cargo.toml +++ b/tests/spi/Cargo.toml @@ -13,3 +13,4 @@ panic = "abort" [dependencies] riot-wrappers = { path = "../..", features = [ "set_panic_handler", "panic_handler_format" ] } embedded-hal = "1" +embedded-hal-bus = "0.2.0" diff --git a/tests/spi/src/lib.rs b/tests/spi/src/lib.rs index 79b6c0b..727986a 100644 --- a/tests/spi/src/lib.rs +++ b/tests/spi/src/lib.rs @@ -22,28 +22,51 @@ fn main() { }; let cs = riot_wrappers::gpio::GPIO::from_port_and_pin(cs_num.0, cs_num.1).unwrap(); - let spi = - riot_wrappers::spi::for_embedded_hal_1::SPIBus::from_number(spi_num) - // arbitrary parameters - .with_speed_1mhz() - .with_mode(embedded_hal::spi::MODE_2); + let spi = riot_wrappers::spi::for_embedded_hal_1::SPIBus::from_number(spi_num) + // arbitrary parameters + .with_speed_1mhz() + .with_mode(embedded_hal::spi::MODE_2); + + println!("Testing with software CS"); + // Writing a test for the SpiBus would be annoyingly repetitive compared to the one for + // SpiDevice; using the SpiBus through the embedded-hal-bus mechanism instead. + // + // Also, there's not really anything about this test where the use of the CS pin makes any + // difference in the outcome, it's more to cover the full API surface. + let Ok(mut spi_with_soft_cs) = embedded_hal_bus::spi::ExclusiveDevice::new( + spi, + cs.configure_as_output(riot_wrappers::gpio::OutputMode::Out).unwrap(), + riot_wrappers::ztimer::Clock::usec(), + ); + test_on_device(&mut spi_with_soft_cs); + + // ExclusiveDevice has no destructuring finalizer, so we just rebuild the pieces, which RIOT + // lets us do -- and it won't cause any sort of practical trouble because the exclusive device + // is not used any more, probably even dropped already. + let cs = riot_wrappers::gpio::GPIO::from_port_and_pin(cs_num.0, cs_num.1).unwrap(); + let spi = riot_wrappers::spi::for_embedded_hal_1::SPIBus::from_number(spi_num) + // arbitrary parameters + .with_speed_1mhz() + .with_mode(embedded_hal::spi::MODE_2); println!("Testing with hardware CS"); // It is not guaranteed that this is really hardware CS; could just as well be performed by // RIOT internally. - let mut spi_with_hard_cs = spi - .with_cs(cs) - .unwrap(); + let mut spi_with_hard_cs = spi.with_cs(cs).unwrap(); test_on_device(&mut spi_with_hard_cs); - println!("Tests done."); + println!("Both tests done."); } -fn test_on_device>(spi: &mut D) { +// This is a bit .unwrap()py even though all our devices have infallible SPI (and CS) operations at +// rumtime; can't use `let Ok(()) = …;` because the ExclusiveDevice has an Either type, and I haven't found an easy way to require that the associated error of D is +// uninhabited. +fn test_on_device(spi: &mut D) { println!("Plain transfer in place:"); let mut buf = [0, 0, 0x12, 0x34]; println!("Writing {:?}, …", buf); - let Ok(()) = spi.transfer_in_place(&mut buf); + spi.transfer_in_place(&mut buf).unwrap(); println!("read {:?}.", buf); println!("Write from flash:"); @@ -51,7 +74,7 @@ fn test_on_device>(spi: &mut D) // read flash. let buf = [0, 0, 0x12, 0x34]; println!("Writing {:?}.", buf); - let Ok(()) = spi.write(&buf); + spi.write(&buf).unwrap(); println!("Performing complex sequence:"); let writebuf = [0; 300]; @@ -64,7 +87,7 @@ fn test_on_device>(spi: &mut D) Operation::Read(&mut readbuf1), Operation::Read(&mut readbuf2), ]; - let Ok(()) = spi.transaction(&mut operations); + spi.transaction(&mut operations).unwrap(); println!( "Wrote [0; 300], read into {:?} and {:?}", readbuf1, readbuf2 @@ -73,7 +96,7 @@ fn test_on_device>(spi: &mut D) println!("Plain transfer in place:"); let writebuf = [0, 0]; let mut readbuf = [0xff; 10]; - let Ok(()) = spi.transfer(&mut readbuf, &writebuf); + spi.transfer(&mut readbuf, &writebuf).unwrap(); println!( "In mixed transfer, wrote [0; 2], and continued reading into {:?}.", readbuf