62 lines
1.9 KiB
Rust
62 lines
1.9 KiB
Rust
use embedded_hal::{
|
|
blocking::spi::Transfer,
|
|
digital::v2::OutputPin,
|
|
};
|
|
use crate::cpld::CPLD;
|
|
use crate::urukul::Error;
|
|
|
|
pub struct SPISlave<'a, SPI, CS0, CS1, CS2, GPIO> (
|
|
// SPI device to be multiplexed
|
|
&'a CPLD<SPI, CS0, CS1, CS2, GPIO>,
|
|
// 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<SPI, CS0, CS1, CS2, GPIO>) -> 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<u8> for SPISlave<'a, SPI, CS0, CS1, CS2, GPIO>
|
|
where
|
|
CS2: OutputPin,
|
|
CS1: OutputPin,
|
|
CS0: OutputPin,
|
|
SPI: Transfer<u8, Error = E>,
|
|
GPIO: OutputPin,
|
|
{
|
|
type Error = Error<E>;
|
|
|
|
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)
|
|
}
|
|
}
|