Skip to main content
Associate
July 10, 2026
Question

The STM32G431 API of USB double‑buffer transmit‑complete interrupt processing contains a bug.

  • July 10, 2026
  • 1 reply
  • 12 views

After I configure EP1 to the double‑buffered mode, debugging reveals an issue inside stm32g4xx_hal_pcd.c. At line 1761, the endpoint register value is read. After executing PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex); to clear the interrupt flag, the actual register content has already been updated. However at line‑1906, (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal); still receives the register value captured before interrupt‑flag clearing. This triggers incorrect conditional judgements inside the HAL_PCD_EP_DB_Transmit() function.

Probable root‑cause: When transmitting data for the first time under double‑buffered setup, USB_EPStartXfer populates both buffers by default. After Buffer‑0 finishes transmission and triggers an interrupt, the program reads register data at line‑1761 of stm32g4xx_hal_pcd.c. Right after this read operation, Buffer‑1 also completes its transmission and updates the endpoint register. Since HAL_PCD_EP_DB_Transmit uses the stale register value obtained earlier rather than the latest value, abnormal behaviour occurs.

Besides, are there any sample project for USB double‑buffered RX‑TX operation?

captured endpoint register value
The input value is inconsistent with the actual current value.

 

1 reply

ST Technical Moderator
July 10, 2026

Hi ​@LuoMing 

Thank you for the detailed analysis and screenshots.

Can you please provide a minimal firmware project that reproduces the issue on my side?

To give better visibility on the answered topics, please click on "Best answer" on the reply which solved your issue or answered your question.Best regards,FBL
LuoMingAuthor
Associate
July 10, 2026

I selected the CDC class inside CubeMX and made modifications based on the generated project. During debugging, I observed that after the second data transmission via the CDC_Transmit_FS API upon each reset cycle, the MCU responds to nearly all IN‑requests from the host. I carried out numerous revisions to fix this issue, which makes it impossible for me to provide a stripped‑down version of my current project.

I regenerated a CDC‑based project with CubeMX and re‑assigned endpoints: EP1 for CDC‑CMD, EP2 as the IN endpoint and EP3 as the OUT endpoint. EP2 and EP3 are configured in double‑buffered mode.

During testing: When send_cmd is set to 1 for the first time, the MCU transmits data frames normally and replies with NAK to all subsequent host IN‑requests without triggering the CTR interrupt. However, once send_cmd is set to 1 a second time, the MCU continuously answers host IN‑requests and causes frequent CTR‑interrupt triggering. Could you advise how I can resolve this‑behaviour?