AnsweredAssumed Answered

STM32F429 USB bug on updating DIEPCTL register while EPENA set

Question asked by serb.sergey on Feb 20, 2016
Latest reply on Mar 2, 2016 by hornang
Hello and sorry for  my bad English )

I have a problem with FS USB Device (Embedded PHY) on STM32F429VGT6 MCU. 
I implemented custom USB "vendor device class" on top of ST USBD Core library and custom communication protocol between STM32 and PC. That device class consists of 1 interface (custom class) with control endpoint + 2 bulk endpoints (IN = 0x81, OUT = 0x01).  All endpoints max packet size == 64 bytes. On PC side, I am using WinUSB driver.

PC can communicate with MCU without problems, restore protocol connection and so on! So, my problem lies in connection restore routine in protocol layer.

Why I need protocol restore routine: if user application crashed in the middle of IN transaction then STM device left in state where some packets of protocol response are still in FIFO and protocol controller is waiting for TX FIFO is empty.  After restart of user application on PC side i need to clean up protocol controller state =>  read bytes in FIFO left from previous response! Otherwise I would not be able to correctly handle new responses (data from old broken response and new one would read as combined).

This part works as expected! 100% tested! But! I really want to make sure that after restarting user application device would function correctly, so, I’m using WinUSB_ResetPipe function before doing software protocol restore. WinUSB_ResetPipe is cleaning STALL condition and data toggle bit for pipe on host side + sends "clear feature" request to STM32 (to clear stall and data tggle bits too).

So, this is the bug! If I call WinUSB_ResetPipe then packets received from STM32 device are messed up! Their order is unpredictable! I am using hardware USB protocol analyzer for debugging and I can't understand logic of what I see there.

Moreover, this is not looks like data toggle bit mismatch, I am not just loosing packet (this is handled correctly by my connection restore routine), packets order is changed! And _part_ of content is discarded (that is strangest thing)! I am sending only 64 bit packets (Always!) but after clearing stall condition I receive zero length packet and 48 bytes packet! I do not understand why 16 bytes from start of packet are discarded!

After some digging, I observed that even rewriting DIEPCTL register with it's own value causing all problems.

uint32_t val = USBx_INEP(1)->DIEPCTL;
USBx_INEP(1)->DIEPCTL=val;  //Next packets are messed up in IN endpoint!

After a bit more digging I found that this happens only if EPENA bit is set in DIEPCTL (aborted transaction due to user application crash on PC side).

So what's wrong with that bit?

Outcomes