Target description
- This tutorial enables you to:
- Use the X-NUCLEO-USBPDM1 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 shield
- Create a USB-PD Sink device using our STM32CubeIDE software
Prerequisites
- Computer with Windows 7 (or higher)
Hardware
- NUCLEO-G071RB (OR: Add revision)[1]
- X-NUCLEO-USBPDM1 (OR: Add revision)[2]
- USB cable Type-A to Micro-B
- USB Type-C cable
- A USB-PD source device to test our USB-PD device
Software
- STM32CubeIDE (OR: Add revision)[3]
Literature
- NUCLEO-G071RB User Manual[4]
- X-NUCLEO-USBPDM1 User Manual[5]
- AN5418[6]
- How to Create a STM32G0 USB-PD Device with STM32CubeIDE.
1. Steps
1.1. Installation of the software tools
In this part, the software we will be working on are STM32CubeIDE
To follow the installation instructions, please refer to the wiki Tools installation article.
1.2. Launching the Project
Open STM32CubeIDE and create a New Project, then select the STM32G071RBT6 from the "MCU/MPU Selector Tab"
File:STM32StepByStep:Picture1.png
1.3. Configuring the Project
- Enter a name for the project and click Finish:
File:STM32StepByStep:Picture2.png
- Enable UCPD:
In this step we will enable and configure the UCPD peripheral, we will configure it as a sink.
- Activate UCPD1 in 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:STM32StepByStep:Picture3a.png
- UCPD peripheral DMA configuration:
File:STM32StepByStep:Picture4.png
- UCPD peripheral interrupt activation:
File:STM32StepByStep:Picture5.png
- Configure FreeRTOS
- Activate FreeRTOS
- Use CMSIS V1
- Set Total heap size to 7000
File:STM32StepByStep:Picture6.png
- Set “eTaskGetState” parameter to Enabled :
File:STM32StepByStep: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
- We will keep the default PDO which is the default 5V FIXED PDO
File:STM32StepByStep:Picture8.png
- Detailed USBPD Stack Configuration:
File:STM32StepByStep:Picture9.png
- Configure PB1 as ADC input, it will be 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:STM32StepByStep:Picture10.png
Rename the pin PB1 to VSENSE, a more descriptive name for the pin used for VBUS monitoring:
File:STM32StepByStep:Picture11.png
- Add “constant Name” and “constant Value” in User Constants, this will be used for calculations in the code:
File:STM32StepByStep:Picture12.png
- Set Clock Tree to 64 MHz:
File:STM32StepByStep:Picture13.png
- Configure LPUART1 to ease debug:
For debug purposes we can enable a trace on a UART that will be connected to the STM32CubeMonitor-UCPD. Select LPUART1
- Remap to PA2/3
- And set DMA request for TX, then
- Default settings
File:STM32StepByStep:Picture14.png
- In the NVIC Settings, enable the interrupts that will be used in this application . This is a requirement when using our UCPD Middleware.
File:STM32StepByStep:Picture15.png
- Activate embedded tracer to ease debug
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:STM32StepByStep:Picture16.png
- In USBPD Middleware:
This is the last step to enable the trace:
- Activate TRACER_EMB
File:STM32StepByStep:Picture17.png
- In GUI_INTERFACE
- Check to enable
- Enter the Fields for HWBoards and PDType
File:STM32StepByStep:Picture18.png
- Project Manager/Project
In Project Manager tab, increase default heap size as follows:
- Minimum Heap Size : 0x500
- Minimum Stack Size : 0x400
File:STM32StepByStep: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 repository. Project uses drivers from STM32Cube repository directly.
File:STM32StepByStep: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:STM32StepByStep:Picture21.png
- Save the project to generate code:
- Answer Yes
In this simple application the warning described will not have an impact but for a more complex application please follow the warning described below:
File:STM32StepByStep: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:STM32StepByStep:Picture23.png
- Hardware settings:
TCPP01 board set-up for Nucleo-G0: Please place jumpers on the X-NUCLEO-USBPDM1 shield as shown in the picture. This is to configure the board for the target STM32G0.
File:STM32StepByStep:Picture24.png
- Assemble your boards like this:
File:STM32StepByStep:Picture25.png
- Load the code to the Nucleo and execute it:
File:STM32StepByStep:Picture26.png
- Check the contract made (meaning that the USPB communication was successful between the source and the sink) with “STM32CubeMonitor-UCPD” when you plug the Type-C cable on the Shield to a USB-PD source
File:STM32StepByStep: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
1.4. References