use crate::device::sys_timer::sleep; use stm32f4xx_hal::{ hal::{blocking::spi::Transfer, digital::v2::OutputPin}, spi, }; /// SPI Mode 1 pub const SPI_MODE: spi::Mode = spi::Mode { polarity: spi::Polarity::IdleLow, phase: spi::Phase::CaptureOnSecondTransition, }; pub const SPI_CLOCK_MHZ: u32 = 30; pub const MAX_VALUE: u32 = 0x3FFFF; pub struct Dac, S: OutputPin> { spi: SPI, sync: S, } impl, S: OutputPin> Dac { pub fn new(spi: SPI, mut sync: S) -> Self { let _ = sync.set_low(); Dac { spi, sync } } fn write(&mut self, buf: &mut [u8]) -> Result<(), SPI::Error> { // pulse sync to start a new transfer. leave sync idle low // afterwards to save power as recommended per datasheet. let _ = self.sync.set_high(); // must be high for >= 33 ns sleep(1); let _ = self.sync.set_low(); self.spi.transfer(buf)?; Ok(()) } pub fn set(&mut self, value: u32) -> Result { let value = value.min(MAX_VALUE); let mut buf = [(value >> 14) as u8, (value >> 6) as u8, (value << 2) as u8]; self.write(&mut buf)?; Ok(value) } }