manuelbl / usb-pd-arduino

USB Power Delivery for Arduino
MIT License
53 stars 10 forks source link

Errors from ProtocolAnalyzer output and some other questions #5

Open DrmnSamoLiu opened 1 year ago

DrmnSamoLiu commented 1 year ago

First of all, thank you so much for making and sharing this project that enables people to perform PD analysis without super expensive equipment!

One of the issue I met during my tests is when I'm using the ProtocolAnalyzer, I kept getting errors and very occasionally good source capability data:

圖片 I'd like to know if this is expected behavior, or it's because my wiring is so bad it's causing CRC problems so the code have to keep retrying until it got good data? (I'm using ProtocolAnalyzer with the "sink" wiring and using my bluepill directly as power sink, if it helps.)

Second question is, have you implemented raw data logging? (For example, real time "got goodCRC" or "resending message", etc.) I've seen some log() calls in source files but I'm not sure how these data can be viewed from serial console.

Lastly I'd like to know if it's possible to send custom data message other than capabilities request from the code that's already present? What I want to achieve is to fuzz test a sink device with different data message type and data objects to see if there are any "hidden" functionalities, but I'm really having a hard time trying to understand how I could construct a data message with existing code.

My understanding for now is that I should first change the 5.1k pull down resistors on both CC line to 56k pull up to indicate the bluepill is a PD source, and then I could probably just put the "SendCustomDataMessage" code in loop and wait for goodCRC response to make sure it successfully received the data message.

I'm very new to USB PD so any advice or suggestions are highly appreciated!

[Edit] Regarding my last question, I'm starting to understand how the code work.... It seems sending custom data message is as simple as following code, for other people who wants to do the same:

#include "USBPowerDelivery.h"

uint32_t object = 0x6;
PDController cont;

void setup() {
  Serial.begin(115200);
}

void loop() {
  PowerSink.poll();
  if (PowerSink.isConnected()){
  cont.sendDataMessage((PDMessageType)0x90, 1, &object);
  }
}

This is very inelegant though and I guess checking for goodCRC response is still needed.

manuelbl commented 1 year ago

It's difficult to say what is causing the problems without seeing your setup. Most likely, it's an electrical problem related to the voltage levels on CC1/CC2. Either they aren't at the right level or too imbalanced between the on and off state. It's unlikely to be due to poor wiring as the signals are rather low speed. More likely the wiring is incorrect, the resistors are of incorrect value, the comparator is of a different type or isn't fast enough.

Do you have an oscilloscope? If so, have a look at the signal on CC1 and CC2.

The logging is not at the detailed level you are looking for. But you can easily extend it by adding more log() statements to PDPowerController.cpp. Log entries are always posted to a queue. Otherwise, serial output, which is really slow, will delay everything so much that the USB PD protocol fails due to timing issues. There is no such things as "real-time" with serial output.

The code currently supports monitoring and power sink. For a power source, additional code will be needed and you will also need the hardware capability to turn on and off VBUS (and potentially set it to different voltages).

DrmnSamoLiu commented 1 year ago

Update:

I realized the error only occur with the PD charger I'm using during the screen capture. ProtocolAnalyzer works perfect with Apple model A1719 87W charger that I tried afterwards. I do have a logic analyzer and would try to see what's wrong with the PD communication on the 1st charger, but can't promise I could find anything helpful.

manuelbl commented 1 year ago

If you post an image of the captured CC_3V3 signal, I can help you analyze the problem. A helpful capture would include about 20 to 50 high/low and low/high transitions and sufficient resolution to estimate the duration. If your logic analyzer supports it, also record a much short time frame in analog mode to see how quick the transitions are and if proper voltage levels are achieved.

DrmnSamoLiu commented 1 year ago

It seems the problem sure is CC_3V3 signal not being generated in some situation, I'm also missing some CC_3V3 signal using Apple charger.

圖片

I tried to capture with following setting with Saleae Logic Pro 8: 圖片

You can check my capture with Saleae Logic software: https://www.saleae.com/downloads/

The capture file is quite large because of analog data, so I have to share it via Google drive: https://drive.google.com/drive/folders/1DYNwswrP-uYivtCU-c8Zw1s5i9Gcwb__?usp=sharing

Hope this helps. If you don't feel comfortable installing Saleae Logic and downloading my capture, I can try to show things with screenshots.

DrmnSamoLiu commented 1 year ago

Quick update, I tried to capture again with CC2 and this time the reason is quite obvious - CC2 is somehow pulled to 5v and it makes the comparator not function properly......

Here's the capture with Apple charger: 圖片

And here's the "error" charger: 圖片

I wonder how this happen and is it common for "none-active" CC line to get pulled up in the middle while the active line is transmitting data.....

Edit: After digging a bit more, this 5v might be the power (Vconn) for the e-marker in the cable. As for why some chargers provide this power in the very beginning and some provide it after some PD transmission, remains unknown for now. I'll keep studying the PD spec.

manuelbl commented 1 year ago

Interesting investigation.

A solution for this would be to split CC_3V3 into CC1_3V3 and CC2_3V3. This could however be a challenges for the STM32F103. Since timers in input capture mode can't trigger both on the raising and falling edge, we would need to identify 2 pairs of pins that can be reconfigured to work with the same two timers.