#![no_std]
#![warn(missing_docs)]
#![cfg_attr(not(doctest), doc = include_str!("../README.md"))]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
use embedded_hal::spi::{Operation, SpiDevice};
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error<SPI> {
Spi(SPI),
Parity,
Magnet,
}
pub struct Mt6816<SPI>
where
SPI: SpiDevice,
{
spi: SPI,
}
impl<SPI> Mt6816<SPI>
where
SPI: SpiDevice,
{
pub fn new(spi: SPI) -> Self {
Self { spi }
}
pub fn read_angle(&mut self) -> Result<u16, Error<SPI::Error>> {
let mut buf = [0u8; 2];
self.spi
.transaction(&mut [Operation::Write(&[0x83]), Operation::Read(&mut buf)])
.map_err(Error::Spi)?;
let raw = u16::from_be_bytes(buf);
let parity_bit = (raw & (1 << 0)) != 0;
let magnet_bit = (raw & (1 << 1)) != 0;
let angle = raw >> 2;
let calculated_parity = ((raw >> 1).count_ones() % 2) != 0;
if calculated_parity != parity_bit {
return Err(Error::Parity);
}
if magnet_bit {
return Err(Error::Magnet);
}
Ok(angle)
}
}