use core::cell::RefCell;
use core::ops::Deref;
use embedded_hal::delay::DelayNs;
use riscv::interrupt;
use super::{PinCS, PinsNoCS, SpiBus, SpiConfig, SpiSharedDevice, SpiX};
pub struct SharedBus<SPI, PINS>(RefCell<SpiBus<SPI, PINS>>);
impl<SPI, PINS> SharedBus<SPI, PINS>
where
SPI: SpiX,
PINS: PinsNoCS<SPI>,
{
pub(crate) fn new(bus: SpiBus<SPI, PINS>) -> Self {
Self(RefCell::new(bus))
}
pub fn new_device<'bus, CS, D>(
&'bus self,
cs: CS,
config: &SpiConfig,
delay: D,
) -> SpiSharedDevice<'bus, SPI, PINS, CS, D>
where
CS: PinCS<SPI>,
D: DelayNs,
{
SpiSharedDevice::new(self, cs, config, delay)
}
}
impl<SPI, PINS> SharedBus<SPI, PINS>
where
SPI: SpiX,
PINS: PinsNoCS<SPI>,
{
pub fn start_frame(&mut self) {
interrupt::free(|| {
let mut bus = self.0.borrow_mut();
bus.start_frame();
});
}
pub fn end_frame(&mut self) {
interrupt::free(|| {
let mut bus = self.0.borrow_mut();
bus.end_frame();
});
}
pub fn release(self) -> (SPI, PINS) {
self.0.into_inner().release()
}
}
impl<SPI, PINS> Deref for SharedBus<SPI, PINS> {
type Target = RefCell<SpiBus<SPI, PINS>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}