Skip to content

Commit

Permalink
tests/spi: Test SpiBus
Browse files Browse the repository at this point in the history
  • Loading branch information
chrysn committed Jan 5, 2025
1 parent 990f5e9 commit 2ad598a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
1 change: 1 addition & 0 deletions tests/spi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
51 changes: 37 additions & 14 deletions tests/spi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,59 @@ 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<D: SpiDevice<Error = core::convert::Infallible>>(spi: &mut D) {
// This is a bit .unwrap()py even though all our devices have infallible SPI (and CS) operations at
// runtime; can't use `let Ok(()) = …;` because the ExclusiveDevice has an Either<Infallible,
// Infallible> type, and I haven't found an easy way to require that the associated error of D is
// uninhabited.
fn test_on_device<D: SpiDevice>(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:");
// Writing from flash makes a difference eg. on nrf52: That peripheral is DMA only and can not
// 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];
Expand All @@ -64,7 +87,7 @@ fn test_on_device<D: SpiDevice<Error = core::convert::Infallible>>(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
Expand All @@ -73,7 +96,7 @@ fn test_on_device<D: SpiDevice<Error = core::convert::Infallible>>(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
Expand Down

0 comments on commit 2ad598a

Please sign in to comment.