This commit is contained in:
2025-10-26 08:56:59 -07:00
parent e0f17649b2
commit 5455935f3a
18 changed files with 180 additions and 68 deletions

View File

@@ -4,6 +4,7 @@ use crate::hardware::pin::{Pin, PinDevice};
use anyhow::Result;
use embedded_hal::digital::PinState;
use log::trace;
use std::any::type_name;
use std::fmt::Debug;
use std::time::Instant;
@@ -53,6 +54,7 @@ pub struct DevicePin<'a, Device: PinDevice> {
impl<'a, Device: PinDevice> Pin for DevicePin<'a, Device> {
fn set(&mut self, value: PinState, valid_until: Instant, priority: u8) {
trace!("ChannelPin<Device={}>::set(self, value: {value:?}, valid_until: {valid_until:?}, priority: {priority})", type_name::<Device>());
self.device.set_pin(self.pin, value, valid_until, priority);
}
}
@@ -64,6 +66,7 @@ pub enum ChannelPin<'a, A: PinDevice, B: PinDevice> {
impl<'a, A: PinDevice, B: PinDevice> Pin for ChannelPin<'a, A, B> {
fn set(&mut self, value: PinState, valid_until: Instant, priority: u8) {
trace!("ChannelPin<A={}, B={}>::set(self, value: {value:?}, valid_until: {valid_until:?}, priority: {priority})", type_name::<A>(), type_name::<B>());
match self {
ChannelPin::ExtA(pin) => pin.set(value, valid_until, priority),
ChannelPin::ExtB(pin) => pin.set(value, valid_until, priority),

View File

@@ -4,6 +4,7 @@ use anyhow::bail;
use embedded_hal::digital::PinState;
use embedded_hal::i2c::I2c;
use log::{error, trace};
use std::any::type_name;
use std::fmt::{Debug, Formatter};
use std::sync::Mutex;
@@ -28,7 +29,7 @@ where
I2C::Error: 'static,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Mcp23017Driver {{ address: {} }}", self.address)
write!(f, "Mcp23017Driver<I2C={}> {{ address: {} }}", type_name::<I2C>(), self.address)
}
}
@@ -40,7 +41,7 @@ where
I2C::Error: 'static,
{
pub fn new(i2c: I2C, address: u8) -> Self {
trace!("Mcp23017Driver::new(i2c, address: 0x{address:02x})");
trace!("Mcp23017Driver<I2C={}>::new(i2c, address: 0x{address:02x})", type_name::<I2C>());
Self {
i2c: i2c.into(),
address,

View File

@@ -18,7 +18,7 @@ pub enum Mcp23017Message {
},
}
impl PinDevice for TaskHandle<Mcp23017Message> {
impl<D: Debug> PinDevice for TaskHandle<Mcp23017Message, D> {
fn set_pin(&self, pin: u8, value: PinState, valid_until: Instant, priority: u8) {
trace!("Mcp23017Task::set_pin(self: {self:?}, pin: {pin}, value: {value:?})");
// This can only fail if the other end is disconnected - which we intentionally want to
@@ -32,11 +32,22 @@ impl PinDevice for TaskHandle<Mcp23017Message> {
}
}
#[derive(Default)]
#[derive(Debug, Default)]
pub struct Mcp23017State {
pub pins: [bool; 16],
}
#[derive(Debug, Clone)]
pub struct Mcp23017Data {
id: SectionIdentifier,
}
impl Mcp23017Data {
pub fn get_id(&self) -> SectionIdentifier {
self.id.clone()
}
}
pub struct Mcp23017Task<'a, M: Mcp23017> {
mcp23017: M,
pins: AllPins,
@@ -55,13 +66,14 @@ struct AllPins {
impl AllPins {
fn new() -> Self {
trace!("AllPins::new()");
Self {
pins: [PinData::new(); _],
}
}
}
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
struct PinData {
state: PinState,
valid_until: Option<Instant>,
@@ -76,6 +88,7 @@ struct PinData {
impl PinData {
fn new() -> Self {
trace!("PinData::new()");
Self {
state: PinState::Low,
valid_until: None,
@@ -90,6 +103,7 @@ impl PinData {
}
fn evaluate(&mut self, now: Instant) {
trace!("PinData::evaluate(self: {self:?}, now: {now:?})");
// Do this twice to check both the current and the current next
// If the current is currently invalid, we'd upgrade the next to current
for _ in 0..2 {
@@ -114,6 +128,7 @@ impl PinData {
}
fn set(&mut self, value: PinState, valid_until: Instant, priority: u8) {
trace!("PinData::set(self: {self:?}, value: {value:?}, valid_until: {valid_until:?}, priority: {priority})");
let can_replace_current = self.valid_until.map(|current| current <= valid_until).unwrap_or(true);
let can_replace_next = self.next_validity.map(|next| next <= valid_until).unwrap_or(true);
@@ -158,20 +173,25 @@ impl<'a, M: Mcp23017 + Debug> Mcp23017Task<'a, M> {
state: state_vector.create_section(Mcp23017State::default()),
}
}
pub fn get_state(&self) -> SectionIdentifier {
self.state.get_identifier()
}
}
impl<M: Mcp23017> CyclicTask for Mcp23017Task<'_, M> {
impl<M: Mcp23017 + Debug> CyclicTask for Mcp23017Task<'_, M> {
type Message = Mcp23017Message;
type Data = Mcp23017Data;
fn get_data(&self) -> Self::Data {
trace!("Mcp23017Task::get_data(self: {self:?})");
Self::Data {
id: self.state.get_identifier()
}
}
fn step(
&mut self,
receiver: &Receiver<Self::Message>,
step_time: Instant,
) {
trace!("Mcp23017Task::step(self: {self:?}, receiver, step_time: {step_time:?})");
let mut changed = false;
for pin in 0u8..16u8 {

View File

@@ -2,6 +2,7 @@ use crate::hardware::error::WrappingError;
use anyhow::{ensure, Result};
use embedded_hal::spi::SpiDevice;
use log::trace;
use std::any::type_name;
use std::fmt::{Debug, Formatter};
pub struct Mcp3208<SPI> {
@@ -11,7 +12,7 @@ pub struct Mcp3208<SPI> {
impl<SPI> Debug for Mcp3208<SPI> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Mcp3208 {{ vref: {} }}", self.vref)
write!(f, "Mcp3208<SPI={}> {{ vref: {} }}", type_name::<SPI>(), self.vref)
}
}
@@ -23,7 +24,7 @@ where
SPI::Error: 'static,
{
pub fn new(spi: SPI, vref: f64) -> Self {
trace!("Mcp3208::new(spi, vref: {vref})");
trace!("Mcp3208<SPI={}>::new(spi, vref: {vref})", type_name::<SPI>());
Self {
spi,
vref,

View File

@@ -15,6 +15,7 @@ use crate::hardware::mct8316a::Mct8316a;
use anyhow::{bail, ensure, Result};
use embedded_hal::i2c::{I2c, Operation};
use log::trace;
use std::any::type_name;
use std::fmt::{Debug, Display, Formatter};
use std::sync::Mutex;
@@ -38,6 +39,7 @@ impl Display for Mct8316AVData {
}
}
#[derive(Debug)]
enum OperationRW {
Read,
Write,
@@ -49,6 +51,7 @@ fn control_word(
data: Mct8316AVData,
address: u32,
) -> [u8; 3] {
trace!("control_word(operation_rw: {operation_rw:?}, crc: {crc}, data: {data}, address: {address:06x})");
let mut control_word = [0u8; _];
control_word[0] |= match operation_rw {
@@ -90,7 +93,7 @@ where
I2C::Error: 'static,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Mct8316AVDriver {{ address: {} }}", self.address)
write!(f, "Mct8316AVDriver<I2C={}> {{ address: {} }}", type_name::<I2C>(), self.address)
}
}
@@ -102,7 +105,7 @@ where
I2C::Error: 'static,
{
pub fn new(i2c: I2C, address: u8) -> Self {
trace!("Mct8316AVDriver::new(i2c, address: 0x{address:02x})");
trace!("Mct8316AVDriver<I2C={}>::new(i2c, address: 0x{address:02x})", type_name::<I2C>());
Self {
i2c: i2c.into(),
address,

View File

@@ -14,6 +14,8 @@ use crate::hardware::mct8316a::Mct8316AVDriver;
use anyhow::Result;
use embedded_hal::i2c::I2c;
use log::trace;
use std::any::type_name;
use std::fmt::{Debug, Formatter};
use std::thread::sleep;
use std::time::Duration;
@@ -28,6 +30,18 @@ where
modified: bool,
}
impl<'a, I2C> Debug for Mct8316AVEeprom<'a, I2C>
where
I2C: I2c + Send + Sync,
I2C::Error: Send,
I2C::Error: Sync,
I2C::Error: 'static,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Mct8316AVEeprom<I2C={}> {{ driver: {:?}, modified: {} }}", type_name::<I2C>(), self.driver, self.modified)
}
}
impl<'a, I2C> Mct8316AVEeprom<'a, I2C>
where
I2C: I2c + Send + Sync,
@@ -36,7 +50,7 @@ where
I2C::Error: 'static,
{
pub fn load(driver: &'a mut Mct8316AVDriver<I2C>) -> Result<Self> {
trace!("Mct8316AVEeprom::load()");
trace!("Mct8316AVEeprom<I2C={}>::load(driver: {driver:?})", type_name::<I2C>());
driver.write(0x0000E6, Mct8316AVData::Four(0x40000000))?;
// Wait 100ms for the EEPROM operation to complete
@@ -49,7 +63,7 @@ where
}
pub fn set_isd_config(self, isd_config: IsdConfig) -> Result<Self> {
trace!("Mct8316AVEeprom::set_isd_config(isd_config: {isd_config:?})");
trace!("Mct8316AVEeprom::set_isd_config(self: {self:?}, isd_config: {isd_config:?})");
let expected_value =
if isd_config.enable_isd { 0x40000000 } else { 0 }
@@ -71,7 +85,7 @@ where
}
pub fn set_motor_startup1(self, motor_startup1: MotorStartup1) -> Result<Self> {
trace!("Mct8316AVEeprom::set_motor_startup1(motor_startup1: {motor_startup1:?})");
trace!("Mct8316AVEeprom::set_motor_startup1(self: {self:?}, motor_startup1: {motor_startup1:?})");
let expected_value =
((motor_startup1.motor_startup_method as u32) & 0x3) << 29
@@ -89,7 +103,7 @@ where
}
pub fn set_motor_startup2(self, motor_startup2: MotorStartup2) -> Result<Self> {
trace!("Mct8316AVEeprom::set_motor_startup2(motor_startup2: {motor_startup2:?})");
trace!("Mct8316AVEeprom::set_motor_startup2(self: {self:?}, motor_startup2: {motor_startup2:?})");
let expected_value =
((motor_startup2.open_loop_current_limit_mode as u32) & 0x1) << 30
@@ -106,7 +120,7 @@ where
}
pub fn set_closed_loop1(self, closed_loop1: ClosedLoop1) -> Result<Self> {
trace!("Mct8316AVEeprom::set_closed_loop1(closed_loop1: {closed_loop1:?})");
trace!("Mct8316AVEeprom::set_closed_loop1(self: {self:?}, closed_loop1: {closed_loop1:?})");
let lead_angle = (closed_loop1.lead_angle / 0.12f32).round().clamp(0.0f32, u8::MAX as f32) as u8;
@@ -125,7 +139,7 @@ where
}
pub fn set_closed_loop2(self, closed_loop2: ClosedLoop2) -> Result<Self> {
trace!("Mct8316AVEeprom::set_closed_loop2(closed_loop2: {closed_loop2:?})");
trace!("Mct8316AVEeprom::set_closed_loop2(self: {self:?}, closed_loop2: {closed_loop2:?})");
let expected_value =
((closed_loop2.speed_feedback_mode as u32) & 0x2) << 29
@@ -143,7 +157,7 @@ where
}
pub fn set_closed_loop3(self, closed_loop3: ClosedLoop3) -> Result<Self> {
trace!("Mct8316AVEeprom::set_closed_loop3(closed_loop3: {closed_loop3:?})");
trace!("Mct8316AVEeprom::set_closed_loop3(self: {self:?}, closed_loop3: {closed_loop3:?})");
let expected_value =
((closed_loop3.degauss_samples as u32) & 0x2) << 29
@@ -163,7 +177,7 @@ where
}
pub fn set_closed_loop4(self, closed_loop4: ClosedLoop4) -> Result<Self> {
trace!("Mct8316AVEeprom::set_closed_loop4(closed_loop4: {closed_loop4:?})");
trace!("Mct8316AVEeprom::set_closed_loop4(self: {self:?}, closed_loop4: {closed_loop4:?})");
let expected_value =
if closed_loop4.wcomp_blanking_enable { 1u32 << 19 } else { 0u32 }
@@ -179,7 +193,7 @@ where
}
pub fn set_constant_speed(self, constant_speed: ConstantSpeed) -> Result<Self> {
trace!("Mct8316AVEeprom::set_constant_speed(constant_speed: {constant_speed:?})");
trace!("Mct8316AVEeprom::set_constant_speed(self: {self:?}, constant_speed: {constant_speed:?})");
let speed_power_kp = (constant_speed.speed_power_kp * 10000f64).round().clamp(0.0f64, 0x3FF as f64) as u32;
let speed_power_ki = (constant_speed.speed_power_ki * 1000000f64).round().clamp(0.0f64, 0xFFF as f64) as u32;
@@ -195,7 +209,7 @@ where
}
pub fn set_constant_power(self, constant_power: ConstantPower) -> Result<Self> {
trace!("Mct8316AVEeprom::set_constant_power(constant_power: {constant_power:?})");
trace!("Mct8316AVEeprom::set_constant_power(self: {self:?}, constant_power: {constant_power:?})");
let max_speed = (constant_power.max_speed * 16f64).round().clamp(0.0f64, 0xFFFF as f64) as u32;
let max_power = (constant_power.max_power * 4f64).round().clamp(0.0f64, 0x3FF as f64) as u32;
@@ -211,7 +225,7 @@ where
}
pub fn set_two_phase_profile(self, profile: TwoPhase150DegreeProfile) -> Result<Self> {
trace!("Mct8316AVEeprom::set_two_phase_profile(profile: {profile:?})");
trace!("Mct8316AVEeprom::set_two_phase_profile(self: {self:?}, profile: {profile:?})");
let expected_value =
((profile.steps[0] as u32) & 0x7) << 28
@@ -227,7 +241,7 @@ where
}
pub fn set_three_phase_profile(self, profile: ThreePhase150DegreeProfile) -> Result<Self> {
trace!("Mct8316AVEeprom::set_three_phase_profile(profile: {profile:?})");
trace!("Mct8316AVEeprom::set_three_phase_profile(self: {self:?}, profile: {profile:?})");
let expected_value =
((profile.steps[0] as u32) & 0x7) << 28
@@ -244,7 +258,7 @@ where
}
pub fn set_trap_config1(self, trap_config1: TrapConfig1) -> Result<Self> {
trace!("Mct8316AVEeprom::set_trap_config1(trap_config1: {trap_config1:?})");
trace!("Mct8316AVEeprom::set_trap_config1(self: {self:?}, trap_config1: {trap_config1:?})");
let expected_value =
((trap_config1.open_loop_handoff_cycles as u32) & 0x3) << 22
@@ -260,7 +274,7 @@ where
}
pub fn set_trap_config2(self, trap_config2: TrapConfig2) -> Result<Self> {
trace!("Mct8316AVEeprom::set_trap_config2(trap_config2: {trap_config2:?})");
trace!("Mct8316AVEeprom::set_trap_config2(self: {self:?}, trap_config2: {trap_config2:?})");
let expected_value =
((trap_config2.blanking_time_microseconds as u32) & 0xF) << 27
@@ -271,7 +285,7 @@ where
}
pub fn set_fault_config1(self, fault_config1: FaultConfig1) -> Result<Self> {
trace!("Mct8316AVEeprom::set_fault_config1(fault_config1: {fault_config1:?})");
trace!("Mct8316AVEeprom::set_fault_config1(self: {self:?}, fault_config1: {fault_config1:?})");
let expected_value =
((fault_config1.no_motor_detect_deglitch_time as u32) & 0x7) << 27
@@ -287,7 +301,7 @@ where
}
pub fn set_fault_config2(self, fault_config2: FaultConfig2) -> Result<Self> {
trace!("Mct8316AVEeprom::set_fault_config2(fault_config2: {fault_config2:?})");
trace!("Mct8316AVEeprom::set_fault_config2(self: {self:?}, fault_config2: {fault_config2:?})");
let expected_value =
if fault_config2.lock_abnormal_speed_enable { 1u32 << 30 } else { 0u32 }
@@ -309,7 +323,7 @@ where
}
pub fn set_pin_config1(self, pin_config1: PinConfig1) -> Result<Self> {
trace!("Mct8316AVEeprom::set_pin_config1(pin_config1: {pin_config1:?})");
trace!("Mct8316AVEeprom::set_pin_config1(self: {self:?}, pin_config1: {pin_config1:?})");
let expected_value =
((pin_config1.dacout1_address as u32) & 0xFFF) << 19
@@ -322,7 +336,7 @@ where
}
pub fn set_pin_config2(self, pin_config2: PinConfig2) -> Result<Self> {
trace!("Mct8316AVEeprom::set_pin_config2(pin_config2: {pin_config2:?})");
trace!("Mct8316AVEeprom::set_pin_config2(self: {self:?}, pin_config2: {pin_config2:?})");
let expected_value =
((pin_config2.pin36config as u32) & 0x3) << 29
@@ -337,7 +351,7 @@ where
}
pub fn set_device_config(self, device_config: DeviceConfig) -> Result<Self> {
trace!("Mct8316AVEeprom::set_device_config(device_config: {device_config:?})");
trace!("Mct8316AVEeprom::set_device_config(self: {self:?}, device_config: {device_config:?})");
let expected_value =
((device_config.max_frequency as u32) & 0x7FFF) << 16
@@ -353,7 +367,7 @@ where
}
pub fn set_gate_driver_config1(self, gate_driver_config1: GateDriverConfig1) -> Result<Self> {
trace!("Mct8316AVEeprom::set_gate_driver_config1(gate_driver_config1: {gate_driver_config1:?})");
trace!("Mct8316AVEeprom::set_gate_driver_config1(self: {self:?}, gate_driver_config1: {gate_driver_config1:?})");
let expected_value =
((gate_driver_config1.slew_rate as u32) & 0x3) << 26
@@ -374,7 +388,7 @@ where
}
pub fn set_gate_driver_config2(self, gate_driver_config2: GateDriverConfig2) -> Result<Self> {
trace!("Mct8316AVEeprom::set_gate_driver_config2(gate_driver_config2: {gate_driver_config2:?})");
trace!("Mct8316AVEeprom::set_gate_driver_config2(self: {self:?}, gate_driver_config2: {gate_driver_config2:?})");
let expected_value =
if gate_driver_config2.driver_delay_compensation_enable { 1u32 << 30 } else { 0u32 }
@@ -389,7 +403,7 @@ where
}
fn assert_register(self, address: u32, value: Mct8316AVData) -> Result<Self> {
trace!("Mct8316AVEeprom::assert_register(address: {address:06x}, value: {value})");
trace!("Mct8316AVEeprom::assert_register(self: {self:?}, address: {address:06x}, value: {value})");
let mut read_value = value.clone();
@@ -412,7 +426,7 @@ where
}
pub fn commit(self) -> Result<()> {
trace!("Mct8316AVEeprom::commit()");
trace!("Mct8316AVEeprom::commit(self: {self:?})");
if self.modified {
self.driver.write(0x0000E6, Mct8316AVData::Four(0x80000000))?;
// Wait for EEPROM operation to complete

View File

@@ -2,6 +2,7 @@ use crate::hardware::mcp23017::Mcp23017;
use crate::hardware::mct8316a::Mct8316a;
use anyhow::Result;
use embedded_hal::pwm::SetDutyCycle;
use log::trace;
use std::fmt::Debug;
pub trait Hardware {
@@ -25,12 +26,14 @@ mod raspi;
#[cfg(feature = "raspi")]
pub fn initialize() -> Result<impl Hardware> {
trace!("initialize()");
raspi::RaspiHardware::new()
}
#[cfg(not(feature = "raspi"))]
#[allow(unreachable_code)]
pub fn initialize() -> Result<impl Hardware> {
trace!("initialize()");
Ok(sim::SimHardware::new())
}

View File

@@ -19,6 +19,7 @@ use std::sync::Mutex;
const CLOCK_1MHZ: u32 = 1_000_000;
#[derive(Debug)]
pub struct RaspiHardware {
_gpio: Gpio,
i2c_bus: Mutex<I2c>,
@@ -54,17 +55,17 @@ impl Hardware for RaspiHardware {
type Pwm = PwmWrapper;
fn new_mcp23017_a(&self) -> Result<Self::Mcp23017<'_>> {
trace!("RaspiHardware::new_mcp23017_a()");
trace!("RaspiHardware::new_mcp23017_a(self: {self:?})");
Ok(Mcp23017Driver::new(MutexDevice::new(&self.i2c_bus), 0b0100000))
}
fn new_mcp23017_b(&self) -> Result<Self::Mcp23017<'_>> {
trace!("RaspiHardware::new_mcp23017_b()");
trace!("RaspiHardware::new_mcp23017_b(self: {self:?})");
Ok(Mcp23017Driver::new(MutexDevice::new(&self.i2c_bus), 0b0100001))
}
fn new_pwm0(&self) -> Result<Self::Pwm> {
trace!("RaspiHardware::new_pwm0()");
trace!("RaspiHardware::new_pwm0(self: {self:?})");
// Unfortunately the current version of rpi_pal assumes an older version
// of the kernel where pwmchip for RPi5 was 2
const PWMCHIP: u8 = 0;
@@ -73,13 +74,13 @@ impl Hardware for RaspiHardware {
}
fn new_mct8316a(&self) -> Result<impl Mct8316a + Sync> {
trace!("RaspiHardware::new_mct8316a()");
trace!("RaspiHardware::new_mct8316a(self: {self:?})");
Ok(Mct8316AVDriver::new(MutexDevice::new(&self.mct8316a), 0b0000000))
}
fn get_battery_voltage(&self) -> Result<f64> {
trace!("RaspiHardware::get_battery_voltage()");
trace!("RaspiHardware::get_battery_voltage(self: {self:?})");
self.mcp3208.borrow_mut().read_single(1)
}
}

View File

@@ -6,6 +6,7 @@ use std::time::Duration;
const PWM_PERIOD: Duration = Duration::from_micros(1000); // 1kHz
#[derive(Debug)]
pub struct PwmWrapper {
pwm: Pwm,
}
@@ -28,12 +29,12 @@ impl ErrorType for PwmWrapper {
impl SetDutyCycle for PwmWrapper {
fn max_duty_cycle(&self) -> u16 {
trace!("PwmWrapper::max_duty_cycle()");
trace!("PwmWrapper::max_duty_cycle(self: {self:?})");
u16::MAX
}
fn set_duty_cycle(&mut self, duty: u16) -> Result<(), Self::Error> {
trace!("PwmWrapper::set_duty_cycle(duty: {duty})");
trace!("PwmWrapper::set_duty_cycle(self: {self:?}, duty: {duty})");
self.pwm.set_duty_cycle((duty as f64) / (u16::MAX as f64)).map_err(WrappingError)
}
}

View File

@@ -9,6 +9,7 @@ use embedded_hal_bus::i2c::MutexDevice;
use log::trace;
use std::sync::Mutex;
#[derive(Debug)]
pub struct SimHardware {
mcp23017a: Mutex<SimMcp23017>,
mcp23017b: Mutex<SimMcp23017>,
@@ -18,6 +19,7 @@ pub struct SimHardware {
impl SimHardware {
pub fn new() -> Self {
trace!("SimHardware::new()");
Self {
mcp23017a: SimMcp23017::new().into(),
mcp23017b: SimMcp23017::new().into(),
@@ -32,26 +34,27 @@ impl Hardware for SimHardware {
type Pwm = SimPwm;
fn new_mcp23017_a(&self) -> Result<Self::Mcp23017<'_>> {
trace!("SimHardware::new_mcp23017_a()");
trace!("SimHardware::new_mcp23017_a(self: {self:?})");
Ok(Mcp23017Driver::new(MutexDevice::new(&self.mcp23017a), 0b0100000))
}
fn new_mcp23017_b(&self) -> Result<Self::Mcp23017<'_>> {
trace!("SimHardware::new_mcp23017_b()");
trace!("SimHardware::new_mcp23017_b(self: {self:?})");
Ok(Mcp23017Driver::new(MutexDevice::new(&self.mcp23017b), 0b0100000))
}
fn new_pwm0(&self) -> Result<Self::Pwm> {
trace!("SimHardware::new_pwm0()");
trace!("SimHardware::new_pwm0(self: {self:?})");
Ok(SimPwm::new())
}
fn new_mct8316a(&self) -> Result<impl Mct8316a + Sync> {
trace!("SimHardware::new_mct8316a()");
trace!("SimHardware::new_mct8316a(self: {self:?})");
Ok(Mct8316AVDriver::new(MutexDevice::new(&self.mct8316a), 0b0000000))
}
fn get_battery_voltage(&self) -> Result<f64> {
trace!("SimHardware::get_battery_voltage(self: {self:?})");
Ok(self.battery_voltage)
}
}

View File

@@ -1,10 +1,13 @@
use embedded_hal::i2c::{ErrorKind, ErrorType, I2c, Operation, SevenBitAddress};
use log::trace;
use std::fmt::{Display, Formatter};
#[derive(Debug)]
pub struct SimMcp23017 {}
impl SimMcp23017 {
pub fn new() -> Self {
trace!("SimMcp23017::new()");
Self {}
}
}
@@ -32,6 +35,7 @@ impl ErrorType for SimMcp23017 {
impl I2c for SimMcp23017 {
fn transaction(&mut self, _address: SevenBitAddress, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
trace!("SimMcp23017::transaction(self: {self:?}, _address: {_address}, operations: {operations:?})");
for operation in operations {
match operation {
Operation::Write(_write_buffer) => {

View File

@@ -1,16 +1,19 @@
use crate::hardware::error::WrappingError;
use anyhow::anyhow;
use embedded_hal::i2c::{ErrorType, I2c, Operation, SevenBitAddress};
use log::trace;
use std::collections::HashMap;
const CRC: crc::Crc<u8> = crc::Crc::<u8>::new(&crc::CRC_8_SMBUS);
#[derive(Debug)]
pub struct SimMct8316a {
data: HashMap<u32, u32>,
}
impl SimMct8316a {
pub fn new() -> Self {
trace!("SimMct8316a::new()");
Self {
data: HashMap::new(),
}
@@ -23,6 +26,7 @@ impl ErrorType for SimMct8316a {
impl I2c for SimMct8316a {
fn transaction(&mut self, i2c_addr: SevenBitAddress, operations: &mut [Operation<'_>]) -> Result<(), Self::Error> {
trace!("SimMct8316a::transaction(self: {self:?}, i2c_addr: {i2c_addr}, operations: {operations:?})");
let mut do_read_operation = false;
let mut include_crc = false;
let mut data_length = 2;

View File

@@ -2,12 +2,14 @@ use embedded_hal::pwm::{ErrorKind, ErrorType, SetDutyCycle};
use log::trace;
use std::fmt::{Display, Formatter};
#[derive(Debug)]
pub struct SimPwm {
duty_cycle: u16,
}
impl SimPwm {
pub fn new() -> Self {
trace!("SimPwm::new()");
Self {
duty_cycle: 0,
}