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