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;
}
// ...
}
2026-05-18 2:34 AM
Hi @mhd0425
Thank you for raising this important point regarding TCPP03 FLGn interrupt handling in a FreeRTOS environment.
I was wondering what was the the fault to trigger EXTI IRQ handler?
The interrupt flow you highlighted, where the EXTI handler reaches BSP_USBPD_PWR_EventCallback() may trigger blocking I2C access to read TCPP03 status registers.
It would be more helpful to attach minimum firmware project to reproduce the issue on our reference boards.
We have escalated this case CDM0062712 to our dedicated teams for confirmation of the intended behavior and recommended implementation approach in RTOS-based applications.
Once we receive their feedback, we will come back to you with a precise answer.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2026-05-18 5:01 PM
Hi @FBL ,
Thank you for following up.
Generating the default project for X-NUCLEO-DRP1M1 reference board following the wiki will include the FLGn interrupt handling with I2C.
From the datasheet section 7.1 FLGn pin description:
In hibernate and low power modes FLGn indicates voltage presence on VBUS.
In normal mode, FLGn indicates an error (OVP, OCP or OTP): I2C registers must be read to identify the error.
This might not be inherently bad if all the G0 is doing is UCPD, but adding any other peripheral, battery charger, or user thread becomes tricky.