Content originally posted in LPCWare by doogul on Sat Jul 11 12:33:43 MST 2015
Well, I did some more testing this morning and I think I can answer my own question. In case this helps anyone else in the future:
The overwrite bit gets set if I don't read the OUT data from EP0 in time before a new SETUP packet comes in. When I finally get around to reading what I thought was EP0 OUT data, it actually contains the new SETUP packet's data. Now I understand why the PO bit is there -- it's telling me that the EP0 OUT data I just read is invalid, and to abort the current control transfer because a new one is beginning. I was able to test it by adding an artificial delay before reading OUT packets in my LPC1768 program, and writing a program on my host computer with libusb to do a couple of control transfers (with the first control transfer having a timeout shorter than the artificial delay in my LPC1768 program).
Here's what my code does now with the PO bit:
[list]
[*]EP_SLOW interrupt comes in.
[*]Check each endpoint in the USBEpIntSt register. If its bit is set, write a 1 to the corresponding bit in the USBEpIntClr register. Read the status byte back after the USBEpIntClr write to determine the difference between SETUP/OUT.
[*]If it's an OUT or SETUP packet, read the packet, and read the status byte from the "clear buffer" command when I'm done.
[*]If the PO bit is set in the status byte, it means the OUT or SETUP data I just read is garbage, so throw it out and abort the current control transfer (if any).
[*]Don't do anything special at this point. A new EP_SLOW interrupt for the new SETUP packet will come in, and these steps can repeat. The write to USBEpIntClr in the next interrupt will clear the PO bit before I try to read it again.
[/list]
I have seen the bit get set in STATUS OUT reads when connected to a Mac OS X host machine, but I don't think there's anything special to do in that case -- it just means that a new setup packet came in immediately after the STATUS OUT reply, and I didn't read the zero-length STATUS OUT reply in time (no big deal, I think).
BTW, with this scheme, you should *not* immediately write to USBEpIntClr as the datasheet advises; this causes the interrupt for the new SETUP packet to be cleared, so you don't get notified about it. If you *do* write immediately to USBEpIntClr to clear the PO bit, then you also need to immediately act as though a new packet has arrived and read it out, as implied by the datasheet. My software wasn't organized in a way to make that particular sequence easy to implement, so I left it for the next interrupt to handle instead. Seems to work OK in my testing.