Getting started with USB-Power Delivery Sink

Create a USB-PD Sink DeviceClock.png 45min

Target description
This tutorial enables to:

  • Use the X-NUCLEO-USBPDM1 or X-NUCLEO-SNK1M1 shield used includes a TCPP01-M12 protection circuit and provides a USB Type-C® connector
  • Create a USB-PD Sink Device with the NUCLEO-G071RB board and the X-NUCLEO-USBPDM1 or X-NUCLEO-SNK1M1

shield

  • Create a USB-PD Sink device using our STM32CubeIDE software

Prerequisites

  • Computer with Windows 7 (or higher)

Hardware

  • NUCLEO-G071RB (tested on rev B01) [1]
  • X-NUCLEO-USBPDM1 (tested on Rev 1) [2] or X-NUCLEO-SNK1M1 [3]
  • USB cable Type-A to Micro-B
  • USB Type-C® cable
  • A USB-PD source device to test our USB-PD device

Software

  • STM32CubeIDE (tested with V1.5.2) [4]

Literature

1 Installation of the software tools

In this part, the exercised software is STM32CubeIDE
To follow the installation instructions, refer to the wiki Tools installation article.

2 Launching the Project

Open STM32CubeIDE and create a New Project, then select the STM32G071RBT6 from the "MCU/MPU Selector Tab"

File:Intro1.png

3 Configuring the Project

  • Enter a name for the project and click Finish:

File:Picture2.png

  • Enable UCPD:

In this step, the UCPD peripheral is enabled and configured as a sink.

  • Activate UCPD1 in the Sink mode
  • No need to include “Dead Battery Signals” in the mode configuration as this is managed by the TCPP01 protection device on the X-NUCLEO-USBPDM1 shield.

File:Picture3a.png

  • UCPD peripheral DMA configuration:

File:Picture4.png

  • UCPD peripheral interrupt activation:

File:Picture5.png

  • Configure FreeRTOS
    • Activate FreeRTOS
    • Use CMSIS V1
    • Set Total heap size to 7000

File:Picture6a.png

  • Set “eTaskGetState” parameter to Enabled :

File:Picture7.png

  • Configure USBPD middleware
    • Select USBPD
    • Make the following Mode selections:
      • Port Configuration: Port 0: UCPD1
      • Stack Configuration: PD3 Full Stack
      • Timer service Source: TIM1
    • For PDO General Definitions, select the following:
      • Number of Sink PDOs for port 0: 1
      • Port 0 Sink PDO 1 0x26019096
      • The default PDO which is the default 5V FIXED PDO is kept

File:Picture8.png

  • Detailed USBPD Stack Configuration:

File:Picture9.png

  • Configure PB1 as ADC input, it is used for measuring the VBUS voltage (VBUS monitoring)
    • Clock prescaler : Synch /4
    • Enable Continuous conversion
    • Overrun data overwritten
    • Rank sampling time: 160.5 Cycles

File:Picture10.png

Rename the pin PB1 to VSENSE, a more descriptive name for the pin used for VBUS monitoring: File:Picture11.png

  • Add “constant Name” and “constant Value” in User Constants, this is used for calculations in the code:

File:Picture12.png

  • Set Clock Tree to 64 MHz:

File:Picture13a.png

  • Configure LPUART1 to ease debug:

For debugging purposes, a trace on a UART that is connected to the STM32CubeMonitor-UCPD can be enabled. Select LPUART1

  • Remap to PA2/3
  • And set DMA request for TX, then
  • Default settings

File:Picture14.png

  • In the NVIC Settings, enable the interrupts that are used in this application. This is a requirement when using our UCPD Middleware.

File:Picture15.png

  • Activate embedded tracer to ease debugging

This is very useful when developing a USB-PD application to enable the trace to get debug information sent to the STM32CubeMonitor-UCPD to provide the trace. In Utilities :

  • Activate TRACER_EMB
  • Set it to LPUART1

File:Picture16.png

  • In USBPD Middleware:

This is the last step to enable the trace:

  • Activate TRACER_EMB

File:Picture17.png

  • In GUI_INTERFACE
    • Check to enable
    • Enter the Fields for HWBoards and PDType

File:Picture18.png

  • Project Manager/Project

In Project Manager tab, increase default heap size as follows:

  • Minimum Heap Size : 0x500
  • Minimum Stack Size : 0x400

File:Picture19.png

  • Project Manager/Code Generator
    • In the Code Generator tab, STMicroelectronics recommends checking the “Add necessary library files as reference”
    • Using this mode, STMCubeIDE does not copy anything from the repository. The project uses drivers from the STM32Cube repository directly.

File:Picture20.png

  • Project Manager/Advanced Settings
    • LPUART is selected as LL to save a bit of memory heap size

LL stands for Low Layer Drivers which are optimized drivers.
File:Picture21.png

  • Save the project to generate code:
    • Answer Yes

In this simple application the described warning has no impact but for a more complex application follow the warning described below: File:Picture22.png

  • Code to be added:

In Core/Src/main.c:

/* USER CODE BEGIN ADC1_Init 2 */
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start(&hadc1);
/* USER CODE END ADC1_Init 2 */

In Core/Src/stm32g0xx_it.c:

/* USER CODE BEGIN SysTick_IRQn 0 */
#if defined( _GUI_INTERFACE)
GUI_TimerCounter(); /* needed with GUI_Interface */
#endif
/* USER CODE END SysTick_IRQn 0 */

In USBPD/usbpd_dpm_user.c:

In USBPD_DPM_GetDataInfo function:

case USBPD_CORE_DATATYPE_SNK_PDO: /*!< Handling of port Sink PDO, requested by get sink capa*/
USBPD_PWR_IF_GetPortPDOs(PortNum, DataId, Ptr, Size);
*Size *= 4;
break;

In USBPD/usbpd_dpm_user.c: In USBPD_DPM_SNK_EvaluateCapabilities function:

/* USER CODE BEGIN USBPD_DPM_SNK_EvaluateCapabilities */
USBPD_SNKRDO_TypeDef rdo;
/* Initialize RDO */
rdo.d32 = 0;
/* Prepare the requested pdo */
rdo.FixedVariableRDO.ObjectPosition = 1;
rdo.FixedVariableRDO.OperatingCurrentIn10mAunits = 50;
rdo.FixedVariableRDO.MaxOperatingCurrent10mAunits = 50;
rdo.FixedVariableRDO.CapabilityMismatch = 0;
*PtrPowerObjectType = USBPD_CORE_PDO_TYPE_FIXED;
*PtrRequestData = rdo.d32;
/* USER CODE END USBPD_DPM_SNK_EvaluateCapabilities */

In USBPD/usbpd_pwr_user.c:

/* USER CODE BEGIN include */
#include "main.h"
/* USER CODE END include */

/* USER CODE BEGIN BSP_USBPD_PWR_VBUSGetVoltage */
/* Check if instance is valid */
int32_t ret = BSP_ERROR_NONE;
if ((Instance >= USBPD_PWR_INSTANCES_NBR) || (NULL == pVoltage))
{
ret = BSP_ERROR_WRONG_PARAM;
*pVoltage = 0;
}
else
{
uint32_t val;
val = __LL_ADC_CALC_DATA_TO_VOLTAGE( VDDA_APPLI, \
LL_ADC_REG_ReadConversionData12(ADC1), \
LL_ADC_RESOLUTION_12B); /* mV */
/* X-NUCLEO-USBPDM board is used */
/* Value is multiplied by 5.97 (Divider R6/R7 (40.2K/200K) for VSENSE) */
val *= 597;
val /= 100;
*pVoltage = val;
}
return ret;
/* USER CODE END BSP_USBPD_PWR_VBUSGetVoltage */
  • Compile the code:

File:Picture23b.png

  • Hardware settings:

TCPP01 board set-up for Nucleo-G0: Place jumpers on the X-NUCLEO-USBPDM1 shield as shown in the picture. This is to configure the board for the target STM32G0.

Picture24.png

  • Assemble the boards like this:

File:Picture25.png


NOTE: if X-NUCLEO-SNK1M1 is used, follow this configuration: NewShield.PNG

  • Assemble the boards like this:

File:NewAssembly.PNG

  • Load the code to the Nucleo and execute it:

File:Picture26a.png

  • Check the contract made (meaning that the USPB communication was successful between the source and the sink) with “STM32CubeMonitor-UCPD” when the USB Type-C® cable is plugged on the Shield into a USB-PD source

File:Picture28a.png

To understand the trace above here are some explanations:
This is the USB-PD communication between the STM32G0 and the source.
IN: sent by the Source
OUT: sent by the STM32G0
The ACCEPT and PS_READY are sent by the source

4 References