usb_pd/
pdo.rs

1use {
2    byteorder::{ByteOrder, LittleEndian},
3    defmt::Format,
4    proc_bitfield::bitfield,
5};
6
7#[derive(Clone, Copy, Format)]
8pub enum PowerDataObject {
9    FixedSupply(FixedSupply),
10    Battery(Battery),
11    VariableSupply(VariableSupply),
12    AugmentedPowerDataObject(AugmentedPowerDataObject),
13}
14
15bitfield! {
16    #[derive(Clone, Copy, PartialEq, Eq)]
17    pub struct PowerDataObjectRaw(pub u32): FromRaw, IntoRaw {
18        pub kind: u8 @ 30..=31,
19    }
20}
21
22bitfield! {
23    #[derive(Clone, Copy, PartialEq, Eq, Format)]
24    pub struct FixedSupply(pub u32): FromRaw, IntoRaw {
25        /// Fixed supply
26        pub kind: u8 @ 30..=31,
27        /// Dual-role power
28        pub dual_role_power: bool @ 29,
29        /// USB suspend supported
30        pub usb_suspend_supported: bool @ 28,
31        /// Unconstrained power
32        pub unconstrained_power: bool @ 27,
33        /// USB communications capable
34        pub usb_communications_capable: bool @ 26,
35        /// Dual-role data
36        pub dual_role_data: bool @ 25,
37        /// Unchunked extended messages supported
38        pub unchunked_extended_messages_supported: bool @ 24,
39        /// EPR mode capable
40        pub epr_mode_capable: bool @ 23,
41        /// Peak current
42        pub peak_current: u8 @ 20..=21,
43        /// Voltage in 50mV units
44        pub voltage: u16 @ 10..=19,
45        /// Maximum current in 10mA units
46        pub max_current: u16 @ 0..=9,
47    }
48}
49
50bitfield! {
51    #[derive(Clone, Copy, PartialEq, Eq, Format)]
52    pub struct Battery(pub u32): FromRaw, IntoRaw {
53        /// Battery
54        pub kind: u8 @ 30..=31,
55        /// Maximum Voltage in 50mV units
56        pub max_voltage: u16 @ 20..=29,
57        /// Minimum Voltage in 50mV units
58        pub min_voltage: u16 @ 10..=19,
59        /// Maximum Allowable Power in 250mW units
60        pub max_power: u16 @ 0..=9,
61    }
62}
63
64bitfield! {
65    #[derive(Clone, Copy, PartialEq, Eq, Format)]
66    pub struct VariableSupply(pub u32): FromRaw, IntoRaw {
67        /// Variable supply (non-battery)
68        pub kind: u8 @ 30..=31,
69        /// Maximum Voltage in 50mV units
70        pub max_voltage: u16 @ 20..=29,
71        /// Minimum Voltage in 50mV units
72        pub min_voltage: u16 @ 10..=19,
73        /// Maximum current in 10mA units
74        pub max_current: u16 @ 0..=9,
75    }
76}
77
78#[derive(Clone, Copy, Format)]
79pub enum AugmentedPowerDataObject {
80    SPR(SPRProgrammablePowerSupply),
81    EPR(EPRAdjustableVoltageSupply),
82}
83
84bitfield! {
85    #[derive(Clone, Copy, PartialEq, Eq, Format)]
86    pub struct AugmentedPowerDataObjectRaw(pub u32): FromRaw, IntoRaw {
87        /// Augmented power data object
88        pub kind: u8 @ 30..=31,
89        pub supply: u8 @ 28..=29,
90        pub power_capabilities: u32 @ 0..=27,
91    }
92}
93
94bitfield! {
95    #[derive(Clone, Copy, PartialEq, Eq, Format)]
96    pub struct SPRProgrammablePowerSupply(pub u32): FromRaw, IntoRaw {
97        /// Augmented power data object
98        pub kind: u8 @ 30..=31,
99        /// SPR programmable power supply
100        pub supply: u8 @ 28..=29,
101        pub pps_power_limited: bool @ 27,
102        /// Maximum voltage in 100mV increments
103        pub max_voltage: u8 @ 17..=24,
104        /// Minimum Voltage in 100mV increments
105        pub min_voltage: u8 @ 8..=15,
106        /// Maximum Current in 50mA increments
107        pub maximum_current: u8 @ 0..=6,
108    }
109}
110
111bitfield! {
112    #[derive(Clone, Copy, PartialEq, Eq, Format)]
113    pub struct EPRAdjustableVoltageSupply(pub u32): FromRaw, IntoRaw {
114        /// Augmented power data object
115        pub kind: u8 @ 30..=31,
116        /// EPR adjustable voltage supply
117        pub supply: u8 @ 28..=29,
118        pub peak_current: u8 @ 26..=27,
119        /// Maximum voltage in 100mV increments
120        pub max_voltage: u16 @ 17..=25,
121        /// Minimum Voltage in 100mV increments
122        pub min_voltage: u8 @ 8..=15,
123        /// PDP in 1W increments
124        pub maximum_current: u8 @ 0..=7,
125    }
126}
127
128bitfield! {
129    #[derive(Clone, Copy, PartialEq, Eq, Format)]
130    pub struct FixedVariableRequestDataObject(pub u32): FromRaw, IntoRaw {
131        /// Valid range 1..=14
132        pub object_position: u8 @ 28..=31,
133        pub giveback_flag: bool @ 27,
134        pub capability_mismatch: bool @ 26,
135        pub usb_communications_capable: bool @ 25,
136        pub no_usb_suspend: bool @ 24,
137        pub unchunked_extended_messages_supported: bool @ 23,
138        pub epr_mode_capable: bool @ 22,
139        pub operating_current: u16 @ 10..=19,
140        pub maximum_operating_current: u16 @ 0..=9,
141    }
142}
143
144impl FixedVariableRequestDataObject {
145    pub fn to_bytes(&self, buf: &mut [u8]) {
146        LittleEndian::write_u32(buf, self.0);
147    }
148}