2021-11-18 11:12 AM
I am trying to use the UCPD peripheral on a STM32G4 (later on STM32G0) target to detect when a debug accessory device has been plugged into the USB-C port. This is going to be used in factory test.
The issue I'm having is the dead battery pull downs are causing erroneous readings in the TYPEC_VSTATE_CCx registers.
I noticed when I uncheck the "Dead Battery Signals" box in STM32CubeIDE (UCPD Mode and Configuration window), the issue goes away. I am pulling up the CC pins with a 56k ohm resistor to 5V to indicate a standard USB power source. The CC voltage with the "Dead Battery Signals" disabled is 0.432V, as would be expected with a 5.1k Rd. With "Dead Battery Signals" enabled, this voltage goes up to 0.644V and the TYPEC_VSTATE_CCx registers start reporting erroneous values (ie: not vRd-USB, as per table 428 in RM0440).
I then measured the voltage when the MCU was unpowered. It was around 0.62V, which I suppose is fine because a USB-C Source should recognize this as a Sink connected. This was the case regardless of the “Dead Battery Signals�? checkbox. I then realized that the DBCC pins are “enabled�? regardless of this checkbox when the MCU is unpowered. This checkbox is extremely confusing!
My notes are below:
The UCPDx_DBCCy pins have special hardware, they do not require register settings to enable them.
If they are shorted to their respective UCPDx_CCy pins, the Rd resistors will automatically be enabled when power is applied to the CC line, even if the MCU is completely unpowered (ie: battery is dead).
However, it seems that having this dead battery pull down enabled when the UCPDx peripheral is operating (ie: it has enabled its own internal CC1/CC2 Rd pull-down resistors) causes incorrect voltage level readings in the TYPEC_VSTATE_CCy registers.
It is not made clear in the documentation (UCPD section nor CubeMX) that this may happen. There is no mention of the related UCPD1_DBDIS register in Power Control Register 3 (See RM0440, section 6.4.3)
The only place where UCPD1_DBDIS is mentioned is in the debug (DBG) section (section 47). This is mentioned because it can cause issues with the JTAG reset function on the same pin. This register is not mentioned in the UCPD chapter at all.
The "Dead Battery Signals" checkbox in the CubeMX UCPDx configuration GUI sets this bit (disables dead battery pull downs) if left unchecked. Checking this box (enabling dead battery signals from a user perspective) does not affect their actual operation when the MCU is unpowered. This is misleading. The only effect it has is clearing the UCPD1_DBDIS bit, enabling the dead battery pull-down resistors at runtime. Checking this box only causes issues with UCPD CC voltage detection.
I'm mostly writing this so that others that may find this and save them a few hours of confusion.
ST -- please update the reference manual with information about this and add a note about the UCPD1_DBDIS bit!
Solved! Go to Solution.
2021-11-23 01:51 AM
Hi GBeck.1 ,
The UCPD1_DBDIS bit function is only disable the "dead battery" functionality in power-on mode not in power-off. If MCU is unpowered then "dead battery" function is always enabled.
In RM0440:
In Chapter "46.4.6 UCPD Type-C pull-ups (Rp) and pull-downs (Rd)":
-----------------------------------------------------------------
When the MCU is unpowered, it still presents the “dead battery�? Rd, provided that UCPDx_DBCC1 and UCPDx_DBCC2 pins are each connected to UCPDx_CC1 and UCPDx_CC2 pins respectively.
If dead battery behavior is not required (for example for source only products), then UCPDx_DBCC1 and UCPDx_DBCC2 pins must both be tied to ground.
After power arrives and the MCU boots, the desired behavior (for example source) must be programmed into ANAMODE and ANASUBMODE[1:0] before setting the UCPD_DBDIS bit of the PWR_CR3 register to remove dead battery pull-down resistor and allow the values just programmed to take effect.
-----------------------------------------------------------------
In datasheets:
Physical implementation of "dead battery" pins is explained in datasheet - note under table "Table 12. STM32G474xB/xC/xE pin definition":
-----------------------------------------------------------------
6. After reset, a pull-down resistor (Rd = 5.1kΩ from UCPD peripheral) can be activated on PB6, PB4 (UCPD1_CC1, UCPD1_CC2). The pull-down on PB6 (UCPD1_CC1) is activated by high level on PA9 (UCPD1_DBCC1). The pull-down on PB4 (UCPD1_CC2) is activated by high level on PA10 (UCPD1_DBCC2). This pull-down control (dead battery support on UCPD peripheral) can be disabled by setting bit UCPD1_DBDIS=1 in the PWR_CR3 register. PB4, PB6 have UCPD_CC functionality which implements an internal pull-down resistor (5.1kΩ) which is controlled by the voltage on the UCPD_DBCC pin (PA10, PA9). A high level on the UCPD_DBCC pin activates the pull-down on the UCPD_CC pin. The pull-down effect on the CC lines can be removed by using the bit UCPD1_DBDIS =1 (USB Type-C and power delivery dead battery disable) in the PWR_CR3 register.
-----------------------------------------------------------------
If MCU is unpowered then registers cannot control the behavior - because registers are unpowered. Physically (if MCU is unpowered): there is fixed control of pull-down resistor on UCPD1_CCx pin from UCPD1_DBCCx pin.
Like: one terminal of internal 5.1kOhm resistor is connected on UCPD1_CCx pin. Second terminal of this resistor is connected to drain of NMOS transistor. Source of this NMOS is connected to VSS. Gate of NMOS is connected to UCPD1_DBCCx pin.
Function: if voltage is present on NMOS gate (UCPD1_DBCCx pin) then 5k1 pull down is activated on UCPD1_CCx pin (NMOS transistor is open). This is valid also in unpowered state - because voltage level on NMOS gate is controlled by the UCPD host - UCPD host applies voltage on pins and then checks if there is pull-down by measuring voltage on pin. If "dead battery" functionality is required then pins UCPD1_DBCCx and UCPD1_CCx are connected together - so in this case voltage always activates 5k1 pull-down.
If "dead battery" function is not required in application then we don't care about behavior if MCU is unpowered (we usually use UCPD pins for another function). After power on we should disable this control between UCPD1_CCx and UCPD1_DBCCx pins by setting bit UCPD1_DBDIS (in PWR_CR3 register). Otherwise this control will be present here and 5k1 pull down will be active or not in dependency from voltage on UCPD1_DBCCx pin (which can cause strange behavior). Therefore there is note under table in datasheet (mentioned above) - mainly for users which don't care about USB power delivery functionality in own application.
If "dead battery" is required by application (UCPD application) then we should disable control between pins UCPD1_CCx and UCPD1_DBCCx after power on - but this disable should be done after we correctly configure UCPD peripheral for next usage (we signalize "dead battery" until MCU is fully ready for next UCPD processing step - according USB power delivery specification). This is written in reference manual (mentioned also above):
-----------------------------------------------------------------
After power arrives and the MCU boots, the desired behavior (for example source) must be programmed into ANAMODE and ANASUBMODE[1:0] before setting the UCPD_DBDIS bit of the PWR_CR3 register to remove dead battery pull-down resistor and allow the values just programmed to take effect.
-----------------------------------------------------------------
I think that behavior is mentioned in RM0440 + datasheet. We can mention this on more places in RM0440 - but I don't know if this is really necessary. For "non UCPD" users (which don't know UCPD behavior) we included into datasheet note under table - to highlight/describe this control between some pins (to not have strange pull-down activation for "non UCPD" applications).
Note: In STM32G491/4A1 devices we established new option bit which disables control between UCPD1_CC2 and UCPD1_DBCC2 pins immediately after power on (when option bytes are loaded) - but only between UCPD1_CC2 and UCPD1_DBCC2 pins , not between UCPD1_CC1 and UCPD1_DBCC1 pins: in RM0440:
-----------------------------------------------------------------
Bit 22 PB4_PUPEN: PB4 pull-up enable
0: USB power delivery dead-battery enabled/ NJTRST pull-up deactivated
1: USB power delivery dead-battery disabled/ NJTRST pull-up activated
Note: Only for Category 4 devices (otherwise Reserved)
-----------------------------------------------------------------
This option bit was implemented mainly due to NJTRST pull-up activation - and correct behavior for JTAG interface after power-on (for non UCPD application).
Regards
Igor
2021-11-18 01:08 PM
Thank you for the detailed writeup.
I know the same problem from the other perspective: users of 'G0/'G4, who *don't* use USB PD, are often caught by surprise when they encounter the 5k1 pulldown, which in addition is switched on/off by a different pin.
This ought to be *clearly* marked in the pinout table in all related datasheets (including the 'G070 which officially does not have USB-PD but the hardware is there), in the GPIO chapter of RM (as it is a departure of usual GPIO structure), and, as you've said, of course, in the PD chapter itself!
As far as the tickbox goes, it's notoriously hard to determine the logic by which registers/bits, which *disable* something by *setting* a bit, should go. Notoriously, this is the case of option bits in FLASH, which are by default OFF when == 1 (the cleared state of FLASH) and ON when programmed to 0 (ever tried to make sure you set properly the tickboxes in STLink Utility's Options window?). However, ST manages to produce additional ambiguity even without GUI/software. One glaring example is how ST in software calls 0 "RESET" - in my dictionary, "reset" means "initial state, regardless of whether it's 0 or 1", and "0" is "zero" or "clear". But there are even better, directly in RM: for example, in the dual-port DMA (in 'F2/'F4/'F7), there's a bit which enables FIFO which is called DMDIS (Direct Mode Disable). One even better example is in the OTG USB, where the bit enabling the built-in PHY is called PWRDWN and you enable the PHY by setting it to 1.
@Imen DAHMEN , can please GBeck's remarks be forwarded to whomever it may concern? Thanks.
JW
2021-11-23 01:51 AM
Hi GBeck.1 ,
The UCPD1_DBDIS bit function is only disable the "dead battery" functionality in power-on mode not in power-off. If MCU is unpowered then "dead battery" function is always enabled.
In RM0440:
In Chapter "46.4.6 UCPD Type-C pull-ups (Rp) and pull-downs (Rd)":
-----------------------------------------------------------------
When the MCU is unpowered, it still presents the “dead battery�? Rd, provided that UCPDx_DBCC1 and UCPDx_DBCC2 pins are each connected to UCPDx_CC1 and UCPDx_CC2 pins respectively.
If dead battery behavior is not required (for example for source only products), then UCPDx_DBCC1 and UCPDx_DBCC2 pins must both be tied to ground.
After power arrives and the MCU boots, the desired behavior (for example source) must be programmed into ANAMODE and ANASUBMODE[1:0] before setting the UCPD_DBDIS bit of the PWR_CR3 register to remove dead battery pull-down resistor and allow the values just programmed to take effect.
-----------------------------------------------------------------
In datasheets:
Physical implementation of "dead battery" pins is explained in datasheet - note under table "Table 12. STM32G474xB/xC/xE pin definition":
-----------------------------------------------------------------
6. After reset, a pull-down resistor (Rd = 5.1kΩ from UCPD peripheral) can be activated on PB6, PB4 (UCPD1_CC1, UCPD1_CC2). The pull-down on PB6 (UCPD1_CC1) is activated by high level on PA9 (UCPD1_DBCC1). The pull-down on PB4 (UCPD1_CC2) is activated by high level on PA10 (UCPD1_DBCC2). This pull-down control (dead battery support on UCPD peripheral) can be disabled by setting bit UCPD1_DBDIS=1 in the PWR_CR3 register. PB4, PB6 have UCPD_CC functionality which implements an internal pull-down resistor (5.1kΩ) which is controlled by the voltage on the UCPD_DBCC pin (PA10, PA9). A high level on the UCPD_DBCC pin activates the pull-down on the UCPD_CC pin. The pull-down effect on the CC lines can be removed by using the bit UCPD1_DBDIS =1 (USB Type-C and power delivery dead battery disable) in the PWR_CR3 register.
-----------------------------------------------------------------
If MCU is unpowered then registers cannot control the behavior - because registers are unpowered. Physically (if MCU is unpowered): there is fixed control of pull-down resistor on UCPD1_CCx pin from UCPD1_DBCCx pin.
Like: one terminal of internal 5.1kOhm resistor is connected on UCPD1_CCx pin. Second terminal of this resistor is connected to drain of NMOS transistor. Source of this NMOS is connected to VSS. Gate of NMOS is connected to UCPD1_DBCCx pin.
Function: if voltage is present on NMOS gate (UCPD1_DBCCx pin) then 5k1 pull down is activated on UCPD1_CCx pin (NMOS transistor is open). This is valid also in unpowered state - because voltage level on NMOS gate is controlled by the UCPD host - UCPD host applies voltage on pins and then checks if there is pull-down by measuring voltage on pin. If "dead battery" functionality is required then pins UCPD1_DBCCx and UCPD1_CCx are connected together - so in this case voltage always activates 5k1 pull-down.
If "dead battery" function is not required in application then we don't care about behavior if MCU is unpowered (we usually use UCPD pins for another function). After power on we should disable this control between UCPD1_CCx and UCPD1_DBCCx pins by setting bit UCPD1_DBDIS (in PWR_CR3 register). Otherwise this control will be present here and 5k1 pull down will be active or not in dependency from voltage on UCPD1_DBCCx pin (which can cause strange behavior). Therefore there is note under table in datasheet (mentioned above) - mainly for users which don't care about USB power delivery functionality in own application.
If "dead battery" is required by application (UCPD application) then we should disable control between pins UCPD1_CCx and UCPD1_DBCCx after power on - but this disable should be done after we correctly configure UCPD peripheral for next usage (we signalize "dead battery" until MCU is fully ready for next UCPD processing step - according USB power delivery specification). This is written in reference manual (mentioned also above):
-----------------------------------------------------------------
After power arrives and the MCU boots, the desired behavior (for example source) must be programmed into ANAMODE and ANASUBMODE[1:0] before setting the UCPD_DBDIS bit of the PWR_CR3 register to remove dead battery pull-down resistor and allow the values just programmed to take effect.
-----------------------------------------------------------------
I think that behavior is mentioned in RM0440 + datasheet. We can mention this on more places in RM0440 - but I don't know if this is really necessary. For "non UCPD" users (which don't know UCPD behavior) we included into datasheet note under table - to highlight/describe this control between some pins (to not have strange pull-down activation for "non UCPD" applications).
Note: In STM32G491/4A1 devices we established new option bit which disables control between UCPD1_CC2 and UCPD1_DBCC2 pins immediately after power on (when option bytes are loaded) - but only between UCPD1_CC2 and UCPD1_DBCC2 pins , not between UCPD1_CC1 and UCPD1_DBCC1 pins: in RM0440:
-----------------------------------------------------------------
Bit 22 PB4_PUPEN: PB4 pull-up enable
0: USB power delivery dead-battery enabled/ NJTRST pull-up deactivated
1: USB power delivery dead-battery disabled/ NJTRST pull-up activated
Note: Only for Category 4 devices (otherwise Reserved)
-----------------------------------------------------------------
This option bit was implemented mainly due to NJTRST pull-up activation - and correct behavior for JTAG interface after power-on (for non UCPD application).
Regards
Igor
2021-11-23 02:04 AM
Hi ,
You have mentioned this:
... I then measured the voltage when the MCU was unpowered. It was around 0.62V, which I suppose is fine because a USB-C Source should recognize this as a Sink connected. This was the case regardless of the “Dead Battery Signals�? checkbox. I then realized that the DBCC pins are “enabled�? regardless of this checkbox when the MCU is unpowered. ...
But the voltage you reported (0.62V) is too high - because the pull down should be 5k1 and the voltage divider is then 56k + 5k1. Are you sure that you have measured 0.62V voltage? Because even if 5k1 resistor has 20% tolerance the voltage should be not so high. Ideal voltage from this divider should be 0.42V .
Regards
Igor