Fixed incorrect/missing control status stage transfers on demos, bootloaders and applications (thanks to Nate Lawson).

pull/1469/head
Dean Camera 16 years ago
parent 4a09da2098
commit 3803976534

@ -167,6 +167,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived())); while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
} }
@ -184,6 +185,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady())); while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -194,6 +196,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady())); while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }

@ -57,7 +57,7 @@ bool RunBootloader = true;
/** Flag to indicate if the bootloader is waiting to exit. When the host requests the bootloader to exit and /** Flag to indicate if the bootloader is waiting to exit. When the host requests the bootloader to exit and
* jump to the application address it specifies, it sends two sequential commands which must be properly * jump to the application address it specifies, it sends two sequential commands which must be properly
* acknowedged. Upon reception of the first the RunBootloader flag is cleared and the WaitForExit flag is set, * acknowledged. Upon reception of the first the RunBootloader flag is cleared and the WaitForExit flag is set,
* causing the bootloader to wait for the final exit command before shutting down. * causing the bootloader to wait for the final exit command before shutting down.
*/ */
bool WaitForExit = false; bool WaitForExit = false;
@ -305,7 +305,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
/* Send ZLP to the host to acknowedge the request */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
break; break;
@ -392,7 +393,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Send ZLP to the host to acknowedge the request */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived())); while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
@ -415,6 +416,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived())); while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
@ -424,9 +426,11 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Reset the status value variable to the default OK status */ /* Reset the status value variable to the default OK status */
DFU_Status = OK; DFU_Status = OK;
Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN();
break; break;
case DFU_GETSTATE: case DFU_GETSTATE:
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
@ -436,6 +440,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived())); while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
@ -446,6 +451,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Reset the current state variable to the default idle state */ /* Reset the current state variable to the default idle state */
DFU_State = dfuIDLE; DFU_State = dfuIDLE;
/* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
break; break;

@ -144,10 +144,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
/* Wait until the host is ready to receive the request confirmation */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady())); while (!(Endpoint_IsSetupINReady()));
/* Handshake the request by sending an empty IN packet */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }

@ -163,7 +163,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP); Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);
} }
/* Handshake the request */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }

@ -193,7 +193,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP); Scheduler_SetTaskMode(USB_Audio_Task, TASK_STOP);
} }
/* Handshake the request */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -249,7 +250,7 @@ TASK(USB_Audio_Task)
/* Check to see if the bank is now empty */ /* Check to see if the bank is now empty */
if (!(Endpoint_ReadWriteAllowed())) if (!(Endpoint_ReadWriteAllowed()))
{ {
/* Acknowedge the packet, clear the bank ready for the next packet */ /* Acknowledge the packet, clear the bank ready for the next packet */
Endpoint_ClearCurrentBank(); Endpoint_ClearCurrentBank();
} }

@ -171,7 +171,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Write the line coding data to the control endpoint */ /* Write the line coding data to the control endpoint */
@ -185,7 +185,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Read the line coding data in from the host into the global struct */ /* Read the line coding data in from the host into the global struct */
@ -210,10 +210,11 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
// Do something with the given line states in wIndex // Do something with the given line states in wIndex
#endif #endif
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }

@ -209,7 +209,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Write the line coding data to the control endpoint */ /* Write the line coding data to the control endpoint */
@ -223,7 +223,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Read the line coding data in from the host into the global struct */ /* Read the line coding data in from the host into the global struct */
@ -237,10 +237,11 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_SetControlLineState: case REQ_SetControlLineState:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Send an empty packet to acknowedge the command (currently unused) */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }

@ -210,10 +210,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Clear the endpoint data */ /* Clear the endpoint data */
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
/* Wait until the host is ready to receive the request confirmation */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady())); while (!(Endpoint_IsSetupINReady()));
/* Handshake the request by sending an empty IN packet */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -228,6 +226,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;
@ -242,7 +244,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Set or clear the flag depending on what the host indicates that the current Protocol should be */ /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
UsingReportProtocol = (wValue != 0x0000); UsingReportProtocol = (wValue != 0x0000);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -258,7 +261,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (wValue >> 8);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -273,6 +277,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;

@ -212,10 +212,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Clear the endpoint data */ /* Clear the endpoint data */
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
/* Wait until the host is ready to receive the request confirmation */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady())); while (!(Endpoint_IsSetupINReady()));
/* Handshake the request by sending an empty IN packet */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -230,6 +228,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;
@ -244,7 +246,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Set or clear the flag depending on what the host indicates that the current Protocol should be */ /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
UsingReportProtocol = (wValue != 0x0000); UsingReportProtocol = (wValue != 0x0000);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -260,7 +263,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (wValue >> 8);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -275,6 +279,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;

@ -213,10 +213,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Clear the endpoint data */ /* Clear the endpoint data */
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
/* Wait until the host is ready to receive the request confirmation */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady())); while (!(Endpoint_IsSetupINReady()));
/* Handshake the request by sending an empty IN packet */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }

@ -211,10 +211,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Clear the endpoint data */ /* Clear the endpoint data */
Endpoint_ClearSetupOUT(); Endpoint_ClearSetupOUT();
/* Wait until the host is ready to receive the request confirmation */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady())); while (!(Endpoint_IsSetupINReady()));
/* Handshake the request by sending an empty IN packet */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -229,6 +227,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;
@ -243,7 +245,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Set or clear the flag depending on what the host indicates that the current Protocol should be */ /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
UsingReportProtocol = (wValue != 0x0000); UsingReportProtocol = (wValue != 0x0000);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -259,7 +262,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (wValue >> 8);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -274,6 +278,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;

@ -159,10 +159,13 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_MassStorageReset: case REQ_MassStorageReset:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Indicate that the current transfer should be aborted */
IsMassStoreReset = true;
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Indicate that the current transfer should be aborted */
IsMassStoreReset = true;
/* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -171,9 +174,15 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Indicate to the host the number of supported LUNs (virtual disks) on the device */ /* Indicate to the host the number of supported LUNs (virtual disks) on the device */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
Endpoint_Write_Byte(TOTAL_LUNS - 1); Endpoint_Write_Byte(TOTAL_LUNS - 1);
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;

@ -201,6 +201,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;
@ -215,7 +219,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Set or clear the flag depending on what the host indicates that the current Protocol should be */ /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
UsingReportProtocol = (wValue != 0x0000); UsingReportProtocol = (wValue != 0x0000);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -231,7 +236,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (wValue >> 8);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -246,6 +252,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;

@ -200,6 +200,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;
@ -214,7 +218,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Set or clear the flag depending on what the host indicates that the current Protocol should be */ /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
UsingReportProtocol = (wValue != 0x0000); UsingReportProtocol = (wValue != 0x0000);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -230,7 +235,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (wValue >> 8);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -245,6 +251,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;

@ -198,6 +198,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;
@ -212,7 +216,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Set or clear the flag depending on what the host indicates that the current Protocol should be */ /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
UsingReportProtocol = (wValue != 0x0000); UsingReportProtocol = (wValue != 0x0000);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -228,7 +233,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (wValue >> 8);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -243,6 +249,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;

@ -164,7 +164,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Write the line coding data to the control endpoint */ /* Write the line coding data to the control endpoint */
@ -178,7 +178,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Read the line coding data in from the host into the global struct */ /* Read the line coding data in from the host into the global struct */
@ -206,10 +206,11 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
// Do something with the given line states in wIndex // Do something with the given line states in wIndex
#endif #endif
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }

@ -29,13 +29,15 @@
* - Function attribute ATTR_ALWAYSINLINE renamed to ATTR_ALWAYS_INLINE to match other function attribute macro naming conventions * - Function attribute ATTR_ALWAYSINLINE renamed to ATTR_ALWAYS_INLINE to match other function attribute macro naming conventions
* - Added ATTR_ALWAYS_INLINE attribute to several key inlined library components, to ensure they are inlined in all circumstances * - Added ATTR_ALWAYS_INLINE attribute to several key inlined library components, to ensure they are inlined in all circumstances
* - Removed SetSystemClockPrescaler() macro, the clock_prescale_set() avr-libc macro has been corrected in recent avr-libc versions * - Removed SetSystemClockPrescaler() macro, the clock_prescale_set() avr-libc macro has been corrected in recent avr-libc versions
* - Fixed incorrect/missing control status stage transfers on demos, bootloaders and applications (thanks to Nate Lawson)
* *
* \section Sec_ChangeLog090209 Version 090209 * \section Sec_ChangeLog090209 Version 090209
* *
* - PWM timer mode in AudioOut demo changed to Fast PWM for speed * - PWM timer mode in AudioOut demo changed to Fast PWM for speed
* - Updated Magstripe project to work with the latest hardware revision * - Updated Magstripe project to work with the latest hardware revision
* - Fixed library not responding to the BCERRI flag correctly in host mode, leading to device lockups * - Fixed library not responding to the BCERRI flag correctly in host mode, leading to device lockups
* - Fixed library handling Get Descriptor requests when not addressed as standard requests to the device or interface * - Fixed library handling Get Descriptor requests when not addressed as standard requests to the device or interface (thanks to
* Nate Lawson)
* - Fixed serious data corruption issue in MassStorage demo dataflash write routine * - Fixed serious data corruption issue in MassStorage demo dataflash write routine
* - Added new NO_CLEARSET_FEATURE_REQUEST compile time token * - Added new NO_CLEARSET_FEATURE_REQUEST compile time token
* - USB task now restores previous global interrupt state after execution, rather than forcing global interrupts to be enabled * - USB task now restores previous global interrupt state after execution, rather than forcing global interrupts to be enabled
@ -326,7 +328,7 @@
* - Added Endpoint_Read_Stream, Endpoint_Write_Stream, Pipe_Read_Stream and Pipe_Write_Stream functions * - Added Endpoint_Read_Stream, Endpoint_Write_Stream, Pipe_Read_Stream and Pipe_Write_Stream functions
* (including Big and Little Endian variants) * (including Big and Little Endian variants)
* - Made Dataflash functions inline for speed, removed now empty Dataflash.c driver file * - Made Dataflash functions inline for speed, removed now empty Dataflash.c driver file
* - Added new SetSystemClockPrescaler() macro - thanks to Joerg Wunsch * - Added new SetSystemClockPrescaler() macro (thanks to Joerg Wunsch)
* - Fixed Endpoint_ClearStall() to function correctly on full USB controller AVRs (AT90USBXXX6/7) * - Fixed Endpoint_ClearStall() to function correctly on full USB controller AVRs (AT90USBXXX6/7)
* - Endpoint_Setup_In_Clear() and Endpoint_Setup_Out_Clear() no longer set FIFOCON, in line with the * - Endpoint_Setup_In_Clear() and Endpoint_Setup_Out_Clear() no longer set FIFOCON, in line with the
* directives in the datasheet * directives in the datasheet

@ -256,7 +256,7 @@
/** Sends an IN packet to the host on the currently selected CONTROL type endpoint. */ /** Sends an IN packet to the host on the currently selected CONTROL type endpoint. */
#define Endpoint_ClearSetupIN() MACROS{ UEINTX &= ~(1 << TXINI); }MACROE #define Endpoint_ClearSetupIN() MACROS{ UEINTX &= ~(1 << TXINI); }MACROE
/** Acknowedges an OUT packet to the host on the currently selected CONTROL type endpoint, freeing /** Acknowledges an OUT packet to the host on the currently selected CONTROL type endpoint, freeing
* up the endpoint for the next packet. * up the endpoint for the next packet.
*/ */
#define Endpoint_ClearSetupOUT() MACROS{ UEINTX &= ~(1 << RXOUTI); }MACROE #define Endpoint_ClearSetupOUT() MACROS{ UEINTX &= ~(1 << RXOUTI); }MACROE
@ -667,7 +667,7 @@
) ATTR_NON_NULL_PTR_ARG(1); ) ATTR_NON_NULL_PTR_ARG(1);
/** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian,
* sending full packets to the host as needed. The host OUT acknowedgement is not automatically cleared * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared
* in both failure and success states; the user is responsible for manually clearing the setup OUT to * in both failure and success states; the user is responsible for manually clearing the setup OUT to
* finalize the transfer via the Endpoint_ClearSetupOUT() macro. * finalize the transfer via the Endpoint_ClearSetupOUT() macro.
* *
@ -684,7 +684,7 @@
uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
/** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian,
* sending full packets to the host as needed. The host OUT acknowedgement is not automatically cleared * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared
* in both failure and success states; the user is responsible for manually clearing the setup OUT to * in both failure and success states; the user is responsible for manually clearing the setup OUT to
* finalize the transfer via the Endpoint_ClearSetupOUT() macro. * finalize the transfer via the Endpoint_ClearSetupOUT() macro.
* *
@ -701,7 +701,7 @@
uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
/** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian,
* discarding fully read packets from the host as needed. The device IN acknowedgement is not * discarding fully read packets from the host as needed. The device IN acknowledgement is not
* automatically sent after success or failure states; the user is responsible for manually sending the * automatically sent after success or failure states; the user is responsible for manually sending the
* setup IN to finalize the transfer via the Endpoint_ClearSetupIN() macro. * setup IN to finalize the transfer via the Endpoint_ClearSetupIN() macro.
* *
@ -718,7 +718,7 @@
uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1);
/** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian,
* discarding fully read packets from the host as needed. The device IN acknowedgement is not * discarding fully read packets from the host as needed. The device IN acknowledgement is not
* automatically sent after success or failure states; the user is responsible for manually sending the * automatically sent after success or failure states; the user is responsible for manually sending the
* setup IN to finalize the transfer via the Endpoint_ClearSetupIN() macro. * setup IN to finalize the transfer via the Endpoint_ClearSetupIN() macro.
* *

@ -205,7 +205,7 @@
#if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__) #if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__)
/** Constant for the maximum software timeout period of the USB data stream transfer functions /** Constant for the maximum software timeout period of the USB data stream transfer functions
* (both control and standard) when in either device or host mode. If the next packet of a stream * (both control and standard) when in either device or host mode. If the next packet of a stream
* is not received or acknowedged within this time period, the stream function will fail. * is not received or acknowledged within this time period, the stream function will fail.
* *
* This value may be overridden in the user project makefile as the value of the * This value may be overridden in the user project makefile as the value of the
* USB_STREAM_TIMEOUT_MS token, and passed to the compiler using the -D switch. * USB_STREAM_TIMEOUT_MS token, and passed to the compiler using the -D switch.

@ -347,7 +347,7 @@
*/ */
#define Pipe_IsSetupOUTReady() ((UPINTX & (1 << TXOUTI)) ? true : false) #define Pipe_IsSetupOUTReady() ((UPINTX & (1 << TXOUTI)) ? true : false)
/** Acknowedges the reception of a setup IN request from the attached device on the currently selected /** Acknowledges the reception of a setup IN request from the attached device on the currently selected
* CONTROL type endpoint, allowing for the transmission of a setup OUT packet, or the reception of * CONTROL type endpoint, allowing for the transmission of a setup OUT packet, or the reception of
* another setup IN packet. * another setup IN packet.
*/ */
@ -356,7 +356,7 @@
/** Sends the currently selected CONTROL type pipe's contents to the device as a setup OUT packet. */ /** Sends the currently selected CONTROL type pipe's contents to the device as a setup OUT packet. */
#define Pipe_ClearSetupOUT() MACROS{ UPINTX &= ~(1 << TXOUTI); UPINTX &= ~(1 << FIFOCON); }MACROE #define Pipe_ClearSetupOUT() MACROS{ UPINTX &= ~(1 << TXOUTI); UPINTX &= ~(1 << FIFOCON); }MACROE
/** Returns true if the device sent a NAK (Negative Acknowedge) in response to the last sent packet on /** Returns true if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on
* the currently selected pipe. This ocurrs when the host sends a packet to the device, but the device * the currently selected pipe. This ocurrs when the host sends a packet to the device, but the device
* is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been * is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been
* received, it must be cleard using Pipe_ClearNAKReceived() before the previous (or any other) packet * received, it must be cleard using Pipe_ClearNAKReceived() before the previous (or any other) packet

@ -22,6 +22,9 @@
* *
* <b>Library Demos</b> * <b>Library Demos</b>
* - The USBtoSerial demo now discards all data when not connected to a host, rather than buffering it for later transmission. * - The USBtoSerial demo now discards all data when not connected to a host, rather than buffering it for later transmission.
* - Most demos, bootloaders and applications have had their control request handling code corrected, to properly send the status
* stage in all handled requests. If you are using code based off one of the library demos, bootloaders or applications, you should
* update to the latest revisions.
* *
* <b>Non-USB Library Components</b> * <b>Non-USB Library Components</b>
* - The ATTR_ALWAYSINLINE function attribute macro has been renamed to ATTR_ALWAYS_INLINE. * - The ATTR_ALWAYSINLINE function attribute macro has been renamed to ATTR_ALWAYS_INLINE.

@ -267,7 +267,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Write the line coding data to the control endpoint */ /* Write the line coding data to the control endpoint */
@ -281,7 +281,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Read the line coding data in from the host into the global struct */ /* Read the line coding data in from the host into the global struct */
@ -298,10 +298,11 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
case REQ_SetControlLineState: case REQ_SetControlLineState:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowedge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSetupReceived(); Endpoint_ClearSetupReceived();
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }

@ -204,6 +204,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;
@ -218,7 +222,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Set or clear the flag depending on what the host indicates that the current Protocol should be */ /* Set or clear the flag depending on what the host indicates that the current Protocol should be */
UsingReportProtocol = (wValue != 0x0000); UsingReportProtocol = (wValue != 0x0000);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -234,7 +239,8 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (wValue >> 8);
/* Send an empty packet to acknowedge the command */ /* Acknowledge status stage */
while (!(Endpoint_IsSetupINReady()));
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
} }
@ -249,6 +255,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
/* Send the flag to the host */ /* Send the flag to the host */
Endpoint_ClearSetupIN(); Endpoint_ClearSetupIN();
/* Acknowledge status stage */
while (!(Endpoint_IsSetupOUTReceived()));
Endpoint_ClearSetupOUT();
} }
break; break;

Loading…
Cancel
Save