If I understand you correctly, you have set up the Periodic List to return a 1-byte (7 ports or less) change status. Once you have received this byte, if a change is detected, you then use the Control Pipe to request the 4-byte status of the hub. Once you have done this, you then send a Clear Feature request (on the Control Pipe) to clear the change status.
Is this correct?
What interrupt are you talking about? A hardware interrupt? Is it because the DoneHead value is being written after the Periodic list is executed?
If you are taking about a new Interrupt TD being executed, this could happen depending on the rate of the check. Your Periodic list could be using a 16ms check and your HubGetPortStatus() routine could be taking more than 16ms to process the change. An external hub usually indicates a 0xFFms interval (or round up to 256ms).
The second (hardware) interrupt may have nothing to do with the external hub port status event. It could be something else, simply that the controller is again, done with the list.
When you get the initial interrupt, at the start of your "HubGetPortStatus" routine check to see if you are already processing the change. If so, simply return. Once you are done with the Change Event (indicate an enumeration of new device or a removal of a device), get the status one more time to see if there was a change between the first initial call and now the end of the process. If so, repeat for a different port change event. If no other change was found, clear the "InThisRoutine" flag and return.
Code:
HubGetPortStatus() {
if (InThisRoutine)
return;
InThisRoutine = 1;
do {
HubStatus = GetHubStatus();
.
. Do Something because of the change event (enumerate new device, removal of device, etc.)
.
while (HubStatus != GetHubStatus());
ClearFeature();
InThisRoutine = 0;
return;
}
Of course this is simply a mock-up example, but you may get the point.
Hope this helps,
Ben
-
https://www.fysnet.net/the_universal_serial_bus.htm