Create a USB-PD Sink Device 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
- Create a USB-PD Sink device using our STM32CubeIDE software
Prerequisites
- Computer with Windows 7 (or higher)
- Computer with Windows 7 (or higher)
Hardware
Software
- STM32CubeIDE (tested with V1.5.2) [4]
Literature
- UM2324 NUCLEO-G071RB User Manual
- UM2658 X-NUCLEO-USBPDM1 User Manual
- UM2773 X-NUCLEO-SNK1M1 User Manual
- AN5418 How to build a simple USB-PD sink application with STM32CubeMX
- How to Create a STM32G0 USB-PD Device with STM32CubeIDE.
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"
3 Configuring the Project
- Enter a name for the project and click Finish:
- 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.
- UCPD peripheral DMA configuration:
- UCPD peripheral interrupt activation:
- Configure FreeRTOS
- Activate FreeRTOS
- Use CMSIS V1
- Set Total heap size to 7000
- Set “eTaskGetState” parameter to Enabled :
- 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
- Detailed USBPD Stack Configuration:
- 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
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:
- Set Clock Tree to 64 MHz:
- 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
- In the NVIC Settings, enable the interrupts that are used in this application. This is a requirement when using our UCPD Middleware.
- 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
- In USBPD Middleware:
This is the last step to enable the trace:
- Activate TRACER_EMB
- In GUI_INTERFACE
- Check to enable
- Enter the Fields for HWBoards and PDType
- Project Manager/Project
In Project Manager tab, increase default heap size as follows:
- Minimum Heap Size : 0x500
- Minimum Stack Size : 0x400
- 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.
- 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:
- 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.
- Assemble the boards like this:
NOTE: if X-NUCLEO-SNK1M1 is used, follow this configuration:
- Assemble the boards like this:
- Load the code to the Nucleo and execute it:
- 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
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