use embedded_hal::{ blocking::spi::Transfer, digital::v2::OutputPin, }; use core::marker::PhantomData; use crate::cpld::{DoOnGetRefMutData, SelectChip, IssueIOUpdate}; use crate::Error; pub struct SPISlave<'a, DEV: 'a, SPI, CS0, CS1, CS2, GPIO> ( &'a DEV, u8, // Channel of SPI slave bool, // Need I/O Update PhantomData<(SPI, CS0, CS1, CS2, GPIO)>, ); pub struct Parts<'a, DEV: 'a, SPI, CS0, CS1, CS2, GPIO> { pub spi1: SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO>, pub spi2: SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO>, pub spi3: SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO>, pub spi4: SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO>, pub spi5: SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO>, pub spi6: SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO>, pub spi7: SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO>, } impl<'a, DEV, SPI, CS0, CS1, CS2, GPIO> Parts<'a, DEV, SPI, CS0, CS1, CS2, GPIO> { pub(crate) fn new(cpld: &'a DEV) -> Self { Parts { spi1: SPISlave(&cpld, 1, false, PhantomData), spi2: SPISlave(&cpld, 2, false, PhantomData), spi3: SPISlave(&cpld, 3, true, PhantomData), spi4: SPISlave(&cpld, 4, true, PhantomData), spi5: SPISlave(&cpld, 5, true, PhantomData), spi6: SPISlave(&cpld, 6, true, PhantomData), spi7: SPISlave(&cpld, 7, true, PhantomData), } } } impl<'a, DEV, SPI, CS0, CS1, CS2, GPIO, E> Transfer for SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO> where CS2: OutputPin, CS1: OutputPin, CS0: OutputPin, DEV: DoOnGetRefMutData, SPI: Transfer, GPIO: OutputPin, { 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); if self.2 { dev.issue_io_update(); } result }) } }