Hi Phil
Some time in June 2021 I had an experience with USB-MSD that would not operate well although the code is several years old and hadn't behaved like this before. With Windows 10 and possibly after a Windows update.
My feeling is that something has been sped up in the enumeration/initialisation and what I saw was that set-ups with data were sent while previous handshakes had no yet completely terminated (queued) and what would happen is that the receiver in the HW would lose synch with the data toggling and drop a reception frame believing its data toggle was incorrect. This causes the host to wait maybe 10..15s and then reset and re-enumerate where is would often then work.
To (hopefully) resolve this 'race-state' I added a modification to kinetis_USB_FS_OTG.h as follows:
07.06.2021 Resynchronise data buffers when sending status stage to ensure no race state on subsequent SETUP reception+ DATA {14}
If you have access to this (it is in branch V2.0.0 of the GIT repository) you may find that it solves the issue - I haven't seen it since but haven't used USB device on the Kinetis a great deal since then.
This is the actual modification that you could build in otherwise, in fnProcessInput():
switch (fnUSB_handle_frame(ucFrameType, (unsigned char *)ptUSB_BD_rx->ptrUSB_BD_Data, iEndpoint_ref, ptrUSB_HW)) { // generic handler routine
case TERMINATE_ZERO_DATA: // send zero data packet to complete status stage of control transfer
if (iEndpoint_ref == 0) { // {14} resynchronise data buffers when sending status stage
if (&ptEndpointBD->usb_bd_rx_even == ptUSB_BD_rx) {
ptEndpointBD->usb_bd_rx_even.ulUSB_BDControl |= (DATA_1);
ptEndpointBD->usb_bd_rx_odd.ulUSB_BDControl &= ~DATA_1;
ptEndpointBD->usb_bd_rx_odd.ulUSB_BDControl |= OWN;
}
else {
ptEndpointBD->usb_bd_rx_odd.ulUSB_BDControl |= (DATA_1);
ptEndpointBD->usb_bd_rx_even.ulUSB_BDControl &= ~DATA_1;
ptEndpointBD->usb_bd_rx_even.ulUSB_BDControl |= OWN;
}
}
*ptrUSB_HW->ptr_ulUSB_BDControl = (OWN | ptrUSB_HW->ptrEndpoint->ulNextTxData0); // transmit a zero data packet on control endpoint
_SIM_USB(0, USB_SIM_TX, iEndpoint_ref, ptrUSB_HW);
ptrUSB_HW->ptrEndpoint->ulNextTxData0 ^= DATA_1; // toggle the data packet
It utilises the point when it is sending a zero frame status stage (just before the host will be allowed to send further sequences) to reset the rx toggle buffer to be sure that they are both ready to receive data 0 and data 1 tokens Previously there was a very small window where the data toggle may not have been correct in both and when the host very quickly sends a following setup and data to the two one may not be correct and thus the data dropped (since the HW thinks it is a repetition it ACKs it though, so the host thinks all is good but times out waiting for the actual response).
Regards
Mark