1use {
2 crate::{DataRole, PowerRole},
3 byteorder::{ByteOrder, LittleEndian},
4 defmt::Format,
5 proc_bitfield::bitfield,
6};
7
8bitfield! {
9 #[derive(Clone, Copy, PartialEq, Eq)]
10 pub struct Header(pub u16): FromRaw, IntoRaw {
11 pub extended: bool @ 15,
12 pub num_objects: u8 [get usize] @ 12..=14,
13 pub message_id: u8 @ 9..=11,
14 pub port_power_role: bool [get PowerRole, set PowerRole] @ 8,
15 pub spec_revision: u8 [get SpecificationRevision, set SpecificationRevision] @ 6..=7,
16 pub port_data_role: bool [get DataRole, set DataRole] @ 5,
17 pub message_type_raw: u8 @ 0..4,
18 }
19}
20
21impl Header {
22 pub fn from_bytes(buf: &[u8]) -> Self {
23 assert!(buf.len() == 2);
24
25 Header(LittleEndian::read_u16(buf))
26 }
27
28 pub fn to_bytes(&self, buf: &mut [u8]) {
29 LittleEndian::write_u16(buf, self.0);
30 }
31
32 pub fn message_type(&self) -> MessageType {
33 if self.num_objects() == 0 {
34 MessageType::Control(self.message_type_raw().into())
35 } else {
36 MessageType::Data(self.message_type_raw().into())
37 }
38 }
39}
40
41#[derive(Format)]
42pub enum SpecificationRevision {
43 R1_0,
44 R2_0,
45 R3_0,
46}
47
48impl From<u8> for SpecificationRevision {
49 fn from(value: u8) -> Self {
50 match value {
51 0b00 => Self::R1_0,
52 0b01 => Self::R2_0,
53 0b10 => Self::R3_0,
54 _ => unimplemented!(),
55 }
56 }
57}
58
59impl From<SpecificationRevision> for u8 {
60 fn from(value: SpecificationRevision) -> Self {
61 match value {
62 SpecificationRevision::R1_0 => 0b00,
63 SpecificationRevision::R2_0 => 0b01,
64 SpecificationRevision::R3_0 => 0b10,
65 }
66 }
67}
68
69#[derive(Clone, Copy, PartialEq, Eq)]
70pub enum MessageType {
71 Control(ControlMessageType),
72 Data(DataMessageType),
73}
74
75#[derive(Clone, Copy, PartialEq, Eq)]
76pub enum ControlMessageType {
77 GoodCRC = 0b0_0001,
78 GotoMin = 0b0_0010,
79 Accept = 0b0_0011,
80 Reject = 0b0_0100,
81 Ping = 0b0_0101,
82 PsRdy = 0b0_0110,
83 GetSourceCap = 0b0_0111,
84 GetSinkCap = 0b0_1000,
85 DrSwap = 0b0_1001,
86 PrSwap = 0b0_1010,
87 VconnSwap = 0b0_1011,
88 Wait = 0b0_1100,
89 SoftReset = 0b0_1101,
90 DataReset = 0b0_1110,
91 DataResetComplete = 0b0_1111,
92 NotSupported = 0b1_0000,
93 GetSourceCapExtended = 0b1_0001,
94 GetStatus = 0b1_0010,
95 FrSwap = 0b1_0011,
96 GetPpsStatus = 0b1_0100,
97 GetCountryCodes = 0b1_0101,
98 GetSinkCapExtended = 0b1_0110,
99 GetSourceInfo = 0b1_0111,
100 GetRevision = 0b1_1000,
101 Reserved,
102}
103
104impl From<u8> for ControlMessageType {
105 fn from(value: u8) -> Self {
106 match value {
107 0b0_0001 => Self::GoodCRC,
108 0b0_0010 => Self::GotoMin,
109 0b0_0011 => Self::Accept,
110 0b0_0100 => Self::Reject,
111 0b0_0101 => Self::Ping,
112 0b0_0110 => Self::PsRdy,
113 0b0_0111 => Self::GetSourceCap,
114 0b0_1000 => Self::GetSinkCap,
115 0b0_1001 => Self::DrSwap,
116 0b0_1010 => Self::PrSwap,
117 0b0_1011 => Self::VconnSwap,
118 0b0_1100 => Self::Wait,
119 0b0_1101 => Self::SoftReset,
120 0b0_1110 => Self::DataReset,
121 0b0_1111 => Self::DataResetComplete,
122 0b1_0000 => Self::NotSupported,
123 0b1_0001 => Self::GetSourceCapExtended,
124 0b1_0010 => Self::GetStatus,
125 0b1_0011 => Self::FrSwap,
126 0b1_0100 => Self::GetPpsStatus,
127 0b1_0101 => Self::GetCountryCodes,
128 0b1_0110 => Self::GetSinkCapExtended,
129 0b1_0111 => Self::GetSourceInfo,
130 0b1_1000 => Self::GetRevision,
131 _ => Self::Reserved,
132 }
133 }
134}
135
136#[derive(Clone, Copy, PartialEq, Eq)]
137pub enum DataMessageType {
138 SourceCapabilities = 0b0_0001,
139 Request = 0b0_0010,
140 Bist = 0b0_0011,
141 SinkCapabilities = 0b0_0100,
142 BatteryStatus = 0b0_0101,
143 Alert = 0b0_0110,
144 GetCountryInfo = 0b0_0111,
145 EnterUsb = 0b0_1000,
146 EprRequest = 0b0_1001,
147 EprMode = 0b0_1010,
148 SourceInfo = 0b0_1011,
149 Revision = 0b0_1100,
150 VendorDefined = 0b0_1111,
151 Reserved,
152}
153
154impl From<u8> for DataMessageType {
155 fn from(value: u8) -> Self {
156 match value {
157 0b0_0001 => Self::SourceCapabilities,
158 0b0_0010 => Self::Request,
159 0b0_0011 => Self::Bist,
160 0b0_0100 => Self::SinkCapabilities,
161 0b0_0101 => Self::BatteryStatus,
162 0b0_0110 => Self::Alert,
163 0b0_0111 => Self::GetCountryInfo,
164 0b0_1000 => Self::EnterUsb,
165 0b0_1001 => Self::EprRequest,
166 0b0_1010 => Self::EprMode,
167 0b0_1011 => Self::SourceInfo,
168 0b0_1100 => Self::Revision,
169 0b0_1111 => Self::VendorDefined,
170 _ => Self::Reserved,
171 }
172 }
173}