【DigiKey好物畅享】ST NUCLEO-H7S3L8开发板 UCPD SINK设备实践

NUCLEO-H7S3L8开发板板载STM32H7S3L8 MCU,属于ST新一代Cortex-M7内核产品,主频可达600MHz。但是其在存储特性上不同于以往M7内核产品,以往的M7内核产品往往具有大容量Flash,用户代码可以直接放在片内Flash中由RAM加载执行。而对于STM32H7R/S系列产品,内部仅有64KB的Bootflash,通常用于存放bootloader,用于初始化硬件、加载启动Appli程序。
即有两种下载方式:

  1. 对于简单的应用程序代码,可以将bootloader和应用程序代码共同下载到Bootflash中,当MCU上电或复位后,首先运行bootloader,接着跳转运行到应用程序代码部分
  2. 对于复杂的应用程序代码,ST官方默认提供了XIP的bootloader,将该bootloader下载到Bootflash中。同时将Appli用户应用程序下载到外部Flash中。当MCU上电或复位后,首先运行bootloader中的代码进行硬件初始化,接着加载外部Flash中的Appli用于应用程序到RAM中运行。这种也是开发STM32H7R/S首选且主流的下载方式。
    本次主要使用NUCLEO-H7S3L8开发板板载的UCPD接口,开发一个SINK设备,用于从充电器Source设备取电的操作,并且使用STM32CubeMonUCPD进行监视,查看SINK和Source设备之间的协商过程。
    使用的硬件设备包括:NUCLEO-H7S3L8开发板、支持PD输出的充电器,具体如下图

NUCLEO-H7S3L8开发板板载一个TCPP03-M20 Type-c端口保护IC,用于为VBUS和CC线提供过压、过流和ESD防护等,同时可以通过更换开发板板载的R26电阻来切换VBUS上的过压检测阈值,最大功率支持100W,最大电压支持22V,如下图所示。

使用到的软件包括:keil-mdk用于编译下载程序、STM32CubeMonUCPD用于监视PD协商过程和信息、STM32_USBPD_Library用于实现SINK设备的核心协议栈(需要注意,ST关于这部分的代码是闭源,直接封库的,开发过程中只需要关注如何调用API即可,如果想深入了解,可以到USB-IF官网查看具体的规范)。
下面是初始化USBPD的核心代码。
USBPD_StatusTypeDef USBPD_DPM_InitCore(void)
{
/* variable to get dynamique memory allocated by usbpd stack */
uint32_t stack_dynamemsize;
USBPD_StatusTypeDef _retr = USBPD_OK;

/* CAD callback definition /
static const USBPD_PE_Callbacks dpmCallbacks =
{
NULL,
USBPD_DPM_HardReset,
NULL,
USBPD_DPM_Notification,
USBPD_DPM_ExtendedMessageReceived,
USBPD_DPM_GetDataInfo,
USBPD_DPM_SetDataInfo,
NULL,
USBPD_DPM_SNK_EvaluateCapabilities,
NULL,
USBPD_PE_TaskWakeUp,
#if defined(_VCONN_SUPPORT)
USBPD_DPM_EvaluateVconnSwap,
USBPD_DPM_PE_VconnPwr,
#else
NULL,
NULL,
#endif /
_VCONN_SUPPORT */
USBPD_DPM_EnterErrorRecovery,
USBPD_DPM_EvaluateDataRoleSwap,
USBPD_DPM_IsPowerReady
};

static const USBPD_CAD_Callbacks CAD_cbs =
{
USBPD_DPM_CADCallback,
USBPD_DPM_CADTaskWakeUp
};

/* Check the lib selected */
if (USBPD_TRUE != USBPD_PE_CheckLIB(LIB_ID))
{
_retr = USBPD_ERROR;
goto error;
}

/* to get how much memory are dynamically allocated by the stack
the memory return is corresponding to 2 ports so if the application
managed only one port divide the value return by 2 */
stack_dynamemsize = USBPD_PE_GetMemoryConsumption();

/* done to avoid warning */
(void)stack_dynamemsize;

/* Initialise the TRACE */
USBPD_TRACE_Init();

for (uint8_t _port_index = 0; _port_index < USBPD_PORT_COUNT; ++_port_index)
{
/* Variable to be sure that DPM is correctly initialized */
DPM_Params[_port_index].DPM_Initialized = USBPD_FALSE;

/* check the stack settings */
DPM_Params[_port_index].PE_SpecRevision  = DPM_Settings[_port_index].PE_SpecRevision;
DPM_Params[_port_index].PE_PowerRole     = DPM_Settings[_port_index].PE_DefaultRole;
DPM_Params[_port_index].PE_SwapOngoing   = USBPD_FALSE;
DPM_Params[_port_index].ActiveCCIs       = CCNONE;
DPM_Params[_port_index].VconnCCIs        = CCNONE;
DPM_Params[_port_index].VconnStatus      = USBPD_FALSE;

/* CAD SET UP : Port 0 */
CHECK_CAD_FUNCTION_CALL(USBPD_CAD_Init(_port_index,
                                       &CAD_cbs,
                                       &DPM_Settings[_port_index],
                                       &DPM_Params[_port_index]));

/* PE SET UP : Port 0 */
CHECK_PE_FUNCTION_CALL(USBPD_PE_Init(_port_index, (USBPD_SettingsTypeDef *)&DPM_Settings[_port_index],
                                     &DPM_Params[_port_index], &dpmCallbacks));

/* DPM is correctly initialized */
DPM_Params[_port_index].DPM_Initialized = USBPD_TRUE;

/* Enable CAD on Port 0 */
USBPD_CAD_PortEnable(_port_index, USBPD_CAD_ENABLE);

}

#ifdef _LOW_POWER
USBPD_LOWPOWER_Init();
#endif /* _LOW_POWER */

error :
return _retr;
}
通过初始化TRACE用于与STM32CubeMonUCPD交互通信,通过USBPD_CAD_Init初始化具体的Type-c端口,通过USBPD_PE_Init初始化协议栈策略引擎。
程序下载完成后的结果如下。

其中右上为板载Type-c接口插入支持PD输出的充电器后,Type-c接口的LED点亮。右下为插入充电器后,开发板和充电器之间的协商过程。首先,Source设备充电器向SINK设备开发板发出SRC_CAPABILITIES信息,告知SINK设备SOURCE充电器支持哪些输出选项,当SINK接收信息成功后发出GOODCRC应答;之后SINK根据策略引擎和硬件配置向Source充电器发出REQUEST请求合适的电压和电流,Source收到信息后发出GOODCRC应答;接着Source充电器根据当前自身功率需求选择是否接收请求的电压和电流配置,如果接受,发送ACCEPT信息,SINK设备收到信息后发出GOODCRC应答;最后一切准备就绪,Source发出PS_RDY信息,告知SINK设备,Source端已准备就绪,SINK设备收到信息后发出GOODCRC应答。至此,完成一次完整的PD协商过程。
总结:
STM32H7S3L8片上具有UCPD控制器,并且集成了PHY,兼容USB PD3.2,同时ST也针对该外设提供了封装好的PD库,可以非常方便的快速上手开发SINK或Source设备。