diff --git a/src/cpld.rs b/src/cpld.rs index 9e705e4..2a19124 100644 --- a/src/cpld.rs +++ b/src/cpld.rs @@ -23,12 +23,7 @@ pub struct CPLD { pub(crate) data: cell::RefCell>, } -pub trait SelectChip { - type Error; - fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error>; -} - -impl SelectChip for CPLDData +impl CPLDData where SPI: Transfer, CS0: OutputPin, @@ -36,8 +31,7 @@ where CS2: OutputPin, GPIO: OutputPin, { - type Error = Error; - fn select_chip(&mut self, chip: u8) -> Result<(), Self::Error> { + pub(crate) fn select_chip(&mut self, chip: u8) -> Result<(), Error> { match chip & (1 << 0) { 0 => self.chip_select.0.set_low(), _ => self.chip_select.0.set_high(), @@ -52,49 +46,13 @@ where }.map_err(|_| Error::CSError)?; Ok(()) } -} -pub trait IssueIOUpdate { - type Error; - fn issue_io_update(&mut self) -> Result<(), Self::Error>; -} - -impl IssueIOUpdate for CPLDData -where - SPI: Transfer, - CS0: OutputPin, - CS1: OutputPin, - CS2: OutputPin, - GPIO: OutputPin, -{ - type Error = Error; - - fn issue_io_update(&mut self) -> Result<(), Self::Error> { + pub(crate) fn issue_io_update(&mut self) -> Result<(), Error> { self.io_update.set_high().map_err(|_| Error::IOUpdateError)?; self.io_update.set_low().map_err(|_| Error::IOUpdateError) } } -pub trait DoOnGetRefMutData { - fn do_on_get_ref_mut_data( - &self, - f: impl FnOnce(cell::RefMut>) -> Result>, - ) -> Result>; -} - -impl DoOnGetRefMutData for CPLD { - fn do_on_get_ref_mut_data( - &self, - f: impl FnOnce(cell::RefMut>) -> Result>, - ) -> Result> { - let dev = self - .data - .try_borrow_mut() - .map_err(|_| Error::GetRefMutDataError)?; - f(dev) - } -} - impl Transfer for CPLD where SPI: Transfer, @@ -106,7 +64,7 @@ where type Error = Error; fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> { - self.do_on_get_ref_mut_data(move |mut dev| dev.spi.transfer(words).map_err(Error::SPI)) + self.data.try_borrow_mut().map_err(|_| Error::GetRefMutDataError)?.spi.transfer(words).map_err(Error::SPI) } } @@ -140,26 +98,7 @@ impl CPLD where } // Split SPI into chips, wrapped by Parts struct - pub fn split<'a>(&'a self) -> Parts<'a, CPLD, SPI, CS0, CS1, CS2, GPIO> { + pub fn split<'a>(&'a self) -> Parts<'a, SPI, CS0, CS1, CS2, GPIO> { Parts::new(&self) } - - // Select Chip - pub fn select_chip(&mut self, channel: u8) -> Result<(), Error> { - self.do_on_get_ref_mut_data(|mut dev| dev.select_chip(channel)) - } } - -impl CPLD -where - SPI: Transfer, - CS0: OutputPin, - CS1: OutputPin, - CS2: OutputPin, - GPIO: OutputPin -{ - // Issue I/O Update - pub fn issue_io_update(&mut self) -> Result<(), Error> { - self.do_on_get_ref_mut_data(|mut dev| dev.issue_io_update()) - } -} \ No newline at end of file diff --git a/src/spi_slave.rs b/src/spi_slave.rs index 2d8d00c..0b1e89c 100644 --- a/src/spi_slave.rs +++ b/src/spi_slave.rs @@ -4,60 +4,60 @@ use embedded_hal::{ }; use core::marker::PhantomData; -use crate::cpld::{DoOnGetRefMutData, SelectChip, IssueIOUpdate}; +use crate::cpld::CPLD; 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 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, 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>, +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, DEV, SPI, CS0, CS1, CS2, GPIO> Parts<'a, DEV, SPI, CS0, CS1, CS2, GPIO> { - pub(crate) fn new(cpld: &'a DEV) -> Self { +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, 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), + spi1: SPISlave(&cpld, 1, false), + spi2: SPISlave(&cpld, 2, false), + spi3: SPISlave(&cpld, 3, true), + spi4: SPISlave(&cpld, 4, true), + spi5: SPISlave(&cpld, 5, true), + spi6: SPISlave(&cpld, 6, true), + spi7: SPISlave(&cpld, 7, true), } } } -impl<'a, DEV, SPI, CS0, CS1, CS2, GPIO, E> Transfer for SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO> +impl<'a, SPI, CS0, CS1, CS2, GPIO, E> Transfer for SPISlave<'a, 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).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) - }) + 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) } }