2019-08-08 08:08:14 +08:00
|
|
|
use embedded_hal::digital::v2::OutputPin;
|
|
|
|
use embedded_hal::blocking::spi::Transfer;
|
|
|
|
|
2019-08-08 08:23:17 +08:00
|
|
|
#[allow(unused)]
|
2019-08-30 05:54:44 +08:00
|
|
|
#[derive(Clone, Copy)]
|
2019-08-08 08:08:14 +08:00
|
|
|
#[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,
|
|
|
|
}
|
|
|
|
|
2019-08-30 05:55:45 +08:00
|
|
|
/// AD7172-2 implementation
|
|
|
|
///
|
|
|
|
/// [Manual](https://www.analog.com/media/en/technical-documentation/data-sheets/AD7172-2.pdf)
|
2019-08-08 08:08:14 +08:00
|
|
|
pub struct Adc<SPI: Transfer<u8>, NSS: OutputPin> {
|
|
|
|
spi: SPI,
|
|
|
|
nss: NSS,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<SPI: Transfer<u8>, NSS: OutputPin> Adc<SPI, NSS> {
|
|
|
|
pub fn new(spi: SPI, nss: NSS) -> Result<Self, SPI::Error> {
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2019-08-30 05:56:02 +08:00
|
|
|
/// `0x00DX` for AD7271-2
|
|
|
|
pub fn identify(&mut self) -> Option<u16> {
|
|
|
|
let mut buf = [0u8; 3];
|
|
|
|
self.read_reg(Register::Id, &mut buf)
|
|
|
|
.ok()
|
|
|
|
.map(|()| (u16::from(buf[1]) << 8) | u16::from(buf[2]))
|
|
|
|
}
|
|
|
|
|
2019-08-08 08:08:14 +08:00
|
|
|
/// Returns the channel the data is from
|
|
|
|
pub fn data_ready(&mut self) -> Option<u8> {
|
|
|
|
let mut buf = [0u8; 2];
|
2019-08-30 05:55:45 +08:00
|
|
|
self.read_reg(Register::Status, &mut buf)
|
|
|
|
.ok()
|
|
|
|
.and_then(|()| {
|
2019-08-08 08:08:14 +08:00
|
|
|
if buf[1] & 0x80 == 0 {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(buf[1] & 0x3)
|
|
|
|
}
|
2019-08-30 05:55:45 +08:00
|
|
|
})
|
2019-08-08 08:08:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Get data
|
|
|
|
pub fn read_data(&mut self) -> Result<u32, SPI::Error> {
|
|
|
|
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> {
|
2019-08-30 05:54:44 +08:00
|
|
|
buffer[0] = 0x40 | (reg as u8);
|
2019-08-08 08:08:14 +08:00
|
|
|
self.transfer(buffer)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write_reg(&mut self, reg: Register, buffer: &'_ mut [u8]) -> Result<(), SPI::Error> {
|
2019-08-30 05:54:44 +08:00
|
|
|
buffer[0] = reg as u8;
|
2019-08-08 08:08:14 +08:00
|
|
|
self.transfer(buffer)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|