use crate::regs::*;
use crate::types::*;
use std::sync::{Arc, Mutex};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MockError {
I2cError,
}
impl embedded_hal::i2c::Error for MockError {
fn kind(&self) -> embedded_hal::i2c::ErrorKind {
embedded_hal::i2c::ErrorKind::Other
}
}
struct MockState {
registers: [u8; 256],
}
#[derive(Clone)]
pub struct AS56Mock {
state: Arc<Mutex<MockState>>,
}
impl AS56Mock {
pub fn new() -> Self {
let mut registers = [0u8; 256];
registers[regs::STATUS as usize] = 0x20; registers[regs::AGC as usize] = 100;
registers[regs::CONF_HI as usize] = 0x20;
Self {
state: Arc::new(Mutex::new(MockState { registers })),
}
}
pub fn mock_set_raw_angle(&self, angle: u16) {
let mut state = self.state.lock().unwrap();
let bytes = (angle & 0x0FFF).to_be_bytes();
state.registers[regs::RAW_ANGLE_HI as usize] = bytes[0];
state.registers[regs::RAW_ANGLE_LO as usize] = bytes[1];
}
pub fn mock_set_status(&self, status: MagnetStatus) {
let mut state = self.state.lock().unwrap();
let mut val = 0u8;
if status.detected {
val |= 0x20;
}
if status.too_weak {
val |= 0x10;
}
if status.too_strong {
val |= 0x08;
}
state.registers[regs::STATUS as usize] = val;
}
pub fn mock_set_agc(&self, agc: u8) {
let mut state = self.state.lock().unwrap();
state.registers[regs::AGC as usize] = agc;
}
pub fn mock_set_magnitude(&self, magnitude: u16) {
let mut state = self.state.lock().unwrap();
let bytes = magnitude.to_be_bytes();
state.registers[regs::MAGNITUDE_HI as usize] = bytes[0];
state.registers[regs::MAGNITUDE_LO as usize] = bytes[1];
}
}
impl embedded_hal::i2c::ErrorType for AS56Mock {
type Error = MockError;
}
impl embedded_hal::i2c::I2c<embedded_hal::i2c::SevenBitAddress> for AS56Mock {
fn read(&mut self, _address: u8, _read: &mut [u8]) -> Result<(), Self::Error> {
Ok(())
}
fn write(&mut self, _address: u8, write: &[u8]) -> Result<(), Self::Error> {
let mut state = self.state.lock().unwrap();
if write.len() >= 2 {
let reg = write[0] as usize;
for (i, val) in write.iter().skip(1).enumerate() {
if reg + i < 256 {
state.registers[reg + i] = *val;
}
}
}
Ok(())
}
fn write_read(
&mut self,
_address: u8,
write: &[u8],
read: &mut [u8],
) -> Result<(), Self::Error> {
let state = self.state.lock().unwrap();
let reg = write[0] as usize;
for i in 0..read.len() {
if reg + i < 256 {
read[i] = state.registers[reg + i];
}
}
Ok(())
}
fn transaction(
&mut self,
_address: u8,
_operations: &mut [embedded_hal::i2c::Operation<'_>],
) -> Result<(), Self::Error> {
unimplemented!("Full I2C transactions are not implemented in this mock")
}
}