Changed all Device mode LowLevel demos and Device Class drivers so that the control request is acknowledged and any data transferred as quickly as possible without any processing inbetween sections, so that long callbacks or event handlers will not break communications with the host by exceeding the maximum control request stage timeout period.

pull/1469/head
Dean Camera 14 years ago
parent 1be3436e89
commit 4cc7f5200b

@ -146,8 +146,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case Req_InitiateAbortBulkOut: case Req_InitiateAbortBulkOut:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
{ {
Endpoint_ClearSETUP();
/* Check that no split transaction is already in progress and the data transfer tag is valid */ /* Check that no split transaction is already in progress and the data transfer tag is valid */
if (RequestInProgress != 0) if (RequestInProgress != 0)
{ {
@ -165,6 +163,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* Save the split request for later checking when a new request is received */ /* Save the split request for later checking when a new request is received */
RequestInProgress = Req_InitiateAbortBulkOut; RequestInProgress = Req_InitiateAbortBulkOut;
} }
Endpoint_ClearSETUP();
/* Write the request response byte */ /* Write the request response byte */
Endpoint_Write_Byte(TMCRequestStatus); Endpoint_Write_Byte(TMCRequestStatus);
@ -177,16 +177,16 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case Req_CheckAbortBulkOutStatus: case Req_CheckAbortBulkOutStatus:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
{ {
Endpoint_ClearSETUP();
/* Check that an ABORT BULK OUT transaction has been requested and that the request has completed */ /* Check that an ABORT BULK OUT transaction has been requested and that the request has completed */
if (RequestInProgress != Req_InitiateAbortBulkOut) if (RequestInProgress != Req_InitiateAbortBulkOut)
TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS; TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS;
else if (IsTMCBulkOUTReset) else if (IsTMCBulkOUTReset)
TMCRequestStatus = TMC_STATUS_PENDING; TMCRequestStatus = TMC_STATUS_PENDING;
else else
RequestInProgress = 0; RequestInProgress = 0;
Endpoint_ClearSETUP();
/* Write the request response bytes */ /* Write the request response bytes */
Endpoint_Write_Byte(TMCRequestStatus); Endpoint_Write_Byte(TMCRequestStatus);
Endpoint_Write_Word_LE(0); Endpoint_Write_Word_LE(0);
@ -200,8 +200,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case Req_InitiateAbortBulkIn: case Req_InitiateAbortBulkIn:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
{ {
Endpoint_ClearSETUP();
/* Check that no split transaction is already in progress and the data transfer tag is valid */ /* Check that no split transaction is already in progress and the data transfer tag is valid */
if (RequestInProgress != 0) if (RequestInProgress != 0)
{ {
@ -219,6 +217,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* Save the split request for later checking when a new request is received */ /* Save the split request for later checking when a new request is received */
RequestInProgress = Req_InitiateAbortBulkIn; RequestInProgress = Req_InitiateAbortBulkIn;
} }
Endpoint_ClearSETUP();
/* Write the request response bytes */ /* Write the request response bytes */
Endpoint_Write_Byte(TMCRequestStatus); Endpoint_Write_Byte(TMCRequestStatus);
@ -232,8 +232,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case Req_CheckAbortBulkInStatus: case Req_CheckAbortBulkInStatus:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
{ {
Endpoint_ClearSETUP();
/* Check that an ABORT BULK IN transaction has been requested and that the request has completed */ /* Check that an ABORT BULK IN transaction has been requested and that the request has completed */
if (RequestInProgress != Req_InitiateAbortBulkIn) if (RequestInProgress != Req_InitiateAbortBulkIn)
TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS; TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS;
@ -241,7 +239,9 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
TMCRequestStatus = TMC_STATUS_PENDING; TMCRequestStatus = TMC_STATUS_PENDING;
else else
RequestInProgress = 0; RequestInProgress = 0;
Endpoint_ClearSETUP();
/* Write the request response bytes */ /* Write the request response bytes */
Endpoint_Write_Byte(TMCRequestStatus); Endpoint_Write_Byte(TMCRequestStatus);
Endpoint_Write_Word_LE(0); Endpoint_Write_Word_LE(0);
@ -255,8 +255,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case Req_InitiateClear: case Req_InitiateClear:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP();
/* Check that no split transaction is already in progress */ /* Check that no split transaction is already in progress */
if (RequestInProgress != 0) if (RequestInProgress != 0)
{ {
@ -271,6 +269,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* Save the split request for later checking when a new request is received */ /* Save the split request for later checking when a new request is received */
RequestInProgress = Req_InitiateClear; RequestInProgress = Req_InitiateClear;
} }
Endpoint_ClearSETUP();
/* Write the request response byte */ /* Write the request response byte */
Endpoint_Write_Byte(TMCRequestStatus); Endpoint_Write_Byte(TMCRequestStatus);
@ -283,8 +283,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case Req_CheckClearStatus: case Req_CheckClearStatus:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP();
/* Check that a CLEAR transaction has been requested and that the request has completed */ /* Check that a CLEAR transaction has been requested and that the request has completed */
if (RequestInProgress != Req_InitiateClear) if (RequestInProgress != Req_InitiateClear)
TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS; TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS;
@ -292,7 +290,9 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
TMCRequestStatus = TMC_STATUS_PENDING; TMCRequestStatus = TMC_STATUS_PENDING;
else else
RequestInProgress = 0; RequestInProgress = 0;
Endpoint_ClearSETUP();
/* Write the request response bytes */ /* Write the request response bytes */
Endpoint_Write_Byte(TMCRequestStatus); Endpoint_Write_Byte(TMCRequestStatus);
Endpoint_Write_Byte(0); Endpoint_Write_Byte(0);
@ -305,13 +305,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case Req_GetCapabilities: case Req_GetCapabilities:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the device capabilities to the control endpoint */ /* Write the device capabilities to the control endpoint */
Endpoint_Write_Control_Stream_LE(&Capabilities, sizeof(TMC_Capabilities_t)); Endpoint_Write_Control_Stream_LE(&Capabilities, sizeof(TMC_Capabilities_t));
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
} }

@ -133,12 +133,11 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* Set Interface is not handled by the library, as its function is application-specific */ /* Set Interface is not handled by the library, as its function is application-specific */
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
/* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */ /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0); StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0);
Endpoint_ClearStatusStage();
} }
break; break;

@ -161,11 +161,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
/* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */ /* Check if the host is enabling the audio interface (setting AlternateSetting to 1) */
StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0); StreamingAudioInterfaceSelected = ((USB_ControlRequest.wValue) != 0);
Endpoint_ClearStatusStage();
} }
break; break;

@ -161,13 +161,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the line coding data to the control endpoint */ /* Write the line coding data to the control endpoint */
Endpoint_Write_Control_Stream_LE(LineEncodingData, sizeof(CDC_Line_Coding_t)); Endpoint_Write_Control_Stream_LE(LineEncodingData, sizeof(CDC_Line_Coding_t));
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
} }
@ -175,13 +172,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* 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 */
Endpoint_Read_Control_Stream_LE(LineEncodingData, sizeof(CDC_Line_Coding_t)); Endpoint_Read_Control_Stream_LE(LineEncodingData, sizeof(CDC_Line_Coding_t));
/* Finalize the stream transfer to clear the last packet from the host */
Endpoint_ClearIN(); Endpoint_ClearIN();
} }
@ -189,9 +183,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case REQ_SetControlLineState: case REQ_SetControlLineState:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }

@ -120,15 +120,12 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
uint8_t GenericData[GENERIC_REPORT_SIZE]; uint8_t GenericData[GENERIC_REPORT_SIZE];
CreateGenericHIDReport(GenericData);
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
CreateGenericHIDReport(GenericData);
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(&GenericData, sizeof(GenericData)); Endpoint_Write_Control_Stream_LE(&GenericData, sizeof(GenericData));
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
} }
@ -139,30 +136,12 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
uint8_t GenericData[GENERIC_REPORT_SIZE]; uint8_t GenericData[GENERIC_REPORT_SIZE];
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Wait until the generic report has been sent by the host */
while (!(Endpoint_IsOUTReceived()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* Read the report data from the control endpoint */
Endpoint_Read_Control_Stream_LE(&GenericData, sizeof(GenericData)); Endpoint_Read_Control_Stream_LE(&GenericData, sizeof(GenericData));
ProcessGenericHIDReport(GenericData);
/* Clear the endpoint data */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
/* Wait until the host is ready to receive the request confirmation */ ProcessGenericHIDReport(GenericData);
while (!(Endpoint_IsINReady()))
{
if (USB_DeviceState == DEVICE_STATE_Unattached)
return;
}
/* Handshake the request by sending an empty IN packet */
Endpoint_ClearIN();
} }
break; break;

@ -117,15 +117,13 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
USB_JoystickReport_Data_t JoystickReportData; USB_JoystickReport_Data_t JoystickReportData;
Endpoint_ClearSETUP();
/* Create the next HID report to send to the host */ /* Create the next HID report to send to the host */
GetNextReport(&JoystickReportData); GetNextReport(&JoystickReportData);
Endpoint_ClearSETUP();
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(&JoystickReportData, sizeof(JoystickReportData)); Endpoint_Write_Control_Stream_LE(&JoystickReportData, sizeof(JoystickReportData));
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
} }

@ -143,15 +143,13 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
USB_KeyboardReport_Data_t KeyboardReportData; USB_KeyboardReport_Data_t KeyboardReportData;
Endpoint_ClearSETUP();
/* Create the next keyboard report for transmission to the host */ /* Create the next keyboard report for transmission to the host */
CreateKeyboardReport(&KeyboardReportData); CreateKeyboardReport(&KeyboardReportData);
Endpoint_ClearSETUP();
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData)); Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
} }
@ -171,13 +169,11 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* Read in the LED report from the host */ /* Read in the LED report from the host */
uint8_t LEDStatus = Endpoint_Read_Byte(); uint8_t LEDStatus = Endpoint_Read_Byte();
/* Process the incoming LED report */
ProcessLEDReport(LEDStatus);
/* Clear the endpoint data */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
/* Process the incoming LED report */
ProcessLEDReport(LEDStatus);
} }
break; break;
@ -188,10 +184,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* Write the current protocol flag to the host */ /* Write the current protocol flag to the host */
Endpoint_Write_Byte(UsingReportProtocol); Endpoint_Write_Byte(UsingReportProtocol);
/* Send the flag to the host */
Endpoint_ClearIN();
Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }
@ -200,23 +194,21 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
/* 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 = (USB_ControlRequest.wValue != 0); UsingReportProtocol = (USB_ControlRequest.wValue != 0);
Endpoint_ClearStatusStage();
} }
break; break;
case REQ_SetIdle: case REQ_SetIdle:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
/* Get idle period in MSB, IdleCount must be multiplied by 4 to get number of milliseconds */ /* Get idle period in MSB, IdleCount must be multiplied by 4 to get number of milliseconds */
IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6); IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
Endpoint_ClearStatusStage();
} }
break; break;
@ -226,11 +218,9 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the current idle duration to the host, must be divided by 4 before sent to host */ /* Write the current idle duration to the host, must be divided by 4 before sent to host */
Endpoint_Write_Byte(IdleCount >> 2); Endpoint_Write_Byte(IdleCount >> 2);
/* Send the flag to the host */
Endpoint_ClearIN();
Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }

@ -148,12 +148,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
Endpoint_ClearOUT();
/* Clear the report data afterwards */ /* Clear the report data afterwards */
memset(ReportData, 0, ReportSize); memset(ReportData, 0, ReportSize);
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT();
} }
break; break;
@ -169,13 +167,14 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
return; return;
} }
/* Read in and process the LED report from the host */ /* Read in the LED report from the host */
Keyboard_ProcessLEDReport(Endpoint_Read_Byte()); uint8_t LEDStatus = Endpoint_Read_Byte();
/* Clear the endpoint data */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
/* Process the incoming LED report */
Keyboard_ProcessLEDReport(LEDStatus);
} }
break; break;

@ -133,11 +133,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
/* Indicate that the current transfer should be aborted */ /* Indicate that the current transfer should be aborted */
IsMassStoreReset = true; IsMassStoreReset = true;
Endpoint_ClearStatusStage();
} }
break; break;
@ -149,8 +148,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* 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_Write_Byte(TOTAL_LUNS - 1); Endpoint_Write_Byte(TOTAL_LUNS - 1);
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }

@ -140,19 +140,17 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
{ {
USB_MouseReport_Data_t MouseReportData; USB_MouseReport_Data_t MouseReportData;
Endpoint_ClearSETUP();
/* Create the next mouse report for transmission to the host */ /* Create the next mouse report for transmission to the host */
CreateMouseReport(&MouseReportData); CreateMouseReport(&MouseReportData);
Endpoint_ClearSETUP();
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(&MouseReportData, sizeof(MouseReportData)); Endpoint_Write_Control_Stream_LE(&MouseReportData, sizeof(MouseReportData));
Endpoint_ClearOUT();
/* Clear the report data afterwards */ /* Clear the report data afterwards */
memset(&MouseReportData, 0, sizeof(MouseReportData)); memset(&MouseReportData, 0, sizeof(MouseReportData));
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT();
} }
break; break;
@ -164,9 +162,7 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* Write the current protocol flag to the host */ /* Write the current protocol flag to the host */
Endpoint_Write_Byte(UsingReportProtocol); Endpoint_Write_Byte(UsingReportProtocol);
/* Send the flag to the host */
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }
@ -175,11 +171,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
/* 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 = (USB_ControlRequest.wValue != 0); UsingReportProtocol = (USB_ControlRequest.wValue != 0);
Endpoint_ClearStatusStage();
} }
break; break;
@ -187,11 +182,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
/* Get idle period in MSB, must multiply by 4 to get the duration in milliseconds */ /* Get idle period in MSB, must multiply by 4 to get the duration in milliseconds */
IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6); IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
Endpoint_ClearStatusStage();
} }
break; break;
@ -202,10 +196,8 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
/* Write the current idle duration to the host, must be divided by 4 before sent to host */ /* Write the current idle duration to the host, must be divided by 4 before sent to host */
Endpoint_Write_Byte(IdleCount >> 2); Endpoint_Write_Byte(IdleCount >> 2);
/* Send the flag to the host */
Endpoint_ClearIN();
Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }

@ -124,13 +124,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case REQ_SendEncapsulatedCommand: case REQ_SendEncapsulatedCommand:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Clear the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Read in the RNDIS message into the message buffer */ /* Read in the RNDIS message into the message buffer */
Endpoint_Read_Control_Stream_LE(RNDISMessageBuffer, USB_ControlRequest.wLength); Endpoint_Read_Control_Stream_LE(RNDISMessageBuffer, USB_ControlRequest.wLength);
/* Finalize the stream transfer to clear the last packet from the host */
Endpoint_ClearIN(); Endpoint_ClearIN();
/* Process the RNDIS message */ /* Process the RNDIS message */
@ -141,9 +138,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case REQ_GetEncapsulatedResponse: case REQ_GetEncapsulatedResponse:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Clear the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP();
/* Check if a response to the last message is ready */ /* Check if a response to the last message is ready */
if (!(MessageHeader->MessageLength)) if (!(MessageHeader->MessageLength))
{ {
@ -152,10 +146,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
MessageHeader->MessageLength = 1; MessageHeader->MessageLength = 1;
} }
Endpoint_ClearSETUP();
/* Write the message response data to the endpoint */ /* Write the message response data to the endpoint */
Endpoint_Write_Control_Stream_LE(RNDISMessageBuffer, MessageHeader->MessageLength); Endpoint_Write_Control_Stream_LE(RNDISMessageBuffer, MessageHeader->MessageLength);
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
/* Reset the message header once again after transmission */ /* Reset the message header once again after transmission */

@ -134,13 +134,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the line coding data to the control endpoint */ /* Write the line coding data to the control endpoint */
Endpoint_Write_Control_Stream_LE(&LineEncoding, sizeof(CDC_Line_Coding_t)); Endpoint_Write_Control_Stream_LE(&LineEncoding, sizeof(CDC_Line_Coding_t));
/* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
} }
@ -148,13 +145,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* 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 */
Endpoint_Read_Control_Stream_LE(&LineEncoding, sizeof(CDC_Line_Coding_t)); Endpoint_Read_Control_Stream_LE(&LineEncoding, sizeof(CDC_Line_Coding_t));
/* Finalize the stream transfer to clear the last packet from the host */
Endpoint_ClearIN(); Endpoint_ClearIN();
} }
@ -162,15 +156,13 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
case REQ_SetControlLineState: case REQ_SetControlLineState:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
/* NOTE: Here you can read in the line state mask from the host, to get the current state of the output handshake /* NOTE: Here you can read in the line state mask from the host, to get the current state of the output handshake
lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the
CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code: CONTROL_LINE_OUT_* masks to determine the RTS and DTR line states using the following code:
*/ */
Endpoint_ClearStatusStage();
} }
break; break;

@ -49,10 +49,9 @@ void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const Audi
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0);
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0);
} }
break; break;

@ -64,7 +64,6 @@ void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInter
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding)); Endpoint_Read_Control_Stream_LE(&CDCInterfaceInfo->State.LineEncoding, sizeof(CDCInterfaceInfo->State.LineEncoding));
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -75,12 +74,11 @@ void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInter
case REQ_SetControlLineState: case REQ_SetControlLineState:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage();
CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue; CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue;
Endpoint_ClearStatusStage();
EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo);
} }

@ -48,8 +48,6 @@ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInter
case REQ_GetReport: case REQ_GetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP();
uint16_t ReportSize = 0; uint16_t ReportSize = 0;
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF); uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1; uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
@ -62,6 +60,7 @@ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInter
if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL) if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL)
memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportData, HIDInterfaceInfo->Config.PrevReportINBufferSize); memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportData, HIDInterfaceInfo->Config.PrevReportINBufferSize);
Endpoint_ClearSETUP();
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
Endpoint_ClearOUT(); Endpoint_ClearOUT();
@ -71,16 +70,16 @@ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInter
case REQ_SetReport: case REQ_SetReport:
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP();
uint16_t ReportSize = USB_ControlRequest.wLength; uint16_t ReportSize = USB_ControlRequest.wLength;
uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF); uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF);
uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1; uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1;
uint8_t ReportData[ReportSize]; uint8_t ReportData[ReportSize];
Endpoint_ClearSETUP();
Endpoint_Read_Control_Stream_LE(ReportData, ReportSize); Endpoint_Read_Control_Stream_LE(ReportData, ReportSize);
CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType, ReportData, ReportSize);
Endpoint_ClearIN(); Endpoint_ClearIN();
CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType, ReportData, ReportSize);
} }
break; break;
@ -88,10 +87,8 @@ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInter
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_Write_Byte(HIDInterfaceInfo->State.UsingReportProtocol); Endpoint_Write_Byte(HIDInterfaceInfo->State.UsingReportProtocol);
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }
@ -100,10 +97,9 @@ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInter
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00);
} }
break; break;
@ -111,10 +107,9 @@ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInter
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6);
} }
break; break;
@ -122,10 +117,8 @@ void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInter
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_Write_Byte(HIDInterfaceInfo->State.IdleCount >> 2); Endpoint_Write_Byte(HIDInterfaceInfo->State.IdleCount >> 2);
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }

@ -52,10 +52,9 @@ void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfac
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
MSInterfaceInfo->State.IsMassStoreReset = true;
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
MSInterfaceInfo->State.IsMassStoreReset = true;
} }
break; break;
@ -63,10 +62,8 @@ void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfac
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1); Endpoint_Write_Byte(MSInterfaceInfo->Config.TotalLUNs - 1);
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }

@ -81,7 +81,6 @@ void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDI
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength); Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength);
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -92,8 +91,6 @@ void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDI
case REQ_GetEncapsulatedResponse: case REQ_GetEncapsulatedResponse:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP();
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
if (!(MessageHeader->MessageLength)) if (!(MessageHeader->MessageLength))
@ -102,6 +99,7 @@ void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDI
MessageHeader->MessageLength = 1; MessageHeader->MessageLength = 1;
} }
Endpoint_ClearSETUP();
Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, MessageHeader->MessageLength); Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, MessageHeader->MessageLength);
Endpoint_ClearOUT(); Endpoint_ClearOUT();

@ -20,8 +20,9 @@
* SCSI_Codes.h file as these values are part of the MassStorage Class Driver * SCSI_Codes.h file as these values are part of the MassStorage Class Driver
* - Added compile time error to the AVRISP-MKII project when built for the U4 chips, as the default VTARGET detection ADC channel * - Added compile time error to the AVRISP-MKII project when built for the U4 chips, as the default VTARGET detection ADC channel
* does not exist on these chips (thanks to Marco) * does not exist on these chips (thanks to Marco)
* - Moved calls to Device mode Class Driver events to after the request has been acknowledged, so that long event handlers do * - Changed all Device mode LowLevel demos and Device Class drivers so that the control request is acknowledged and any data
* do skew the timing of the control requests * transferred as quickly as possible without any processing inbetween sections, so that long callbacks or event handlers will
* not break communications with the host by exceeding the maximum control request stage timeout period
* *
* <b>Fixed:</b> * <b>Fixed:</b>
* - Fixed USB_GetHIDReportItemInfo() function modifying the given report item's data when the report item does not exist * - Fixed USB_GetHIDReportItemInfo() function modifying the given report item's data when the report item does not exist

Loading…
Cancel
Save