Getting started with USB-Power Delivery Sink

Target description

This tutorial helps to:

  • Use the X-NUCLEO-SNK1M1 shield that 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-SNK1M1 using STM32CubeMX software


  • Computer with Windows 7 (or higher)


  • NUCLEO-G071RB (tested on rev B01) [1]
  • X-NUCLEO-SNK1M1 (tested on Rev 1) [2]
  • A USB-PD source device to test our USB-PD device (it can be a PD capable wall charger, a power bank, etc.)
  • USB cable Type-A to Micro-B
  • USB Type-C® to Type-C® cable


  • STM32CubeMX (tested with V6.11.0 - minimal release 6.11.0) [3]
  • STM32CubeIDE (tested with V1.14.0) [4]
  • STM32CubeMonitor-UCPD (tested with V1.3.0) [5]
  • X-CUBE-TCPP MCU Firmware Package (BSP) [6]


Create a USB-PD Sink Device

Clock.png Total 45min

1. Software pack installation

Open STM32CubeMX, in the software pack area, click on the install/remove button.

STM32StepByStep Install SP 1bis.png

Then select the STMicroelectronics tab, scroll down to the X-Cube-TCPP software pack, and click on the install button if it is not already installed.

STM32StepByStep Install SP 2.png

2. Creating the project

Clock.png 5min

In STM32CubeMX, create a new STM32 project. As a target selection, choose the NUCLEO-G071RB from the Board Selector Tab.

STM32StepByStep 03 Start Project G0.png

Click "Start Project", then in the file menu, create a new folder under your project's name, and click "Save".

STM32StepByStep 04 Save Project as.png

When prompted for initializing peripherals with their default mode, click No.

3. Configuring the system

Clock.png 15min

At this point, your project is created. The next steps show how to configure the peripherals and options needed for the project.

3.1. Clear the pinout

To start from a blank configuration, click on the Pinout menu and select Clear Pinouts. This will reset the pinouts in the Pinout view.

USBPD 0-pinoutConf.png

3.2. Select the X-CUBE-TCPP software pack

From the software pack menu:

STM32StepByStep SP Menu v4.png

Select the X-CUBE-TCPP Software pack and enable its Sink application, the tcpp01 board part, and the X-NUCLEO-SNK1M1 board support.

STM32StepByStep 06 SP Select SNK.png

3.3. Configure UCPD peripheral

In the Connectivity tab, select the UCPD1 peripheral and enable it in sink mode. Under the NVIC Settings tab, enable UCPD global interrupts.

Info white.png Information
You do not need to include “Dead Battery Signals” in the configuration as this is managed by the TCPP01 protection device on the X-NUCLEO-SNK1M1 shield.

Under the DMA Settings tab, add UCPD1_RX and UCPD1_TX DMA requests. Select DMA1 channel 4 for RX and DMA1 channel 2 for TX.

USBPD 1-UCPD1Conf.png

3.4. Configure FreeRTOS Middleware

In the Middleware section, enable FreeRTOS with CMSIS_V1 interface. Under the Config Parameters tab, change "TOTAL_HEAP_SIZE" to 7000 bytes.


Info white.png Information

If an STM32G4 is used instead of a G0, LIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY needs to be set to 3 instead of STM32CubeMX's default value 5. In some cases with STM32G4, leaving it set to 5 causes the code execution to get stuck in the vPortValidateInterruptPriority function.

3.5. Configure USBPD Middleware

In the Middleware section, enable USBPD with the following configuration:

  • Port configuration: Port 0: UCPD1
  • Stack configuration: PD3 Full Stack
  • Timer service source: TIM1

Under the PDO General Definitions tab, verify the following configuration:

  • Number of Sink PDOs for port 0: 1
  • Port 0 Sink PDO 1 0x00019096 (corresponds to a 5V / 1.5A, dual-role data sink)

The following table is extracted from USB Power Delivery Specification, Table 6-14 Fixed Supply PDO - Sink. Used values and associated decoding for this project have been added to the table.

Bit(s) Description Used value Decoding
B31..30 Fixed supply 00b Fixed
B29 Dual-Role Power 0b No
B28 Higher capability 0b No
B27 Unconstrained Power 0b No
B26 USB Communications Capable 0b No
B25 Dual-Role Data 0b No
B24..23 Fast Role Swap support 00b No
B22..20 Reserved - Must be set to zero 0b No
B19..10 Voltage in 50mV units 0001100100b 5V
B9..0 Maximum current in 10mA units 0010010110b 1.5A

3.6. Configure ADC peripheral

For the Power Delivery stack to work, VBUS needs to be monitored. To do it, an ADC needs to be configured to measure the VBUS voltage and current.
As the X-NUCLEO-SNK1M1 BSP is used here, the ADC configuration is not needed in CubeMX.
As the ADC HAL drivers are needed for it to work properly, it is still necessary to configure the ADC in CubeMX for it to include the driver files, but the actual configuration and init function are not called in this project.

In the Analog section, enable ADC1 peripheral channel 0. Leave the configuration as default, as the software pack reconfigures it.

USBPD 0-ADC1Conf.png

3.7. Enable the software pack

In the middleware and software pack category, select the X-CUBE-TCPP software pack. Enable the 'Source' application, the 'tcpp01' board part, and the 'X-NUCLEO-SNK1M1' board support.

STM32StepByStep 07 SP Enable SNK.png

3.8. Configure the clocks

Under the Clock Configuration main tab, change the system clock mux to PLLCLK. It sets the HCLK clock to 64 MHz.


Info white.png Information
The mandatory settings for the simple USB-PD sink application are finished.

The following part is highly recommended for debugging

3.9. [OPTIONAL] Configure Tracer for debug

3.9.1. Configure LPUART

On the STM32G0 Nucleo-64 board, the Virtual COM port connected to the ST-LINK is the LPUART1.

Warning white.png Warning
The default STM32CubeMX pins used by LPUART1 must be changed to match the STM32G0 Nucleo-64 hardware:
  • PA2 for TX
  • PA3 for RX

In the Connectivity section, enable LPUART1 in asynchronous mode, and baud rate to 921600 bauds. Leave the rest as default.


In the pinout view, left-click PA2 and PA3 to remap them to LPUART1_TX and LPUART1_RX.


Under the DMA Configuration tab, add a request for LPUART1_TX. Use DMA1 channel 3.


Finally, under the NVIC Settings tab, enable LPUART1 global interrupts.


3.9.2. Configure embedded tracer

In the Utilities section, select TRACER_EMB and use LPUART1 as the trace source.


Then, go back to the USBPD middleware configuration and check the Tracer Source checkbox.


3.9.3. Configure UCPD monitor firmware responder for debug

The firmware interactive stack responder can be activated if interaction with the USB-PD stack is needed, using the UCPD monitor tool. STM32CubeMonUCPD. GUI can be activated only with tracer. In the "Utilities" section, enable GUI_INTERFACE, then enter free text to describe the board.


4. Configure the project

Clock.png 5min

Under the Project Manager main tab, configure the minimum stack size to 0xC00 under the Project tab. This is a first value, which can be tuned later, depending on application needs.

STM32StepByStep 08 Config Proj SNK.png

For STM32G0 or G4 MCU, uncheck “Use default firmware location” and instead, select the Software pack “c:|\user\ … \STM32Cube\Repositoryctronics/Packs\STMicroelectronics\X-CUBE-TCPP\V4.1.0\” as the firmware location to be sure to use the latest USBPD lib releases, as the standard evolution is very fast.

STM32StepByStep 08 Config Proj2 SNK.png

Under the Advanced Settings tab, change the LPUART driver to LL to save a bit of memory heap size. As ADC initialization functions are not needed (handled by the BSP drivers), uncheck Generate Code for the MX_ADC1_Init functions.

STM32StepByStep 09 Advanced SNK.png

5. Generate the code

Clock.png 5min

Save your file with Ctrl+s and select generate code.

STM32StepByStep 10 Generate SNK.png

A warning appears, informing that a proper HAL time base is not defined. It is safer to use a dedicated timer as a HAL time base source.
For this demonstration, the below warning can be ignored by clicking Yes.


Info white.png Information
This becomes the recommended standard way of working in the forthcoming firmware package deliveries, especially when using CMSIS OS V2, which defines Systick as FreeRTOS™ time base.

For this demonstration, the warning can be ignored by clicking Yes.


6. Configure the shield's jumpers

Place jumpers on the X-NUCLEO-SNK1M1 shield as shown in the picture.


7. Compile and run the application

The compilation must be performed without error or warnings.
Build the application by clicking on the Built Button.png button (or select Project/Build Project).
Run the application by clicking on the DownloadRun Button.png button (or select Run/Run).

8. Establish the first explicit contract

Clock.png 5min

With your application running on the board, launch the STM32CubeMonitor-UCPD application. The user's board must appear in the list when clicking "Refresh list of connected boards". Double click on the corresponding line (or click "NEXT").


Note: The ComPort may be different. It depends on the number of boards installed on the computer. Double click on the desired UCPD port, here Port 0, or select it and click "NEXT".


Click on the TRACES button in the bottom right corner to get protocol traces. You can then plug a power delivery source into the USB Type-C® receptacle of the X-NUCLEO-SKN1M1 shield. The screen may look like this:


The figure above shows the communication between the STM32G0 and the power delivery source on the right panel. It is possible to verify the correct sequence to reach an explicit contract:

  1. The capabilities are sent by the source (IN green message).
  2. The request is sent by the STM32G0 (OUT orange message).
  3. The ACCEPT and the PS_RDY are sent by the source (IN green message).
  4. The contract negotiation ends by the POWER_EXPLICIT_CONTRACT notification (blue message).

For more details on how to use this tool, refer to UM2468. And for more details on the protocol, refer to UM2552. Note that this trace is very helpful for debugging and application development.

9. Information focus : Code inserted by the software pack

By enabling the software pack in section 3.7, the code below has been added automatically in the following files:

You can find other applicative examples on GitHub: x-cube-tcpp

10. Project with a custom board

This chapter allows building an USBPD source application using a custom board with an STM32 MCU from series G0, G4, H5, L5, or U5 that includes the UCPD peripheral.

Info white.png Information
Selected resources: ADC1-IN9, PB6, and PC10, are for the example, replaced by the custom board resources affectation.
  • As in chapter 2: Create the project
  • As in chapter 3.1: Clear the pinout
  • As in chapter 3.2: Select the X-CUBE-TCPP software pack

Do not select the board support for X-NUCLEO-SNK1M1, as your application is based on a custom board.

STM32StepByStep 12 Custom SP Selct SNK.png

  • As in chapter 3.3: Configure UCPD Peripheral
  • As in chapter 3.4: Configure FreeRTOS Middleware
  • As in chapter 3.5: Configure USBPD Middleware
  • Configure ADC Peripheral

Select and configure the ADC and its channel on which Vbus is connected for monitoring. Select the ADC and its channel. Adjust the clock prescaler. Keep 12 Bits resolution. Enable the continuous conversion mode, and set a medium cycle sampling time.

STM32StepByStep 13 Custom ADC SNK.png

  • Configure GPIO

In the Pinout view, select the GPIO output for TCPP01 VCC and a second GPIO output for TCPP01 DB.

STM32StepByStep 14 Custom GPIO SNK.png

  • Enable the software pack

In the middleware category, select the X-CUBE-TCPP software pack and enable its application and board part.

STM32StepByStep 15 Custom SP Enable SNK.png

  • Assign resources to the application requirements
STM32StepByStep 16 Custom SP Platform SNK.png

  • As in chapter 4: Configure the project

However, in the Advanced settings, keep ADC initialization code generation.

  • As in chapter 5: Generate code
  • As in chapter 7: Compile and run the application

11. References