39 lines
1.0 KiB
Rust
39 lines
1.0 KiB
Rust
use embedded_hal::spi::{Operation, SpiDevice};
|
|
use anyhow::{ensure, Result};
|
|
use crate::hardware::error::SpiError;
|
|
|
|
pub struct Mcp3208<SPI> {
|
|
spi: SPI,
|
|
vref: f64
|
|
}
|
|
|
|
impl<SPI> Mcp3208<SPI>
|
|
where
|
|
SPI : SpiDevice<u8>,
|
|
SPI::Error : Send,
|
|
SPI::Error : Sync,
|
|
SPI::Error : 'static,
|
|
{
|
|
pub fn new(spi: SPI, vref: f64) -> Self {
|
|
Self {
|
|
spi,
|
|
vref
|
|
}
|
|
}
|
|
|
|
pub fn read_single(&mut self, channel: u8) -> Result<f64> {
|
|
ensure!(channel < 8, "Invalid Channel {channel}");
|
|
|
|
// We don't care what the third byte written is
|
|
let mut write_bits = [0b00000110, 0b00000000, 0b00000000];
|
|
write_bits[0] |= (channel.unbounded_shr(2)) & 0xFF;
|
|
write_bits[1] |= (channel.unbounded_shl(6)) & 0xFF;
|
|
|
|
let mut read_bits = [0u8; 3];
|
|
self.spi.transfer(&mut read_bits, &write_bits).map_err(SpiError)?;
|
|
|
|
let value: u16 = u16::from_be_bytes([read_bits[1], read_bits[2]]) & 0x0FFF;
|
|
|
|
Ok(((value as f64) / (0xFFF as f64)) * self.vref)
|
|
}
|
|
} |