use embedded_hal::digital::v2::OutputPin; use embedded_hal::blocking::spi::Transfer; #[allow(unused)] #[derive(Clone, Copy)] #[repr(u8)] pub enum Register { Status = 0x00, AdcMode = 0x01, IfMode = 0x02, RegCheck = 0x03, Data = 0x04, GpioCon = 0x06, Id = 0x07, Ch0 = 0x10, Ch1 = 0x11, Ch2 = 0x12, Ch3 = 0x13, SetupCon0 = 0x20, SetupCon1 = 0x21, SetupCon2 = 0x22, SetupCon3 = 0x23, FiltCon0 = 0x28, FiltCon1 = 0x29, FiltCon2 = 0x2A, FiltCon3 = 0x2B, Offset0 = 0x30, Offset1 = 0x31, Offset2 = 0x32, Offset3 = 0x33, Gain0 = 0x38, Gain1 = 0x39, Gain2 = 0x3A, Gain3 = 0x3B, } /// AD7172-2 implementation /// /// [Manual](https://www.analog.com/media/en/technical-documentation/data-sheets/AD7172-2.pdf) pub struct Adc, NSS: OutputPin> { spi: SPI, nss: NSS, } impl, NSS: OutputPin> Adc { pub fn new(spi: SPI, mut nss: NSS) -> Result { let _ = nss.set_high(); let mut adc = Adc { spi, nss}; let mut buf = [0, 0, 0]; adc.write_reg(Register::AdcMode, &mut buf)?; let mut buf = [0, 1, 0]; adc.write_reg(Register::IfMode, &mut buf)?; let mut buf = [0, 0, 0]; adc.write_reg(Register::GpioCon, &mut buf)?; Ok(adc) } /// `0x00DX` for AD7271-2 pub fn identify(&mut self) -> Option { let mut buf = [0u8; 3]; self.read_reg(Register::Id, &mut buf) .ok() .map(|()| (u16::from(buf[1]) << 8) | u16::from(buf[2])) } /// Returns the channel the data is from pub fn data_ready(&mut self) -> Option { let mut buf = [0u8; 2]; self.read_reg(Register::Status, &mut buf) .ok() .and_then(|()| { if buf[1] & 0x80 == 0 { None } else { Some(buf[1] & 0x3) } }) } /// Get data pub fn read_data(&mut self) -> Result { let mut buf = [0u8; 4]; self.read_reg(Register::Data, &mut buf)?; let result = (u32::from(buf[1]) << 16) | (u32::from(buf[2]) << 8) | u32::from(buf[3]); Ok(result) } fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], SPI::Error> { let _ = self.nss.set_low(); let result = self.spi.transfer(words); let _ = self.nss.set_high(); result } fn read_reg(&mut self, reg: Register, buffer: &'_ mut [u8]) -> Result<(), SPI::Error> { buffer[0] = 0x40 | (reg as u8); self.transfer(buffer)?; Ok(()) } fn write_reg(&mut self, reg: Register, buffer: &'_ mut [u8]) -> Result<(), SPI::Error> { buffer[0] = reg as u8; self.transfer(buffer)?; Ok(()) } }