use embedded_hal::{ blocking::spi::Transfer, digital::v2::OutputPin, }; use core::marker::PhantomData; use crate::{DoOnGetRefMutData, Error, SelectChip}; pub struct SPISlave<'a, DEV: 'a, SPI, CS0, CS1, CS2> ( &'a DEV, u8, PhantomData<(SPI, CS0, CS1, CS2)>, ); pub struct Parts<'a, DEV: 'a, SPI, CS0, CS1, CS2> { pub spi1: SPISlave<'a, DEV, SPI, CS0, CS1, CS2>, pub spi2: SPISlave<'a, DEV, SPI, CS0, CS1, CS2>, pub spi3: SPISlave<'a, DEV, SPI, CS0, CS1, CS2>, pub spi4: SPISlave<'a, DEV, SPI, CS0, CS1, CS2>, pub spi5: SPISlave<'a, DEV, SPI, CS0, CS1, CS2>, pub spi6: SPISlave<'a, DEV, SPI, CS0, CS1, CS2>, pub spi7: SPISlave<'a, DEV, SPI, CS0, CS1, CS2>, } impl<'a, DEV, SPI, CS0, CS1, CS2> Parts<'a, DEV, SPI, CS0, CS1, CS2> { pub(crate) fn new(cpld: &'a DEV) -> Self { Parts { spi1: SPISlave(&cpld, 1, PhantomData), spi2: SPISlave(&cpld, 2, PhantomData), spi3: SPISlave(&cpld, 3, PhantomData), spi4: SPISlave(&cpld, 4, PhantomData), spi5: SPISlave(&cpld, 5, PhantomData), spi6: SPISlave(&cpld, 6, PhantomData), spi7: SPISlave(&cpld, 7, PhantomData), } } } impl<'a, DEV, SPI, CS0, CS1, CS2, E> Transfer for SPISlave<'a, DEV, SPI, CS0, CS1, CS2> where CS2: OutputPin, CS1: OutputPin, CS0: OutputPin, DEV: DoOnGetRefMutData, SPI: Transfer, { type Error = Error; fn transfer<'w>(&mut self, words: &'w mut[u8]) -> Result<&'w [u8], Self::Error> { self.0.do_on_get_ref_mut_data(move |mut dev| { dev.select_chip(self.1); let result = dev.spi.transfer(words).map_err(Error::SPI); dev.select_chip(0); result }) } }