usb-pd-arduino
usb-pd-arduino copied to clipboard
Problems with protocol analyzer with STM32G4 with integrated UCPD peripheral
When monitoring the CC-Lines with the STM32G4RE Nucleo board, the STM32 pulls the CC-Lines pretty low. When having the STM32 disconnected, the voltages of both CC-Lines are about 3.1V. When connecting the STM32 to the CC-Lines, their voltages drop to about 430mV, which prohibits any devices communicating over the CC-Lines, and thus nothing happens. Is this expected behavior for this board?
That does sound right. But then again, I've tested this setup and it worked.
I will investigate it soon. Possibly an Arduino core update has introduced a change...
I've just measured the resistances of CC1 and CC2 to ground, and they're both at 5.1k, which they shouldn't. I've already pulled PA10 and PA9 low, just incase the dead battery stuff didn't get disabled properly, but no change
I can disable the pulldown resistors, with modifying the LL_UCPD_SetRpResistor and/or LL_UCPD_SetccEnable in PDPhySTM32UCPD.cpp. The problem with that is, that the PDProtocolAnalyzer.poll() function doesn't do anything then, the console output just stays empty. This is to be expected when doing LL_UCPD_SetccEnable(UCPD1, LL_UCPD_CCENABLE_NONE), because this disable the entire CC PHY, if I've understood the code correctly. But i don't quite understand why disabling the resistors prohibits the PHY from receiving anything
It will probably be the weekend before I can create a good test setup and dig into the code.
The problem is reproducible even though it does not affecting the monitoring a great deal in my setup. The power source however thinks that a sink is connected and immediately starts sending requests.
It looks as if it is not possible to disable the resistors and still have a functioning USB PD peripheral with the STM32. At least, I couldn't find a way to achieve it.
So the best approach for USB PD monitoring is to decouple the CC1 and CC2 lines from the STM32 inputs for CC1 and CC2. I simply way to achieve it is with an op amp configured as voltage follower. This can either be achieved with a basic op amp IC or – very conveniently – with the op amps built into the STM32 G4 family.
I've tested the later setup as follows:
Wiring:
- CC1 (monitored USB-C) to PA1 (Op Amp 3 input, STM32)
- PB1 (Op Amp 3 output, STM32) to PB6 (UCPD1 CC1, STM32)
- CC2 (monitored USB-C) to PB11 (Op Amp 4 input, STM32)
- PB12 (Op Amp 4 output, STM32) to PB4 (UCPD1 CC2, STM32)
Initialization of Op Amp (in setup() function):
pinMode(PA1, INPUT_ANALOG); // Op Amp 3 Input
pinMode(PB1, INPUT_ANALOG); // Op Amp 3 Output
hopamp3.Instance = OPAMP3;
memset(&hopamp3.Init, 0, sizeof(hopamp3.Init));
hopamp3.Init.Mode = OPAMP_FOLLOWER_MODE;
hopamp3.Init.NonInvertingInput = OPAMP_NONINVERTINGINPUT_IO2;
HAL_OPAMP_Init(&hopamp3);
pinMode(PB11, INPUT_ANALOG); // Op Amp 4 Input
pinMode(PB12, INPUT_ANALOG); // Op Amp 4 Output
hopamp4.Instance = OPAMP4;
memset(&hopamp4.Init, 0, sizeof(hopamp3.Init));
hopamp4.Init.Mode = OPAMP_FOLLOWER_MODE;
hopamp4.Init.NonInvertingInput = OPAMP_NONINVERTINGINPUT_IO2;
HAL_OPAMP_Init(&hopamp4);
HAL_OPAMP_Start(&hopamp3);
HAL_OPAMP_Start(&hopamp4);
Additionally, the STM32 HAL for the Op Amps needs to be enabled:
If using Arduino IDE, create a file called hal_conf_extra.h containing:
#define HAL_OPAMP_MODULE_ENABLED
If using PlatformIO, add the following lines to platformio.ini:
build_flags =
-D HAL_OPAMP_MODULE_ENABLED
Thanks for the fix, that works (kinda, occasionally there are some weird signals, but that's easy to ignore). Additionally to your code, there needs to be
static OPAMP_HandleTypeDef hopamp3;
static OPAMP_HandleTypeDef hopamp4;
after the defines in the beginning of the code.
I think most of my issues (as mentioned above) come from my not USB-IF certified source (TPS26750EVM) doing weird stuff. For example:
3394123549 Connected: CC1
3394123558 Connected: CC1
3394123760 Disconnected
3394133294 Connected: CC0
3394133318 Disconnected
3394133344 Connected: CC1
3394145820 Disconnected
3394145837 Connected: CC1
3394145854 Disconnected
3394145882 Connected: CC1
3394145898 Disconnected
3394145929 Connected: CC1
3394145958 Disconnected
3394150527 Connected: CC1
But as i said, that's easy to ignore, and is likely my fault, and not your library acting up.
Does the library work with EPR, especially the PowerSink.requestPower() function in terms of the E-Marker stuff that needs to happen for EPR?
The connect/disconnect events are to be expected when a USB-C plug is connected or disconnected. The USB-PD protocol should handle it. A monitor is also more likely to see spurious events on the unused CC line as the line can be floating (which wouldn't be the case for a proper sink or source).
EPR isn't supported yet by the library.