#![deny(missing_docs)]
#![deny(warnings)]
#![no_std]
#![allow(dead_code)]
use embedded_hal::digital::v2::OutputPin;
pub struct Dac<NSS, LDAC, ENABLE> {
nss: NSS,
ldac: LDAC,
enable: ENABLE,
active: bool,
}
#[allow(dead_code)]
#[repr(u8)]
#[derive(PartialEq)]
pub enum Channel {
A = 0b0000,
B = 0b0010,
C = 0b0100,
D = 0b0110,
ALL = 0b0111,
}
impl Channel {
pub fn from_index(index: u8) -> Channel {
if index == 0 {
return Channel::A;
} else if index == 1 {
return Channel::B;
} else if index == 2 {
return Channel::C;
} else if index == 3 {
return Channel::D;
}
panic!("Channel unknown for index {}", index);
}
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum DacError {
BusWriteError,
}
fn get_payload(channel: Channel, value: u16) -> [u8; 3] {
let mut command: [u8; 3] = [0; 3];
command[0] = 0b00010000 | (channel as u8);
command[1] = ((value & 0xFF00) >> 8) as u8;
command[2] = (value & 0xFF) as u8;
command
}
fn delay() {
let mut x = 0;
while x < 10000 {
x += 1;
}
}
impl<NSS, LDAC, ENABLE> Dac<NSS, LDAC, ENABLE>
where
NSS: OutputPin,
LDAC: OutputPin,
ENABLE: OutputPin,
{
pub fn new(nss: NSS, ldac: LDAC, enable: ENABLE) -> Self {
Self {
nss,
ldac,
enable,
active: false,
}
}
pub fn enable(&mut self) {
self.enable.set_low().unwrap_or_default();
self.nss.set_low().unwrap_or_default();
self.nss.set_high().unwrap_or_default();
self.enable.set_high().unwrap_or_default();
self.ldac.set_low().unwrap_or_default();
delay();
self.ldac.set_high().unwrap_or_default();
delay();
self.ldac.set_low().unwrap_or_default();
self.active = true;
}
pub fn write_blocking(
&mut self,
spi: &mut dyn embedded_hal::blocking::spi::Write<u8, Error = ()>,
channel: Channel,
value: u16,
) -> Result<(), DacError> {
if !self.active {
return Ok(());
}
let command: [u8; 3] = get_payload(channel, value);
self.enable.set_low().unwrap_or_default();
self.nss.set_low().unwrap_or_default();
let result = spi.write(&command);
self.nss.set_high().unwrap_or_default();
self.enable.set_high().unwrap_or_default();
match result {
Ok(v) => Ok(v),
Err(_e) => Err(DacError::BusWriteError),
}
}
pub fn prepare_transfer<F: FnMut([u8; 3]) -> ()>(
&mut self,
channel: Channel,
value: u16,
mut callback: F,
) {
if !self.active {
return;
}
let command: [u8; 3] = get_payload(channel, value);
self.enable.set_low().unwrap_or_default();
self.nss.set_low().unwrap_or_default();
callback(command);
self.nss.set_high().unwrap_or_default();
self.enable.set_high().unwrap_or_default();
}
}