ap33772s_rs/commands/data_objects/
extended_power_range_data_object.rs1use crate::commands::data_objects::source_power_range_data_object::{
2 PeakCurrent, PowerType, SourceMaximumCurrent,
3};
4use crate::errors::Ap33772sError;
5use crate::units::*;
6use arbitrary_int::u2;
7use bitbybit::bitfield;
8
9#[bitfield(u16, default = 0x00, defmt_bitfields(feature = "defmt"))]
13#[derive(Debug, PartialEq)]
14pub struct ExtendedPowerRangeDataObject {
15 #[bits(0..=7, r)]
16 pub raw_max_voltage: u8,
17 #[bits(8..=9, r)]
18 pub minimum_voltage_or_peak_current: u2,
19 #[bits(10..=13, r)]
20 pub max_current: SourceMaximumCurrent,
21 #[bit(14, r)]
22 pub source_power_type: PowerType,
23 #[bit(15, r)]
24 pub is_detected: bool,
25}
26impl ExtendedPowerRangeDataObject {
37 pub const VOLTAGE_RESOLUTION: u16 = 200;
39 pub const ABSOLUTE_MAXIMUM_VOLTAGE: u16 = 28000;
43
44 pub fn max_voltage(&self) -> Result<ElectricPotential, Ap33772sError> {
46 let scaled_voltage = u16::from(self.raw_max_voltage())
47 .checked_mul(Self::VOLTAGE_RESOLUTION)
48 .ok_or(Ap33772sError::ConversionFailed)?;
49 Ok(ElectricPotential::new::<millivolt>(f32::from(
50 scaled_voltage,
51 )))
52 }
53 pub fn peak_current(&self) -> Option<PeakCurrent> {
55 match self.source_power_type() {
56 PowerType::Fixed => Some(PeakCurrent::from(self.minimum_voltage_or_peak_current())),
57 PowerType::Adjustable => None,
58 }
59 }
60 pub fn minimum_voltage(&self) -> Option<MinimumVoltage> {
63 match self.source_power_type() {
64 PowerType::Fixed => None,
65 PowerType::Adjustable => {
66 Some(MinimumVoltage::from(self.minimum_voltage_or_peak_current()))
67 }
68 }
69 }
70}
71
72#[derive(Debug, PartialEq)]
74#[cfg_attr(feature = "defmt", derive(defmt::Format))]
75pub enum MinimumVoltage {
76 Reserved = 0,
77 Fifteen = 1,
78 FifteenLessThanVoltageMinimumLessThanTwenty = 2,
79 Others = 3,
80}
81
82impl From<u2> for MinimumVoltage {
83 fn from(value: u2) -> Self {
84 match value.value() {
85 0 => MinimumVoltage::Reserved,
86 1 => MinimumVoltage::Fifteen,
87 2 => MinimumVoltage::FifteenLessThanVoltageMinimumLessThanTwenty,
88 3 => MinimumVoltage::Others,
89 _ => unreachable!("This will never happen due to rust type safety"),
90 }
91 }
92}
93
94impl core::fmt::Display for ExtendedPowerRangeDataObject {
95 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
96 write!(
97 f,
98 "ExtendedPowerRangeDataObject {{ max_voltage: {:?}, minimum_voltage: {:?}, peak_current: {:?}, max_current: {:?}, source_power_type: {:?}, is_detected: {} }}",
99 self.max_voltage()
100 .unwrap_or(ElectricPotential::new::<millivolt>(f32::NEG_INFINITY))
101 .get::<volt>(),
102 self.minimum_voltage(),
103 self.peak_current(),
104 self.max_current(),
105 self.source_power_type(),
106 self.is_detected()
107 )
108 }
109}