Target description

This tutorial aims to help you to:

  • Use the X-NUCLEO-SRC1M1 shield that includes a TCPP02-M18 protection circuit and provides a USB Type-C® connector.
  • Create a USB legacy 3 A at 5 V Type-C source application with the NUCLEO-F446RE board that does not include any UCPD peripheral and the X-NUCLEO-SRC1M1 shield by using STM32CubeIDE software.


  • Computer with Windows 7 (or higher)


  • NUCLEO-F446RE (tested on rev C-04)[1]
  • X-NUCLEO-SRC1M1 shield[2]
  • USB PD Sink device (to test our USB source device, it can be the sink created in this wiki article, or a USB Type-C® mobile phone or device.)
  • USB cable Type-A to Mini-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]
  • X-CUBE-TCPP MCU firmware Package (BSP)[5]


  • UM1724 NUCLEO-F446RE User Manual
  • UM2973 X-NUCLEO-SRC1M1 User Manual

Create a USB PD source device

Clock.png Total 50min

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

Open STM32CubeIDE and create a new STM32 project. As a target selection, choose the NUCLEO-F446RE from the board selector tab.

STM32StepByStep 03 Start Project F4.png

Click on start project, then in the file menu, create a new folder at your project's name, and click on 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 and in the next steps, we will 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 resets the pinouts in the pinout view.

USBPD 0-pinoutConf.png

3.2. Select the X-CUBE-TCPP software pack

Click on the software packs menu.

STM32StepByStep 05 SP Menu SRC5V.png

Select the X-CUBE-TCPP software pack and enable its source without UCPD application, the tcpp0203 Board part, and the X-NUCLEO-SRC1M1 Board support.

STM32StepByStep 06 SP Select.png

3.3. Configure the system timebase

For this simple example, we use SysTick as the system timebase. In the system core section, select SYS and change the timebase source to SysTick.

USBnoPD 0 sysConf v2.png

3.4. Configure ADC peripheral

For this application, VBUS, CC1, and CC2 need to be monitored. To do it, an ADC needs to be configured to measure the VBUS voltage and current, CC1, CC2, and Vprovider.
As we are going to use the X-NUCLEO-SRC1M1 BSP, the ADC configuration does not need to be done in CubeMX.
As we need the ADC HAL drivers for it to work properly, we still need to configure the ADC in CubeMX for it to include the driver files, but the actual configuration and init function will not be called in our 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.5. Configure I2C peripheral

As the X-NUCLEO-SRC1M1 shield includes a TCPP02-M18 that communicates via I2C, we need to enable the I2C peripheral in our project.

In the connectivity section, enable I2C2 peripheral, in I2C mode. Leave the configuration as default, as the software pack reconfigures it.

USBPD 0-I2C2Conf.png

Note: We need to enable the I2C2 peripheral in the CubeMX view for code generation to include the I2C drivers as we do for the ADC.

3.6. Enable the software pack

In the middleware and software pack category, select the X-CUBE-TCPP software pack. Enable the 'source without UCPD' application, the 'tcpp0203' Board part and the 'X-NUCLEO-SRC1M1' Board support.

STM32StepByStep 07 SP Enable SRC5V.png

3.7. Check the clock configuration

Under clock configuration main tab.

USBnoPD 0 CLKConf2.png

4. Configure the project

Clock.png 5min

Under the project manager main tab, and the advanced settings tab, as we do not need the ADC and I2C initialization functions (handled by the BSP drivers), uncheck generate code for the MX_ADC1_Init and MX_I2C1_Init.

STM32StepByStep 09 Advanced SRC5V.png

5. Generate code

Clock.png 5min

Save your file with Ctrl+s and select generate code if prompted. You can also generate code from the STM32CubeIDE menu, clicking on project/generate code, or by pressing alt+K.

STM32StepByStep 10 Generate SRC5V.png

In this project, different folders can be found:

  • The core folder contains the source files for the core of the project.
  • The drivers folder contains the HAL drivers for the STM32, and the BSP for the Nucleo board and X-NUCLEO-SRC1M1 shield.
STM32StepByStep 11 Tree SRC5V.png

6. Configure the shield's jumpers

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

USBnoPD SRC1M1 Shield.jpg

On the NUCLEO-F446, place a link between PA3 (CN10 - 37) and PC4 (CN10 - 34).

This X-NUCLEO-SRC1M1 shield default configuration allows SINK to source up to 0.5 A at 5 V.
Plug an external 5 V source with current capability >0.6 A into the green "source" connector.
The current sense resistor R4 is 7 mOhms, then TCPP02 current protection level is 6A. Refer to TCPP02-M18 datasheet[6].

With this configuration, the board is powered by the ST-Link of the Nucleo board.
If you want to power your system from the external power supply connected to the "source" terminal, and not from the ST-Link, add the JP1 jumpers between 1-2 and 3-4.

Info white.png Information

To increase the solution current capability to 3 A at 5 V:

  • Remove the R35 and place it on SH19.
  • Remove the R39 and place it on SH21.
  • Replace the R4 sense resistor (initially 7 mOhms) with a 10 mOhms resistor.

Next, plug an external 5 V source with current capability > 4.5 A into the green "source" connector.

In SRC1M1_conf.h change the SRC1M1_ISENSE_RS value from 7 milliohms to 10 milliohms:

#define SRC1M1_ISENSE_RS                            10u  /* Current measure shunt resistor in milliohm */

7. Compile and run the application

The compilation must be performed without errors or warnings.
Build the application, clicking on the Built Button.png button (or select project/build project).
Run the application, clicking on the DownloadRun Button.png button (or select run/run).

8. Evaluate the application

Clock.png 5min

Vbus is active 120 ms after plugging a USB Type-C® source device.
Vbus is immediately shut down and placed in safe mode (0 V) when unplugging the sink device.
During connection, if an overcurrent or malfunction is detected, the source is placed in safe mode (0V) and needs a disconnection/reconnection to restart.

9. Information focus: Code inserted by the software pack

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

10. Project with a custom board

This chapter describes how to build a USB PD source application using a custom board with any STM32 MCU with five ADC channels.

Info white.png Information
Selected resources: ADC1-IN0, ADC1-IN1, ADC1-IN4, ADC1-IN10, ADC1-IN11, I2C1, PC4, and PC8, are for the example, replace by the custom board resources affectation.
  • As in the chapter 2, create the project.
  • As in the chapter 3.1, clear the pinout.
  • As per chapter 3.2, select the X-CUBE-TCPP software pack.

But do not select the board support for X-NUCLEO-SRC1M1 as your application is based on a custom board.

STM32StepByStep 12 Custom SP Selection SRC5V.png

  • Configure the ADC peripheral:

Five signals must be monitored to ensure proper and safe USB 3 A-5 V delivery:
CC1 and CC2 lines voltage, Vbus and Vprovider voltages and Iana, and the current through Vbus.
The ADC needs to be configured:
In the pin view, with a left click, select the pin PC0 and configure it as ADC1 Channel 10 (CC2).
Repeat the operation for PC1 as ADC1 Channel 11 (IANA); for PA0 as ADC1 Channel 0 (VBusc); for PA1 as ADC1 Channel 1(Vprov); and for PA4 as ADC1 Channel 4 (CC1).

USBnoPD 0 ADCConf.png

Note: it is not mandatory to set their name as each value is stored in a table by the DMA in function of its rank.

  • In the analog section click on ADC and select, in the parameter settings tab:

Scan conversion mode: Enabled
Continuous conversion mode: Enabled
Number of conversions: 5

STM32StepByStep 14 Custom ADC SRC5V.png

Define for each ADC input its channel and 84 cycles sampling time.
Rank 1: CC2: Channel 10
Rank 2: CC1: Channel 4
Rank 3: Vbus: Channel 0
Rank 4: Iana: Channel 11
Rank 5: Vprov: Channel 1

USBnoPD 2 ADCConf.png

  • Configure the DMA for ADC1:

In the system core section, select the DMA, tab DMA2 click on "add" and select ADC1 in the DMA2 request column.

USBnoPD 0 DMAConf.png

Set the DMA mode to circular.

USBnoPD 1 DMAConf.png

Then back to the ADC1 parameters configuration, set DMA continuous requests to enabled.

USBnoPD 3 ADCConf.png

  • Configure the I2C peripheral:

Enable the I2C connected to the TCPP02 I2C bus.
Set its speed in fast mode.

STM32StepByStep 14 Custom I2C SRC5V.png

  • Configure the GPIO:

Enable and configure the external interrupt input where the TCPP02 FLG signal is connected.
Select it in the pinout view.
In the GPIO category, set it as external interrupt mode with falling edge trigger detection.
Enable its pull-up.

STM32StepByStep 15 Custom FLG SRC5V.png

In the pinout view, select the GPIO output for TCPP02 enable.

STM32StepByStep 16 Custom GPIO SRC5V.png

  • Configure the timer:

In the timers section, select timer2: "TIM2", affect the "internal clock" as clock source.
In the parameter settings tab:

    • Set the internal clock division to no division; then the timer peripheral frequency is 84 MHz.
    • Set the prescaler value to 2099; then the timer counter frequency is 84 MHz / (2099+1) = 40 kHz.
    • Set the counter period to 39; then the timer period is 40 kHz / (39+1) = 1 ms.
    • Set auto-reload preload to enable.
USBnoPD 0 Tim2Conf2.png

Finally, select the NVIC settings tab to enable the TIM2 global interrupt.

USBnoPD 1 Tim2Conf.png

  • Enable the software pack:

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

STM32StepByStep 17 Custom SP Enable SRC5V.png

  • Assign resources to the application requirements:
STM32StepByStep 18 Custom SRC5V SP Platform.png

  • As in the chapter 4, configure the project.

But in the advanced settings keep ADC and I2C initialization code generation.

  • As in the chapter 5, generate the code.
  • As in the chapter 7, compile and run the application.

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

11. References