I have added a kick-start (below) to my code and now the device enumerates every time directly or through a hub to Windows or Mac, but there is a new issue.
It isn't a new issue, you are still trapped in the PIC SETUP timing issue.
Your workaround (
delayed start) suppresses your firmware activity other than control transfer process, until Set_Configuration comes on the "enumeration". In this way, you gave timing priority to the control transfer process until Set_Configuration.
But as you said, "enumeration" doesn't always finish with Set_Configuration. Rather, it is rare case for OS class drivers. Usually, more requests come from host after Set_Configuration. For example,
- Windows HID driver puts Get_Descriptor( Report Descriptor ) and Set_Idle just after Set_Configuration.
- Windows CDC driver puts Get_Line_Coding and Set_Control_Line_State
- Most of OS puts Get_Max_LUN for MSC
- MacOSX often puts many Get_Descriptor( String ) for most of classes.
etc.
For the radical solution of this timing issue, apply ping-pong buffers to the PIC EP0 OUT. But it's beyond modification of stack users. Request it to the provider of the PIC USB device stack for better implementation. I believe the PIC SIE designer has added EP0_OUT_ONLY ping-pong option for this purpose. It is the responsibility of USB stack programmers to apply this option.
Other than PIC, this SETUP timing issue potentially occurs on a couple of other SIE designs, which require firmware intervention to accept the next SETUP transaction after the last control transfer. For instances,
- Freescale MC9S08JM/MM, MCF51JM
- ST Micro STM32F102-3, STR71/73/91
- TI MSP430x5xx/x6xx
Usually, USB device stacks for these MCUs apply hardware interrupt to process USB events. Therefore, this timing issue is hidden. But it'll be revealed under heavy piled-up interrupts, which disturbs USB interrupt more than 100us. Stress test is recommended for critical applications.
Fortunately, the majority of SIEs are well designed on this aspect. The SIEs on these MCUs always accept SETUP transaction automatically, and the SIEs notify it to firmware. The firmware on these chips enjoys easy timing on SETUP handling.
- Atmel AT90USB, SAM7X, SAM3U
- Cypress EZ-USB FX2
- NXP LPC ARM family
- Renesas uPD78F, H8SX, SH2/3
- SiLabs C8051F32x/34x
- ST Micro STM32F105-7
- TI Stellaris LM3S5x/9x
Tsuneo