Skip to main content
JChau
Associate II
July 22, 2019
Solved

STM32G071 UCPD library bug or my bad?

  • July 22, 2019
  • 12 replies
  • 2888 views

Hello there, I have a custom board with STM32G071CB for USB Type C PD Source, dual port, RTOS, configured with CubeMX 5.3.0, after writing code on usbpd_dpm_user.c and start debugging, I suspected there are 2+1 strange behavior so I hope somebody can give me some insights why are these happening:

  1. in the code USBPD_SettingsTypeDef.CAD_DefaultResistor is set to 0x00u, from datasheet I am expecting UCPDx.CR.ANASUBMODE should be 1 but what I got from the debugger is 3.
  2. with UCPDx.CR.ANASUBMODE set to 3, UCPDx.SR.TYPEC_VSTATE_CC2 is always 1, even though the type-c connector is n.c.! modified UCPDx.CR.ANASUBMODE to 1 fixed everything (i.e. correct behavior for UCPDx cable detection).
  3. in USBPD_DPM_GetDataInfo I programmed like this:
switch (DataId)
{
 /* Case Port Source PDO Data information */
 case USBPD_CORE_DATATYPE_SRC_PDO :
 *(uint32_t*)(Ptr) = 0x14019032;
 *Size = 4;
 break;
}

I expected this will send a 5V, 500mA fixed source pdo to my usb-pd packet sniffer, that should be

611332900114

, but what i get is

6103

so I guess something in between my code and the wire filtered my PDO? What's wrong with my code?

This topic has been closed for replies.
Best answer by Dominique

​Hi John,

Question 1 : the parameter USBPD_SettingsTypeDef.CAD_DefaultResistor is the right place to set the source resistor unfortunately there is a bug inside the G0 device which don't care about the value coming from setting structure.

The correction do perform is the following : file usbpd_cad_hw_if.c function CAD_Init replace the lines

void CAD_Init(uint8_t PortNum, USBPD_SettingsTypeDef *pSettings, USBPD_ParamsTypeDef *pParams, void (*WakeUp)(void))
{
....
/* Replace */
// Ports[PortNum].params = pParams;
// #ifndef _VALID_RP
// #define _VALID_RP vRp_3_0A
// #endif
// Ports[PortNum].params->RpResistor = _VALID_RP;
// Ports[PortNum].settings = pSettings;
 
/* by */
Ports[PortNum].params = pParams;
Ports[PortNum].settings = pSettings;
Ports[PortNum].params->RpResistor = Ports[PortNum].settings->CAD_DefaultResistor;

The range of the value for CAD_DefaultResistor are :

#define vRp_Default 0x00u /*!< Default USB Power */ ie ANASUBMODE = 1
 
#define vRp_1_5A 0x01u /*!< USB Type-C Current @ 1.5 A */ ie ANASUBMODE = 2
 
#define vRp_3_0A 0x02u /*!< USB Type-C Current @ 3 A */ ie ANASUBMODE = 3
 

Please have a lock at function void USBPDM1_AssertRp(uint8_t PortNum) to see the conversion mechanism

Question2 ; this is really strange because for any value of anasubmode a source without cable plug shall return UCPDx.SR.TYPEC_VSTATE_CC2  = UCPDx.SR.TYPEC_VSTATE_CC2 = 2 which means nothing connected. Please could you confirm if the DEAD BATTERY PIN are connected to ground and setup in analog mode ? (DBCC1 and DBCC2)

Question3 : the variable is not necessary 32 bits aligned so you must avoid cast on uint32_t to write it. So we recommend to use a memcpy or the code bellow to avoid more optimized.

 case USBPD_CORE_DATATYPE_SRC_PDO :
// *(uint32_t*)(Ptr) = 0x14019032;
 Ptr[0] = 0x32;
 Ptr[1] = 0x90;
 Ptr[2] = 0x01;
 Ptr[3] = 0x14;
 *Size = 4;
 break;

I hope my reply will be helpful

BR

12 replies

Dominique
DominiqueBest answer
ST Employee
July 22, 2019

​Hi John,

Question 1 : the parameter USBPD_SettingsTypeDef.CAD_DefaultResistor is the right place to set the source resistor unfortunately there is a bug inside the G0 device which don't care about the value coming from setting structure.

The correction do perform is the following : file usbpd_cad_hw_if.c function CAD_Init replace the lines

void CAD_Init(uint8_t PortNum, USBPD_SettingsTypeDef *pSettings, USBPD_ParamsTypeDef *pParams, void (*WakeUp)(void))
{
....
/* Replace */
// Ports[PortNum].params = pParams;
// #ifndef _VALID_RP
// #define _VALID_RP vRp_3_0A
// #endif
// Ports[PortNum].params->RpResistor = _VALID_RP;
// Ports[PortNum].settings = pSettings;
 
/* by */
Ports[PortNum].params = pParams;
Ports[PortNum].settings = pSettings;
Ports[PortNum].params->RpResistor = Ports[PortNum].settings->CAD_DefaultResistor;

The range of the value for CAD_DefaultResistor are :

#define vRp_Default 0x00u /*!< Default USB Power */ ie ANASUBMODE = 1
 
#define vRp_1_5A 0x01u /*!< USB Type-C Current @ 1.5 A */ ie ANASUBMODE = 2
 
#define vRp_3_0A 0x02u /*!< USB Type-C Current @ 3 A */ ie ANASUBMODE = 3
 

Please have a lock at function void USBPDM1_AssertRp(uint8_t PortNum) to see the conversion mechanism

Question2 ; this is really strange because for any value of anasubmode a source without cable plug shall return UCPDx.SR.TYPEC_VSTATE_CC2  = UCPDx.SR.TYPEC_VSTATE_CC2 = 2 which means nothing connected. Please could you confirm if the DEAD BATTERY PIN are connected to ground and setup in analog mode ? (DBCC1 and DBCC2)

Question3 : the variable is not necessary 32 bits aligned so you must avoid cast on uint32_t to write it. So we recommend to use a memcpy or the code bellow to avoid more optimized.

 case USBPD_CORE_DATATYPE_SRC_PDO :
// *(uint32_t*)(Ptr) = 0x14019032;
 Ptr[0] = 0x32;
 Ptr[1] = 0x90;
 Ptr[2] = 0x01;
 Ptr[3] = 0x14;
 *Size = 4;
 break;

I hope my reply will be helpful

BR

JChau
JChauAuthor
Associate II
July 23, 2019

Thank you a lot for your reply!

  1. Yes that solution fixed the problem, but I guess until a patch to the USBPD library arrives I have to make this change every time after I touched STM32CubeMX...
  2. Yes I confirm for both UCPD1 and UCPD2, DBCC1 and DBCC2 is both tied to ground, GPIOA.MODER8 and MODER9 is 0x3 so it should be analog, same situation for UCPD2. Also I tested with ANASUBMODE = 0, 1, 2 and all are performed as expected, only ANASUBMODE = 3 have this problem. For your reference I powered the digital part of my board at 1.8V, just to say so because this seems related to analog voltage,
  3. i do fixed the problem using memcpy as ST's demo software, but that gets me confused because I can see Ptr is actually 32bit aligned... anyway it's fixed.
Dominique
ST Employee
July 23, 2019

Hi John

About the question 2, you must take care about the operating condition (see chapter 5.3.23 of the STM32G071CB datasheet)

0690X000009Z0AqQAK.png

BR

Dominique

JChau
JChauAuthor
Associate II
July 23, 2019

Hi Dominque

Yes I do take notice and asked our hardware guy to bridge the mcu to 3.3V, because we already noticed another problem that not even GoodCRC is sent from any device, so we checked hardware and the upper bound voltage of CC line is only 0.74V, much lower than requried 1.04-1.2V per PD specification.

Anyway, I can confirm that raising the voltage of VDD to 3.3V solved my question 2, but we still don't get any GoodCRC just for your interest :(

Thank you very much for your help anyway!

Dominique
ST Employee
July 23, 2019

Hi John,

This issue could be link with the system clock please could you share the sytem clock configuration ? to make working UCPD, HSI clock shall be enabled.

To check if the problem is linked with the system clock please could use the settings from our G0 demo

BR

Dominique

JChau
JChauAuthor
Associate II
July 23, 2019

Hi Dominque,

Attached is the settings from STM32CubeMX, from what I can see it should be the same as G0 demo except PLLN/PLLR, but final clocks are the same

I am now out of office but my final test today is connecting the prototype to my Nexus 6P phone and the phone do says "Quick Charging", but because the only PDO now is 5V 500mA I don't know why "Quick Charging" is displayed:downcast_face_with_sweat: I hope that's just because it did recognized a PD source and if that's the case I can assume my case solved and move on to the other parts of the system.

0690X000009Z103QAC.jpg

Dominique
ST Employee
July 24, 2019

Hi John

Please could you send me the USB-PD trace ? i could help you to analyse if there is an issue.

FYI, our software solution embedded is own trace system which could be a great help to analyse USB-PD issue. So i recommend you to enable it, this could be done through Cube-MX (enable the utilities TRACER_EMB and tick the box "Tracer Source (TRACER_EMB)"

0690X000009Z2ZtQAK.png

And you shall use the UCPD Monitor tools to catch the trace 0690X000009Z2X9QAK.png

Interesting link for you

  1. Cube Monitor tools : https://www.st.com/en/development-tools/stm32cubemonucpd.html
  2. USB-PD user manual : https://www.st.com/content/ccc/resource/technical/document/user_manual/group1/aa/15/14/5d/f5/b8/4a/fc/DM00598101/files/DM00598101.pdf/jcr:content/translations/en.DM00598101.pdf

BR

Dominique

JChau
JChauAuthor
Associate II
July 24, 2019

Hi Dominique,

Yes, we do enabled tracer_emb from the start, unfortunately the board 3.3V buck failed (possibility due to all those mods on the board :( ) and our hardware guy is fixing it, so until the board work again there is nothing for me to do right now.

I do read your manual, also docs from USB.org, and even other guys source code for comparison, I have to say the USB-PD library is quite complex and take some time to familiar, functions keep calling here and there and together with RTOS the code size is much larger than we had think of (We love to work directly with registers :) ).

But again thank you a lot for your help! You are so kind and helpful!

JChau
JChauAuthor
Associate II
July 24, 2019

btw please let me ask here if we can output custom messages to tracer_emb for our board debugging purpose? will UCPD_Monitor output custom debug messages? And can I set the baud rate to lower rate like 115200?

Dominique
ST Employee
July 25, 2019

Hi John,

Yes our system allows to add your own debugging trace, please see below an extract from the user manual

BR

Dominique

0690X000009Z4x4QAC.png

JChau
JChauAuthor
Associate II
July 25, 2019

Hi Dominique,

Please find attached screen capture of USB-PD trace,

I now solved most of the problem and communication with device seems goes smooth, however after device sent a request, from your manual UM2552 USBPD_PE_RequestSetupNewPower should have been called after PE_SRC_TRANSITION_SUPPLY, and I have a debug trace simply write "SetupNewPower" to ensure that function is called, but as seen from the screenshot no such thing is written and break point there is not invoking confirms that function is not called at all, I guess that's why a soft reset/request loop keeps going on without success, can you please provide me some clues why is this happening?0690X000009Z5GLQA0.png

JChau
JChauAuthor
Associate II
July 26, 2019

And also after my board as a source sends hardreset with USBPD_PE_Request_HardReset, no USBPD_HR_STATUS_START_REQ callback is received after PE_SRC_HARD_RESET_TIMEOUT.

0690X000009Z6n1QAC.png

And btw I tried forcing a PS_RDY signal by focing SetupNewPower after EvaluateRequest, which in turn calling USBPD_PE_Request_CtrlMessage, but returned with USBPD_FAIL.

0690X000009Z6n6QAC.png

Below is the callback structure generated by STM32CubeMX

 static const USBPD_PE_Callbacks dpmCallbacks =
 {
 USBPD_DPM_SetupNewPower,
 USBPD_DPM_HardReset,
 USBPD_DPM_EvaluatePowerRoleSwap,
 USBPD_DPM_Notification,
 NULL,
 USBPD_DPM_GetDataInfo,
 USBPD_DPM_SetDataInfo,
 USBPD_DPM_EvaluateRequest,
 NULL,
 NULL,
 USBPD_PE_TaskWakeUp,
 NULL,
 NULL,
 NULL,
 USBPD_DPM_EvaluateDataRoleSwap,
 USBPD_DPM_IsPowerReady
 };

Please kindly help if again something is missing at my side, thank you!