77//
88
99#include < Arduino.h>
10- #include " USBPDProtocolAnalyzer.h"
11- #include " PDSourceCapability.h"
10+ #include " PDProtocolAnalyzer.h"
1211#include " PDController.h"
1312
14-
1513static const char * const ControlMessageNames[] = {
1614 [0 ] = nullptr ,
1715 [(int )PDMessageType::controlGoodCrc] = " GoodCRC" ,
@@ -57,37 +55,6 @@ static const char* const DataMessageNames[] = {
5755 [(int )PDMessageType::dataVendorDefined - 0x80 ] = " Vendor Defined" ,
5856};
5957
60- static const char * getMessageName (PDMessageType messageType) {
61- unsigned int index = (unsigned int )messageType;
62- const char * name = nullptr ;
63- if (index < 0x80 ) {
64- constexpr unsigned int arraySize = sizeof (ControlMessageNames) / sizeof (ControlMessageNames[0 ]);
65- if (index < arraySize)
66- name = ControlMessageNames[index];
67- } else {
68- index -= 0x80 ;
69- constexpr unsigned int arraySize = sizeof (DataMessageNames) / sizeof (DataMessageNames[0 ]);
70- if (index < arraySize)
71- name = DataMessageNames[index];
72- }
73- return name != nullptr ? name : " <unknown>" ;
74- }
75-
76- static const char * const SupplyTypeNames[] = {
77- [(int )PDSupplyType::fixed] = " Fixed" ,
78- [(int )PDSupplyType::battery] = " Battery" ,
79- [(int )PDSupplyType::variable] = " Variable" ,
80- [(int )PDSupplyType::pps] = " PPS" ,
81- };
82-
83- static const char * getSupplyTypeName (PDSupplyType type) {
84- constexpr unsigned int arraySize = sizeof (SupplyTypeNames) / sizeof (SupplyTypeNames[0 ]);
85- if ((unsigned int )type < arraySize)
86- return SupplyTypeNames[(unsigned int )type];
87- else
88- return " <unknown>" ;
89- }
90-
9158static const char * const SOPSequenceNames[] = {
9259 [0 ] = " INV" ,
9360 [(int )PDSOPSequence::sop] = " SOP" ,
@@ -97,33 +64,11 @@ static const char* const SOPSequenceNames[] = {
9764 [(int )PDSOPSequence::sop2Debug] = " SOP2D" ,
9865};
9966
100- static const char * getSOPSequenceName (PDSOPSequence sequence) {
101- constexpr unsigned int arraySize = sizeof (SOPSequenceNames) / sizeof (SOPSequenceNames[0 ]);
102- unsigned int index = (unsigned int )sequence;
103- if (index >= arraySize)
104- index = arraySize;
105- return SOPSequenceNames[index];
106- }
107-
108- static const char * getSender (const PDMessage* message) {
109- auto seq = message->sopSequence ;
110- if (seq == PDSOPSequence::sop) {
111- return (message->header & 0x0100 ) != 0 ? " Source" : " Sink" ;
112- } else if (seq == PDSOPSequence::sop1 || seq == PDSOPSequence::sop2) {
113- return (message->header & 0x0100 ) != 0 ? " Cable" : " Port" ;
114- }
11567
116- return " " ;
117- }
68+ USBPDProtocolAnalyzer PDProtocolAnalyzer;
11869
119- static void printMessage (const PDMessage* message) {
120- Serial.printf (" CC%d %-5s %-7s %-20s %d %04x" ,
121- message->cc , getSOPSequenceName (message->sopSequence ),
122- getSender (message),getMessageName (message->type ()),
123- message->messageId (), message->header );
124- int numObjects = message->numObjects ();
125- for (int i = 0 ; i < numObjects; i++)
126- Serial.printf (" %08x" , message->objects [i]);
70+ USBPDProtocolAnalyzer::USBPDProtocolAnalyzer () {
71+ memset (&capabilities, 0 , sizeof (capabilities));
12772}
12873
12974void USBPDProtocolAnalyzer::poll () {
@@ -137,7 +82,6 @@ void USBPDProtocolAnalyzer::poll() {
13782 case PDLogEntryType::messageReceived:
13883 Serial.print (" RX: " );
13984 printMessage (logEntry->message );
140- Serial.println ();
14185 break ;
14286 case PDLogEntryType::sinkSourceConnected:
14387 Serial.printf (" Connected: CC%d" , PowerController.ccPin );
@@ -158,7 +102,6 @@ void USBPDProtocolAnalyzer::poll() {
158102 case PDLogEntryType::transmissionStarted:
159103 Serial.print (" TX: " );
160104 printMessage (logEntry->message );
161- Serial.println ();
162105 break ;
163106 case PDLogEntryType::transmissionCompleted:
164107 Serial.println (" TX: completed" );
@@ -168,3 +111,149 @@ void USBPDProtocolAnalyzer::poll() {
168111 break ;
169112 }
170113}
114+
115+ void USBPDProtocolAnalyzer::printMessage (const PDMessage* message) {
116+ Serial.printf (" CC%d %-5s %-7s %-20s %d %04x" ,
117+ message->cc , getSOPSequenceName (message->sopSequence ),
118+ getSender (message),getMessageName (message->type ()),
119+ message->messageId (), message->header );
120+
121+ int numObjects = message->numObjects ();
122+ for (int i = 0 ; i < numObjects; i++)
123+ Serial.printf (" %08x" , message->objects [i]);
124+
125+ Serial.println ();
126+
127+ if (numObjects > 0 ) {
128+ switch (message->type ()) {
129+ case PDMessageType::dataRequest:
130+ printRequestDetails (message);
131+ break ;
132+ case PDMessageType::dataSourceCapabilities:
133+ printCapabilitiesDetails (message);
134+ break ;
135+ default :
136+ ;
137+ }
138+ }
139+ }
140+
141+ void USBPDProtocolAnalyzer::printCapabilitiesDetails (const PDMessage* message) {
142+ auto numbObjects = message->numObjects ();
143+
144+ // remember source capabilities
145+ capabilities.header = message->header ;
146+ memcpy (&capabilities.objects , &message->objects , numbObjects * 4 );
147+
148+ for (int i = 0 ; i < numbObjects; i += 1 ) {
149+ auto object = message->objects [i];
150+ int supplyType = (object >> 30 ) & 0x03 ;
151+
152+ Serial.printf (" %2d:" , i + 1 );
153+
154+ if (supplyType == 0 ) {
155+ // fixed supply: Vmin = Vmax
156+ int maxCurrent = (object & 0x3ff ) * 10 ;
157+ int maxVoltage = ((object >> 10 ) & 0x3ff ) * 50 ;
158+ Serial.printf (" Fixed %6dmV (fix) %6dmA (max) " , maxVoltage, maxCurrent);
159+ if ((object & (1 << 24 )) != 0 ) Serial.print (" extended msg, " );
160+ if ((object & (1 << 25 )) != 0 ) Serial.print (" dual-role data, " );
161+ if ((object & (1 << 26 )) != 0 ) Serial.print (" USB comm capable, " );
162+ if ((object & (1 << 27 )) != 0 ) Serial.print (" unconstrained power, " );
163+ if ((object & (1 << 28 )) != 0 ) Serial.print (" USB suspend, " );
164+ if ((object & (1 << 29 )) != 0 ) Serial.print (" dual-role power" );
165+
166+ } else if (supplyType == 1 ) {
167+ // battery
168+ int maxCurrent = (object & 0x3ff ) * 10 ;
169+ int minVoltage = ((object >> 10 ) & 0x3ff ) * 50 ;
170+ int maxVoltage = ((object >> 20 ) & 0x3ff ) * 50 ;
171+ Serial.printf (" Battery %6dmV (min) %6dmV (max) %6dmA (max)" , minVoltage, maxVoltage, maxCurrent);
172+
173+ } else if (supplyType == 2 ) {
174+ // variable
175+ int maxPower = (object & 0x3ff ) * 250 ;
176+ int minVoltage = ((object >> 10 ) & 0x3ff ) * 50 ;
177+ int maxVoltage = ((object >> 20 ) & 0x3ff ) * 50 ;
178+ Serial.printf (" Variable %6dmV (min) %6dmV (max) %6dmW (max)" , minVoltage, maxVoltage, maxPower);
179+
180+ } else {
181+ // APDO
182+ if (((object >> 28 ) & 0x03 ) == 0 ) {
183+ // PPS
184+ int maxCurrent = (object & 0x7f ) * 50 ;
185+ int minVoltage = ((object >> 8 ) & 0xff ) * 100 ;
186+ int maxVoltage = ((object >> 17 ) & 0xff ) * 100 ;
187+ Serial.printf (" PPS %6dmV (min) %6dmV (max) %6dmA (max)" , minVoltage, maxVoltage, maxCurrent);
188+ }
189+ }
190+
191+ Serial.println ();
192+ }
193+ }
194+
195+ void USBPDProtocolAnalyzer::printRequestDetails (const PDMessage* message) {
196+ auto header = message->header ;
197+ auto object = message->objects [0 ];
198+ int objPos = (object >> 28 ) & 0x07 ;
199+ bool giveBack = (object & (1 << 27 )) != 0 ;
200+ auto capObject = capabilities.numObjects () >= objPos ? capabilities.objects [objPos - 1 ] : 0 ;
201+ int supplyType = (capObject >> 30 ) & 0x03 ;
202+
203+ if (supplyType == 0 || supplyType == 2 ) {
204+ int current0 = (object & 0x3ff ) * 10 ;
205+ int current1 = ((object >> 10 ) & 0x3ff ) * 10 ;
206+ Serial.printf (" Capability: %d %6dmA (oper) %6dmA (%s) " , objPos, current1, current0, giveBack ? " min" : " max" );
207+
208+ } else if (supplyType == 1 ) {
209+ int power0 = (object & 0x3ff ) * 250 ;
210+ int power1 = ((object >> 10 ) & 0x3ff ) * 250 ;
211+ Serial.printf (" Capability: %d %6dmW (oper) %6dmW (%s) " , objPos, power1, power0, giveBack ? " min" : " max" );
212+
213+ } else {
214+ int current = (object & 0x7f ) * 50 ;
215+ int voltage = ((object >> 9 ) & 0x7ff ) * 20 ;
216+ Serial.printf (" Capability: %d %6dmV (oper) %6dmA (oper) " , objPos, voltage, current);
217+ }
218+
219+ if ((object & (1 << 23 )) != 0 ) Serial.print (" extended msg, " );
220+ if ((object & (1 << 24 )) != 0 ) Serial.print (" USB suspend, " );
221+ if ((object & (1 << 25 )) != 0 ) Serial.print (" USB comm capable, " );
222+ if (giveBack) Serial.print (" give back" );
223+ Serial.println ();
224+ }
225+
226+ const char * USBPDProtocolAnalyzer::getMessageName (PDMessageType messageType) {
227+ unsigned int index = (unsigned int )messageType;
228+ const char * name = nullptr ;
229+ if (index < 0x80 ) {
230+ constexpr unsigned int arraySize = sizeof (ControlMessageNames) / sizeof (ControlMessageNames[0 ]);
231+ if (index < arraySize)
232+ name = ControlMessageNames[index];
233+ } else {
234+ index -= 0x80 ;
235+ constexpr unsigned int arraySize = sizeof (DataMessageNames) / sizeof (DataMessageNames[0 ]);
236+ if (index < arraySize)
237+ name = DataMessageNames[index];
238+ }
239+ return name != nullptr ? name : " <unknown>" ;
240+ }
241+
242+ const char * USBPDProtocolAnalyzer::getSOPSequenceName (PDSOPSequence sequence) {
243+ constexpr unsigned int arraySize = sizeof (SOPSequenceNames) / sizeof (SOPSequenceNames[0 ]);
244+ unsigned int index = (unsigned int )sequence;
245+ if (index >= arraySize)
246+ index = arraySize;
247+ return SOPSequenceNames[index];
248+ }
249+
250+ const char * USBPDProtocolAnalyzer::getSender (const PDMessage* message) {
251+ auto seq = message->sopSequence ;
252+ if (seq == PDSOPSequence::sop) {
253+ return (message->header & 0x0100 ) != 0 ? " Source" : " Sink" ;
254+ } else if (seq == PDSOPSequence::sop1 || seq == PDSOPSequence::sop2) {
255+ return (message->header & 0x0100 ) != 0 ? " Cable" : " Port" ;
256+ }
257+
258+ return " " ;
259+ }
0 commit comments