2026-04-26 12:59 PM - last edited on 2026-04-27 3:07 AM by Amel NASRI
Hello, I am developing a project using the TCPP03 (X-NUCLEO-DRP1M1) and the ST USB-PD stack on an STM32G0 with FreeRTOS.
I am concerned about the thread safety of the FLGn interrupt handling. In the standard BSP examples, the EXTI interrupt calls BSP_USBPD_PWR_EventCallback().
2026-04-28 6:49 AM
Hello @mhd0425
@mhd0425 wrote:I am concerned about the thread safety of the FLGn interrupt handling. In the standard BSP examples, the EXTI interrupt calls BSP_USBPD_PWR_EventCallback().
Which BSP example ?
2026-04-28 10:59 AM
Hi Saket_Om,
X-CUBE-TCPP 4.2.0 downloaded from ST or GitHub. I followed this guide:
https://wiki.st.com/stm32mcu/wiki/STM32StepByStep:Getting_started_with_USB-Power_Delivery_Dual_Role
When a fault occurs, EXTI IRQ Handler is triggered.
// File: TCPP/App/app_tcpp.c:60
void TCPP0203_PORT0_FLG_EXTI_IRQHANDLER(void)
{
BSP_USBPD_PWR_EventCallback(USBPD_PWR_TYPE_C_PORT_1);
TCPP0203_PORT0_FLG_EXTI_CLEAR_FLAG();
}
The IRQ handler calls the BSP layer EventCallback.
// File: Drivers/BSP/X-NUCLEO-DRP1M1/drp1m1_usbpd_pwr.c:1400
void BSP_USBPD_PWR_EventCallback(uint32_t PortNum)
{
// ...
case USBPD_PWR_HW_CONFIG_TYPE_TCPP03:
PWR_TCPP0203_EventCallback(PortNum); // Calls the internal event handler
break;
}
The internal event callback function immediately performs a register read over I2C to determine the cause of the interrupt.
// File: Drivers/BSP/X-NUCLEO-DRP1M1/drp1m1_usbpd_pwr.c:1897
static void PWR_TCPP0203_EventCallback(uint32_t PortNum)
{
uint8_t flg_reg;
// ...
/* Read Flags register (FLGn) via I2C */
if (USBPD_PWR_PortCompDrv[PortNum]->ReadFlagRegister(&USBPD_PWR_PortCompObj[PortNum], &flg_reg) == TCPP0203_OK)
{
// ... Logic to handle faults (may also call WriteCtrlRegister which is another I2C write)
}
}
The ReadFlagRegister function maps to the component driver:
// File: Drivers/BSP/Components/tcpp0203/tcpp0203.c:762
int32_t TCPP0203_ReadFlagRegister(TCPP0203_Object_t *pObj, uint8_t *pFlagRegister)
{
return tcpp0203_read_reg(&pObj->Ctx, TCPP0203_FLAG_REG, pFlagRegister, 1);
}
The driver calls the BSP layer:
// File: Drivers/BSP/X-NUCLEO-DRP1M1/drp1m1_bus.c:377
int32_t BSP_I2C_ReadReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length)
{
// Final HAL I2C Call
if (HAL_I2C_Mem_Read(&TCPP0X_HANDLE_I2C, DevAddr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 0x1000) == HAL_OK)
{
return BSP_ERROR_NONE;
}
// ...
}