humpback-dds/src/spi_slave.rs

64 lines
2.0 KiB
Rust
Raw Normal View History

2020-08-11 00:07:07 +08:00
use embedded_hal::{
blocking::spi::Transfer,
digital::v2::OutputPin,
2020-08-10 17:04:40 +08:00
};
use core::marker::PhantomData;
2020-08-31 09:31:56 +08:00
use crate::cpld::{DoOnGetRefMutData, SelectChip, IssueIOUpdate};
use crate::Error;
2020-08-10 17:04:40 +08:00
2020-08-24 17:03:44 +08:00
pub struct SPISlave<'a, DEV: 'a, SPI, CS0, CS1, CS2, GPIO> (
2020-08-10 17:04:40 +08:00
&'a DEV,
2020-08-24 17:03:44 +08:00
u8, // Channel of SPI slave
bool, // Need I/O Update
PhantomData<(SPI, CS0, CS1, CS2, GPIO)>,
2020-08-10 17:04:40 +08:00
);
2020-08-24 17:03:44 +08:00
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>,
2020-08-10 17:04:40 +08:00
}
2020-08-24 17:03:44 +08:00
impl<'a, DEV, SPI, CS0, CS1, CS2, GPIO> Parts<'a, DEV, SPI, CS0, CS1, CS2, GPIO> {
2020-08-10 17:04:40 +08:00
pub(crate) fn new(cpld: &'a DEV) -> Self {
Parts {
2020-08-24 17:03:44 +08:00
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),
2020-08-10 17:04:40 +08:00
}
}
}
2020-08-24 17:03:44 +08:00
impl<'a, DEV, SPI, CS0, CS1, CS2, GPIO, E> Transfer<u8> for SPISlave<'a, DEV, SPI, CS0, CS1, CS2, GPIO>
2020-08-10 17:04:40 +08:00
where
CS2: OutputPin,
CS1: OutputPin,
CS0: OutputPin,
2020-08-24 17:03:44 +08:00
DEV: DoOnGetRefMutData<SPI, CS0, CS1, CS2, GPIO>,
2020-08-10 17:04:40 +08:00
SPI: Transfer<u8, Error = E>,
2020-08-24 17:03:44 +08:00
GPIO: OutputPin,
2020-08-10 17:04:40 +08:00
{
type Error = Error<E>;
fn transfer<'w>(&mut self, words: &'w mut[u8]) -> Result<&'w [u8], Self::Error> {
2020-08-11 11:29:47 +08:00
self.0.do_on_get_ref_mut_data(move |mut dev| {
2020-09-14 17:33:50 +08:00
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)?;
2020-08-24 17:03:44 +08:00
if self.2 {
2020-09-14 17:33:50 +08:00
dev.issue_io_update().map_err(|_| Error::IOUpdateError)?;
2020-08-24 17:03:44 +08:00
}
2020-09-14 17:33:50 +08:00
Ok(result)
2020-08-11 11:29:47 +08:00
})
2020-08-10 17:04:40 +08:00
}
}