use crate::cpld::CPLD; use crate::urukul::Error; use embedded_hal::{blocking::spi::Transfer, digital::v2::OutputPin}; pub struct SPISlave<'a, SPI, CS0, CS1, CS2, GPIO>( // SPI device to be multiplexed &'a CPLD, // Channel of SPI slave u8, // Need I/O Update bool, ); pub struct Parts<'a, SPI, CS0, CS1, CS2, GPIO> { pub spi1: SPISlave<'a, SPI, CS0, CS1, CS2, GPIO>, pub spi2: SPISlave<'a, SPI, CS0, CS1, CS2, GPIO>, pub spi3: SPISlave<'a, SPI, CS0, CS1, CS2, GPIO>, pub spi4: SPISlave<'a, SPI, CS0, CS1, CS2, GPIO>, pub spi5: SPISlave<'a, SPI, CS0, CS1, CS2, GPIO>, pub spi6: SPISlave<'a, SPI, CS0, CS1, CS2, GPIO>, pub spi7: SPISlave<'a, SPI, CS0, CS1, CS2, GPIO>, } impl<'a, SPI, CS0, CS1, CS2, GPIO> Parts<'a, SPI, CS0, CS1, CS2, GPIO> { pub(crate) fn new(cpld: &'a CPLD) -> Self { Parts { spi1: SPISlave(&cpld, 1, false), spi2: SPISlave(&cpld, 2, false), spi3: SPISlave(&cpld, 3, false), spi4: SPISlave(&cpld, 4, true), spi5: SPISlave(&cpld, 5, true), spi6: SPISlave(&cpld, 6, true), spi7: SPISlave(&cpld, 7, true), } } } impl<'a, SPI, CS0, CS1, CS2, GPIO, E> Transfer for SPISlave<'a, SPI, CS0, CS1, CS2, GPIO> where CS2: OutputPin, CS1: OutputPin, CS0: OutputPin, SPI: Transfer, GPIO: OutputPin, { type Error = Error; fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { let mut dev = self .0 .data .try_borrow_mut() .map_err(|_| Error::GetRefMutDataError)?; dev.select_chip(self.1).map_err(|_| Error::CSError)?; let result = dev.spi.transfer(words).map_err(Error::SPI)?; dev.select_chip(0).map_err(|_| Error::CSError)?; if self.2 { dev.issue_io_update().map_err(|_| Error::IOUpdateError)?; } Ok(result) } }