USB_HostRequest renamed to USB_ControlRequest, entire control request header is now read into USB_ControlRequest in Device mode rather than having the library pass only partially read header data to the application.

The USB_UnhandledControlPacket event has had its parameters removed, in favour of accessing the new USB_ControlRequest structure.

The Endpoint control stream functions now correctly send a ZLP to the host when less data than requested is sent.
pull/1469/head
Dean Camera 16 years ago
parent e5e7eaee7a
commit d860e9e842

@ -152,13 +152,11 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
uint8_t* LineCodingData = (uint8_t*)&LineCoding; uint8_t* LineCodingData = (uint8_t*)&LineCoding;
Endpoint_Discard_Word();
/* Process CDC specific control requests */ /* Process CDC specific control requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -174,7 +172,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -192,7 +190,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetControlLineState: case REQ_SetControlLineState:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -151,16 +151,10 @@ EVENT_HANDLER(USB_Disconnect)
*/ */
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Discard unused wIndex value */
Endpoint_Discard_Word();
/* Discard unused wValue value */
Endpoint_Discard_Word();
/* Get the size of the command and data from the wLength value */ /* Get the size of the command and data from the wLength value */
SentCommand.DataSize = Endpoint_Read_Word_LE(); SentCommand.DataSize = USB_ControlRequest.wLength;
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case DFU_DNLOAD: case DFU_DNLOAD:
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -96,10 +96,10 @@ EVENT_HANDLER(USB_ConfigurationChanged)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Handle HID Class specific requests */ /* Handle HID Class specific requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_SetReport: case REQ_SetReport:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -131,18 +131,16 @@ EVENT_HANDLER(USB_ConfigurationChanged)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Process General and Audio specific control requests */ /* Process General and Audio specific control requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_SetInterface: case REQ_SetInterface:
/* 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 (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
{ {
uint16_t wValue = Endpoint_Read_Word_LE();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* 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) */
if (wValue) if (USB_ControlRequest.wValue)
{ {
/* Start audio task */ /* Start audio task */
Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN); Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN);

@ -158,18 +158,16 @@ EVENT_HANDLER(USB_ConfigurationChanged)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Process General and Audio specific control requests */ /* Process General and Audio specific control requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_SetInterface: case REQ_SetInterface:
/* 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 (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE))
{ {
uint16_t wValue = Endpoint_Read_Word_LE();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* 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) */
if (wValue) if (USB_ControlRequest.wValue)
{ {
/* Start audio task */ /* Start audio task */
Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN); Scheduler_SetTaskMode(USB_Audio_Task, TASK_RUN);

@ -160,10 +160,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
uint8_t* LineCodingData = (uint8_t*)&LineCoding; uint8_t* LineCodingData = (uint8_t*)&LineCoding;
/* Process CDC specific control requests */ /* Process CDC specific control requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (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 */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -177,7 +177,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (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 */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -191,18 +191,12 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetControlLineState: case REQ_SetControlLineState:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
#if 0
/* 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, and can be masked against the CONTROL_LINE_OUT_* masks lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the
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:
*/ */
uint16_t wIndex = Endpoint_Read_Word_LE();
// Do something with the given line states in wIndex
#endif
/* Acknowledge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -198,10 +198,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
LineCodingData = (wIndex == 0) ? (uint8_t*)&LineCoding1 : (uint8_t*)&LineCoding2; LineCodingData = (wIndex == 0) ? (uint8_t*)&LineCoding1 : (uint8_t*)&LineCoding2;
/* Process CDC specific control requests */ /* Process CDC specific control requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (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 */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -215,7 +215,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (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 */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -229,7 +229,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetControlLineState: case REQ_SetControlLineState:
if (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 */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -160,10 +160,10 @@ EVENT_HANDLER(USB_ConfigurationChanged)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Handle HID Class specific requests */ /* Handle HID Class specific requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetReport: case REQ_GetReport:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -180,7 +180,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetReport: case REQ_SetReport:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -122,33 +122,20 @@ EVENT_HANDLER(USB_ConfigurationChanged)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Handle HID Class specific requests */ /* Handle HID Class specific requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetReport: case REQ_GetReport:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
USB_JoystickReport_Data_t JoystickReportData; USB_JoystickReport_Data_t JoystickReportData;
/* Create the next HID report to send to the host */ /* Create the next HID report to send to the host */
GetNextReport(&JoystickReportData); GetNextReport(&JoystickReportData);
/* Ignore report type and ID number value */
Endpoint_Discard_Word();
/* Ignore unused Interface number value */
Endpoint_Discard_Word();
/* Read in the number of bytes in the report to send to the host */
uint16_t wLength = Endpoint_Read_Word_LE();
/* If trying to send more bytes than exist to the host, clamp the value at the report size */
if (wLength > sizeof(JoystickReportData))
wLength = sizeof(JoystickReportData);
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(&JoystickReportData, wLength); Endpoint_Write_Control_Stream_LE(&JoystickReportData, sizeof(JoystickReportData));
/* Finalize the stream transfer to send the last packet or clear the host abort */ /* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();

@ -193,33 +193,20 @@ EVENT_HANDLER(USB_ConfigurationChanged)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Handle HID Class specific requests */ /* Handle HID Class specific requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetReport: case REQ_GetReport:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
USB_KeyboardReport_Data_t KeyboardReportData; USB_KeyboardReport_Data_t KeyboardReportData;
/* Create the next keyboard report for transmission to the host */ /* Create the next keyboard report for transmission to the host */
CreateKeyboardReport(&KeyboardReportData); CreateKeyboardReport(&KeyboardReportData);
/* Ignore report type and ID number value */
Endpoint_Discard_Word();
/* Ignore unused Interface number value */
Endpoint_Discard_Word();
/* Read in the number of bytes in the report to send to the host */
uint16_t wLength = Endpoint_Read_Word_LE();
/* If trying to send more bytes than exist to the host, clamp the value at the report size */
if (wLength > sizeof(KeyboardReportData))
wLength = sizeof(KeyboardReportData);
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(&KeyboardReportData, wLength); Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
/* Finalize the stream transfer to send the last packet or clear the host abort */ /* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
@ -227,7 +214,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetReport: case REQ_SetReport:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -250,7 +237,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_GetProtocol: case REQ_GetProtocol:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -267,15 +254,12 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetProtocol: case REQ_SetProtocol:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Read in the wValue parameter containing the new protocol mode */
uint16_t wValue = Endpoint_Read_Word_LE();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* 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 = (USB_ControlRequest.wValue != 0x0000);
/* Acknowledge status stage */ /* Acknowledge status stage */
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
@ -284,15 +268,12 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetIdle: case REQ_SetIdle:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Read in the wValue parameter containing the idle period */
uint16_t wValue = Endpoint_Read_Word_LE();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (USB_ControlRequest.wValue >> 8);
/* Acknowledge status stage */ /* Acknowledge status stage */
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
@ -301,7 +282,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_GetIdle: case REQ_GetIdle:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -139,17 +139,13 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
uint8_t ReportSize; uint8_t ReportSize;
/* Handle HID Class specific requests */ /* Handle HID Class specific requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetReport: case REQ_GetReport:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_Discard_Word();
uint16_t wIndex = Endpoint_Read_Word_LE();
/* Determine if it is the mouse or the keyboard data that is being requested */ /* Determine if it is the mouse or the keyboard data that is being requested */
if (!(wIndex)) if (!(USB_ControlRequest.wIndex))
{ {
ReportData = (uint8_t*)&KeyboardReportData; ReportData = (uint8_t*)&KeyboardReportData;
ReportSize = sizeof(KeyboardReportData); ReportSize = sizeof(KeyboardReportData);
@ -160,17 +156,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
ReportSize = sizeof(MouseReportData); ReportSize = sizeof(MouseReportData);
} }
/* Read in the number of bytes in the report to send to the host */
uint16_t wLength = Endpoint_Read_Word_LE();
/* If trying to send more bytes than exist to the host, clamp the value at the report size */
if (wLength > ReportSize)
wLength = ReportSize;
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(ReportData, wLength); Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
/* Clear the report data afterwards */ /* Clear the report data afterwards */
memset(ReportData, 0, ReportSize); memset(ReportData, 0, ReportSize);
@ -181,7 +170,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetReport: case REQ_SetReport:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -148,10 +148,10 @@ EVENT_HANDLER(USB_ConfigurationChanged)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Process UFI specific control requests */ /* Process UFI specific control requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_MassStorageReset: case REQ_MassStorageReset:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -165,7 +165,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_GetMaxLUN: case REQ_GetMaxLUN:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -183,33 +183,20 @@ EVENT_HANDLER(USB_ConfigurationChanged)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Handle HID Class specific requests */ /* Handle HID Class specific requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetReport: case REQ_GetReport:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
USB_MouseReport_Data_t MouseReportData; USB_MouseReport_Data_t MouseReportData;
/* Create the next mouse report for transmission to the host */ /* Create the next mouse report for transmission to the host */
CreateMouseReport(&MouseReportData); CreateMouseReport(&MouseReportData);
/* Ignore report type and ID number value */
Endpoint_Discard_Word();
/* Ignore unused Interface number value */
Endpoint_Discard_Word();
/* Read in the number of bytes in the report to send to the host */
uint16_t wLength = Endpoint_Read_Word_LE();
/* If trying to send more bytes than exist to the host, clamp the value at the report size */
if (wLength > sizeof(MouseReportData))
wLength = sizeof(MouseReportData);
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(&MouseReportData, wLength); Endpoint_Write_Control_Stream_LE(&MouseReportData, sizeof(MouseReportData));
/* Clear the report data afterwards */ /* Clear the report data afterwards */
memset(&MouseReportData, 0, sizeof(MouseReportData)); memset(&MouseReportData, 0, sizeof(MouseReportData));
@ -220,7 +207,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_GetProtocol: case REQ_GetProtocol:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -237,15 +224,12 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetProtocol: case REQ_SetProtocol:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Read in the wValue parameter containing the new protocol mode */
uint16_t wValue = Endpoint_Read_Word_LE();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* 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 = (USB_ControlRequest.wValue != 0x0000);
/* Acknowledge status stage */ /* Acknowledge status stage */
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
@ -254,15 +238,12 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetIdle: case REQ_SetIdle:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Read in the wValue parameter containing the idle period */
uint16_t wValue = Endpoint_Read_Word_LE();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (USB_ControlRequest.wValue >> 8);
/* Acknowledge status stage */ /* Acknowledge status stage */
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
@ -271,7 +252,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_GetIdle: case REQ_GetIdle:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -150,10 +150,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
uint16_t wLength = Endpoint_Read_Word_LE(); uint16_t wLength = Endpoint_Read_Word_LE();
/* Process RNDIS class commands */ /* Process RNDIS class commands */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_SendEncapsulatedCommand: case REQ_SendEncapsulatedCommand:
if (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 */ /* Clear the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -170,7 +170,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_GetEncapsulatedResponse: case REQ_GetEncapsulatedResponse:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* 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))
@ -180,15 +180,11 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
MessageHeader->MessageLength = 1; MessageHeader->MessageLength = 1;
} }
/* Check if less than the requested number of bytes to transfer */
if (MessageHeader->MessageLength < wLength)
wLength = MessageHeader->MessageLength;
/* Clear the SETUP packet, ready for data transfer */ /* Clear the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the message response data to the endpoint */ /* Write the message response data to the endpoint */
Endpoint_Write_Control_Stream_LE(RNDISMessageBuffer, wLength); Endpoint_Write_Control_Stream_LE(RNDISMessageBuffer, MessageHeader->MessageLength);
/* Finalize the stream transfer to send the last packet or clear the host abort */ /* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();

@ -153,10 +153,10 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
uint8_t* LineCodingData = (uint8_t*)&LineCoding; uint8_t* LineCodingData = (uint8_t*)&LineCoding;
/* Process CDC specific control requests */ /* Process CDC specific control requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetLineEncoding: case REQ_GetLineEncoding:
if (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 */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -170,7 +170,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetLineEncoding: case REQ_SetLineEncoding:
if (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 */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -187,18 +187,12 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetControlLineState: case REQ_SetControlLineState:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
#if 0
/* 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, and can be masked against the CONTROL_LINE_OUT_* masks lines. The mask is read in from the wValue parameter in USB_ControlRequest, and can be masked against the
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:
*/ */
uint16_t wIndex = Endpoint_Read_Word_LE();
// Do something with the given line states in wIndex
#endif
/* Acknowledge the SETUP packet, ready for data transfer */ /* Acknowledge the SETUP packet, ready for data transfer */
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

@ -181,7 +181,7 @@ TASK(USB_CDC_Host)
{ {
case HOST_STATE_Addressed: case HOST_STATE_Addressed:
/* Standard request to set the device configuration to configuration 1 */ /* Standard request to set the device configuration to configuration 1 */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_SetConfiguration, .bRequest = REQ_SetConfiguration,

@ -257,7 +257,7 @@ void WriteNextReport(uint8_t* ReportOUTData, uint8_t ReportIndex, uint8_t Report
else else
{ {
/* Class specific request to send a HID report to the device */ /* Class specific request to send a HID report to the device */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetReport, .bRequest = REQ_SetReport,
@ -286,7 +286,7 @@ TASK(USB_HID_Host)
{ {
case HOST_STATE_Addressed: case HOST_STATE_Addressed:
/* Standard request to set the device configuration to configuration 1 */ /* Standard request to set the device configuration to configuration 1 */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_SetConfiguration, .bRequest = REQ_SetConfiguration,

@ -253,7 +253,7 @@ TASK(USB_Keyboard_Host)
{ {
case HOST_STATE_Addressed: case HOST_STATE_Addressed:
/* Standard request to set the device configuration to configuration 1 */ /* Standard request to set the device configuration to configuration 1 */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_SetConfiguration, .bRequest = REQ_SetConfiguration,
@ -303,7 +303,7 @@ TASK(USB_Keyboard_Host)
} }
/* HID class request to set the keyboard protocol to the Boot Protocol */ /* HID class request to set the keyboard protocol to the Boot Protocol */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetProtocol, .bRequest = REQ_SetProtocol,

@ -47,7 +47,7 @@ uint8_t GetHIDReportData(void)
/* Create a buffer big enough to hold the entire returned HID report */ /* Create a buffer big enough to hold the entire returned HID report */
uint8_t HIDReportData[HIDReportSize]; uint8_t HIDReportData[HIDReportSize];
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE), .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE),
.bRequest = REQ_GetDescriptor, .bRequest = REQ_GetDescriptor,

@ -184,7 +184,7 @@ TASK(USB_Keyboard_Host)
{ {
case HOST_STATE_Addressed: case HOST_STATE_Addressed:
/* Standard request to set the device configuration to configuration 1 */ /* Standard request to set the device configuration to configuration 1 */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_SetConfiguration, .bRequest = REQ_SetConfiguration,

@ -155,7 +155,7 @@ TASK(USB_MassStore_Host)
{ {
case HOST_STATE_Addressed: case HOST_STATE_Addressed:
/* Standard request to set the device configuration to configuration 1 */ /* Standard request to set the device configuration to configuration 1 */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_SetConfiguration, .bRequest = REQ_SetConfiguration,

@ -250,7 +250,7 @@ static uint8_t MassStore_GetReturnedStatus(void)
*/ */
uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum) uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum)
{ {
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),
.bRequest = REQ_ClearFeature, .bRequest = REQ_ClearFeature,
@ -272,7 +272,7 @@ uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum)
*/ */
uint8_t MassStore_MassStorageReset(void) uint8_t MassStore_MassStorageReset(void)
{ {
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_MassStorageReset, .bRequest = REQ_MassStorageReset,
@ -298,7 +298,7 @@ uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex)
{ {
uint8_t ErrorCode; uint8_t ErrorCode;
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_GetMaxLUN, .bRequest = REQ_GetMaxLUN,

@ -248,7 +248,7 @@ TASK(USB_Mouse_Host)
{ {
case HOST_STATE_Addressed: case HOST_STATE_Addressed:
/* Standard request to set the device configuration to configuration 1 */ /* Standard request to set the device configuration to configuration 1 */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_SetConfiguration, .bRequest = REQ_SetConfiguration,
@ -298,7 +298,7 @@ TASK(USB_Mouse_Host)
} }
/* HID class request to set the mouse protocol to the Boot Protocol */ /* HID class request to set the mouse protocol to the Boot Protocol */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),
.bRequest = REQ_SetProtocol, .bRequest = REQ_SetProtocol,

@ -47,7 +47,7 @@ uint8_t GetHIDReportData(void)
/* Create a buffer big enough to hold the entire returned HID report */ /* Create a buffer big enough to hold the entire returned HID report */
uint8_t HIDReportData[HIDReportSize]; uint8_t HIDReportData[HIDReportSize];
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE), .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE),
.bRequest = REQ_GetDescriptor, .bRequest = REQ_GetDescriptor,

@ -185,7 +185,7 @@ TASK(USB_Mouse_Host)
{ {
case HOST_STATE_Addressed: case HOST_STATE_Addressed:
/* Standard request to set the device configuration to configuration 1 */ /* Standard request to set the device configuration to configuration 1 */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_SetConfiguration, .bRequest = REQ_SetConfiguration,

@ -263,7 +263,7 @@ bool SImage_IsEventReceived(void)
*/ */
uint8_t SImage_ClearPipeStall(const uint8_t EndpointNum) uint8_t SImage_ClearPipeStall(const uint8_t EndpointNum)
{ {
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),
.bRequest = REQ_ClearFeature, .bRequest = REQ_ClearFeature,

@ -151,7 +151,7 @@ TASK(USB_SImage_Host)
{ {
case HOST_STATE_Addressed: case HOST_STATE_Addressed:
/* Standard request to set the device configuration to configuration 1 */ /* Standard request to set the device configuration to configuration 1 */
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_SetConfiguration, .bRequest = REQ_SetConfiguration,

@ -193,8 +193,9 @@ EVENT_HANDLER(USB_DeviceError)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
puts_P(PSTR(EVENT_PREFIX "Ctrl Request\r\n")); puts_P(PSTR(EVENT_PREFIX "Ctrl Request\r\n"));
printf_P(PSTR(" -- Req Data %d\r\n"), bRequest); printf_P(PSTR(" -- Req Data %d\r\n"), USB_ControlRequest.bRequest);
printf_P(PSTR(" -- Req Type %d\r\n"), bmRequestType); printf_P(PSTR(" -- Req Type %d\r\n"), USB_ControlRequest.bmRequestType);
printf_P(PSTR(" -- Req Length %d\r\n"), USB_ControlRequest.wLength);
} }
/** Event handler for the USB_ConfigurationChanged event. When fired, the event is logged to the USART. */ /** Event handler for the USB_ConfigurationChanged event. When fired, the event is logged to the USART. */

@ -55,6 +55,10 @@
* - Capitalised the "Descriptor_Search" and "Descriptor_Search_Comp" prefixes of the values in the DSearch_Return_ErrorCodes_t and * - Capitalised the "Descriptor_Search" and "Descriptor_Search_Comp" prefixes of the values in the DSearch_Return_ErrorCodes_t and
* DSearch_Comp_Return_ErrorCodes_t enums * DSearch_Comp_Return_ErrorCodes_t enums
* - Changed over all deprecated GCC structure tag initializers to the standardized C99 format (thanks to Mike Alexander) * - Changed over all deprecated GCC structure tag initializers to the standardized C99 format (thanks to Mike Alexander)
* - USB_HostRequest renamed to USB_ControlRequest, entire control request header is now read into USB_ControlRequest in Device mode
* rather than having the library pass only partially read header data to the application
* - The USB_UnhandledControlPacket event has had its parameters removed, in favour of accessing the new USB_ControlRequest structure
* - The Endpoint control stream functions now correctly send a ZLP to the host when less data than requested is sent
* *
* *
* \section Sec_ChangeLog090401 Version 090401 * \section Sec_ChangeLog090401 Version 090401

@ -35,7 +35,7 @@ uint8_t USB_GetDeviceConfigDescriptor(uint16_t* const ConfigSizePtr, void* Buffe
{ {
uint8_t ErrorCode; uint8_t ErrorCode;
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_GetDescriptor, .bRequest = REQ_GetDescriptor,
@ -60,7 +60,7 @@ uint8_t USB_GetDeviceConfigDescriptor(uint16_t* const ConfigSizePtr, void* Buffe
} }
else else
{ {
USB_HostRequest.wLength = *ConfigSizePtr; USB_ControlRequest.wLength = *ConfigSizePtr;
ErrorCode = USB_Host_SendControlRequest(BufferPtr); ErrorCode = USB_Host_SendControlRequest(BufferPtr);
} }

@ -305,7 +305,7 @@
* parameters (wValue, wIndex, wLength, and Data) remain in the control endpoint bank until * parameters (wValue, wIndex, wLength, and Data) remain in the control endpoint bank until
* read out by the user application for processing. * read out by the user application for processing.
*/ */
void USB_UnhandledControlPacket(const uint8_t bRequest, const uint8_t bmRequestType); void USB_UnhandledControlPacket(void);
/** Event for USB configuration number changed. This event fires when a the USB host changes the /** Event for USB configuration number changed. This event fires when a the USB host changes the
* selected configuration number while in device mode. This event should be hooked in device * selected configuration number while in device mode. This event should be hooked in device
@ -392,7 +392,7 @@
#endif #endif
#if defined(USB_CAN_BE_DEVICE) #if defined(USB_CAN_BE_DEVICE)
#define USB_UnhandledControlPacket_P (const uint8_t bRequest, const uint8_t bmRequestType) #define USB_UnhandledControlPacket_P (void)
#define USB_ConfigurationChanged_P (void) #define USB_ConfigurationChanged_P (void)
#define USB_Suspend_P (void) #define USB_Suspend_P (void)
#define USB_WakeUp_P (void) #define USB_WakeUp_P (void)

@ -135,6 +135,20 @@
*/ */
#define FEATURE_REMOTE_WAKEUP 0x01 #define FEATURE_REMOTE_WAKEUP 0x01
/* Type Defines: */
/** Type define for a standard USB control request.
*
* \see The USB 2.0 specification for more information on standard control requests.
*/
typedef struct
{
uint8_t bmRequestType; /**< Type of the request. */
uint8_t bRequest; /**< Request command code. */
uint16_t wValue; /**< wValue parameter of the request. */
uint16_t wIndex; /**< wIndex parameter of the request. */
uint16_t wLength; /**< Length of the data to transfer in bytes. */
} USB_Request_Header_t;
/* Enums: */ /* Enums: */
/** Enumeration for the various standard request commands. These commands are applicable when the /** Enumeration for the various standard request commands. These commands are applicable when the
* request type is REQTYPE_STANDARD (with the exception of REQ_GetDescriptor, which is always * request type is REQTYPE_STANDARD (with the exception of REQ_GetDescriptor, which is always

@ -33,9 +33,10 @@
#define INCLUDE_FROM_USBTASK_C #define INCLUDE_FROM_USBTASK_C
#include "USBTask.h" #include "USBTask.h"
volatile bool USB_IsSuspended; volatile bool USB_IsSuspended;
volatile bool USB_IsConnected; volatile bool USB_IsConnected;
volatile bool USB_IsInitialized; volatile bool USB_IsInitialized;
USB_Request_Header_t USB_ControlRequest;
#if defined(USB_CAN_BE_HOST) #if defined(USB_CAN_BE_HOST)
volatile uint8_t USB_HostState; volatile uint8_t USB_HostState;
@ -169,7 +170,7 @@ static void USB_HostTask(void)
USB_HostState = HOST_STATE_Default; USB_HostState = HOST_STATE_Default;
break; break;
case HOST_STATE_Default: case HOST_STATE_Default:
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_GetDescriptor, .bRequest = REQ_GetDescriptor,
@ -214,7 +215,7 @@ static void USB_HostTask(void)
Pipe_SetInfiniteINRequests(); Pipe_SetInfiniteINRequests();
USB_HostRequest = (USB_Host_Request_Header_t) USB_ControlRequest = (USB_Request_Header_t)
{ {
.bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE),
.bRequest = REQ_SetAddress, .bRequest = REQ_SetAddress,

@ -40,6 +40,7 @@
#include "../../../Scheduler/Scheduler.h" #include "../../../Scheduler/Scheduler.h"
#include "../LowLevel/LowLevel.h" #include "../LowLevel/LowLevel.h"
#include "StdRequestType.h"
#include "USBMode.h" #include "USBMode.h"
#include "Events.h" #include "Events.h"
#include "StdDescriptors.h" #include "StdDescriptors.h"
@ -82,6 +83,14 @@
*/ */
extern volatile bool USB_IsInitialized; extern volatile bool USB_IsInitialized;
/** Structure containing the last received Control request when in Device mode (for use in user-applications
* inside of the USB_UnhandledControlPacket() event, or for filling up with a control request to issue when
* in Host mode before calling USB_Host_SendControlRequest().
*
* \ingroup Group_USBManagement
*/
extern USB_Request_Header_t USB_ControlRequest;
#if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) #if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)
/** Indicates if the USB interface is currently suspended by the host when in device mode. When suspended, /** Indicates if the USB interface is currently suspended by the host when in device mode. When suspended,
* the device should consume minimal power, and cannot communicate to the host. If Remote Wakeup is * the device should consume minimal power, and cannot communicate to the host. If Remote Wakeup is

@ -41,17 +41,19 @@ bool USB_CurrentlySelfPowered;
void USB_Device_ProcessControlPacket(void) void USB_Device_ProcessControlPacket(void)
{ {
uint8_t bmRequestType = Endpoint_Read_Byte(); bool RequestHandled = false;
uint8_t bRequest = Endpoint_Read_Byte(); uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest;
bool RequestHandled = false;
switch (bRequest) for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++)
*(RequestHeader++) = Endpoint_Read_Byte();
switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetStatus: case REQ_GetStatus:
if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || if ((USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
(bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT))) (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT)))
{ {
USB_Device_GetStatus(bmRequestType); USB_Device_GetStatus();
RequestHandled = true; RequestHandled = true;
} }
@ -59,16 +61,16 @@ void USB_Device_ProcessControlPacket(void)
#if !defined(FEATURELESS_CONTROL_ONLY_DEVICE) #if !defined(FEATURELESS_CONTROL_ONLY_DEVICE)
case REQ_ClearFeature: case REQ_ClearFeature:
case REQ_SetFeature: case REQ_SetFeature:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT))
{ {
USB_Device_ClearSetFeature(bRequest, bmRequestType); USB_Device_ClearSetFeature();
RequestHandled = true; RequestHandled = true;
} }
break; break;
#endif #endif
case REQ_SetAddress: case REQ_SetAddress:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
{ {
USB_Device_SetAddress(); USB_Device_SetAddress();
RequestHandled = true; RequestHandled = true;
@ -76,8 +78,8 @@ void USB_Device_ProcessControlPacket(void)
break; break;
case REQ_GetDescriptor: case REQ_GetDescriptor:
if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || if ((USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) ||
(bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE))) (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE)))
{ {
USB_Device_GetDescriptor(); USB_Device_GetDescriptor();
RequestHandled = true; RequestHandled = true;
@ -85,7 +87,7 @@ void USB_Device_ProcessControlPacket(void)
break; break;
case REQ_GetConfiguration: case REQ_GetConfiguration:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE))
{ {
USB_Device_GetConfiguration(); USB_Device_GetConfiguration();
RequestHandled = true; RequestHandled = true;
@ -93,7 +95,7 @@ void USB_Device_ProcessControlPacket(void)
break; break;
case REQ_SetConfiguration: case REQ_SetConfiguration:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE))
{ {
USB_Device_SetConfiguration(); USB_Device_SetConfiguration();
RequestHandled = true; RequestHandled = true;
@ -103,7 +105,7 @@ void USB_Device_ProcessControlPacket(void)
} }
if (!(RequestHandled)) if (!(RequestHandled))
RAISE_EVENT(USB_UnhandledControlPacket, bRequest, bmRequestType); RAISE_EVENT(USB_UnhandledControlPacket);
if (Endpoint_IsSETUPReceived()) if (Endpoint_IsSETUPReceived())
{ {
@ -114,8 +116,6 @@ void USB_Device_ProcessControlPacket(void)
static void USB_Device_SetAddress(void) static void USB_Device_SetAddress(void)
{ {
uint8_t wValue_LSB = Endpoint_Read_Byte();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
@ -124,28 +124,27 @@ static void USB_Device_SetAddress(void)
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
UDADDR = ((1 << ADDEN) | (wValue_LSB & 0x7F)); UDADDR = ((1 << ADDEN) | (USB_ControlRequest.wValue & 0x7F));
return; return;
} }
static void USB_Device_SetConfiguration(void) static void USB_Device_SetConfiguration(void)
{ {
uint8_t wValue_LSB = Endpoint_Read_Byte();
bool AlreadyConfigured = (USB_ConfigurationNumber != 0); bool AlreadyConfigured = (USB_ConfigurationNumber != 0);
#if defined(USE_SINGLE_DEVICE_CONFIGURATION) #if defined(USE_SINGLE_DEVICE_CONFIGURATION)
if (wValue_LSB > 1) if (USB_ControlRequest.wValue > 1)
#else #else
USB_Descriptor_Device_t* DevDescriptorPtr; USB_Descriptor_Device_t* DevDescriptorPtr;
if ((USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr) == NO_DESCRIPTOR) || if ((USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr) == NO_DESCRIPTOR) ||
#if defined(USE_RAM_DESCRIPTORS) #if defined(USE_RAM_DESCRIPTORS)
(wValue_LSB > DevDescriptorPtr->NumberOfConfigurations)) (USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations))
#elif defined (USE_EEPROM_DESCRIPTORS) #elif defined (USE_EEPROM_DESCRIPTORS)
(wValue_LSB > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations))) (USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
#else #else
(wValue_LSB > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations))) (USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations)))
#endif #endif
#endif #endif
{ {
@ -154,7 +153,7 @@ static void USB_Device_SetConfiguration(void)
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
USB_ConfigurationNumber = wValue_LSB; USB_ConfigurationNumber = USB_ControlRequest.wValue;
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -178,24 +177,23 @@ void USB_Device_GetConfiguration(void)
static void USB_Device_GetDescriptor(void) static void USB_Device_GetDescriptor(void)
{ {
uint16_t wValue = Endpoint_Read_Word_LE();
uint16_t wIndex = Endpoint_Read_Word_LE();
uint16_t wLength = Endpoint_Read_Word_LE();
void* DescriptorPointer; void* DescriptorPointer;
uint16_t DescriptorSize; uint16_t DescriptorSize;
bool SendZLP; if ((DescriptorSize = USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex, &DescriptorPointer)) == NO_DESCRIPTOR)
if ((DescriptorSize = USB_GetDescriptor(wValue, wIndex, &DescriptorPointer)) == NO_DESCRIPTOR)
return; return;
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
#if defined(USE_RAM_DESCRIPTORS)
Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize);
#else
bool SendZLP;
if (wLength > DescriptorSize) if (USB_ControlRequest.wLength > DescriptorSize)
wLength = DescriptorSize; USB_ControlRequest.wLength = DescriptorSize;
while (wLength) while (USB_ControlRequest.wLength)
{ {
while (!(Endpoint_IsINReady())) while (!(Endpoint_IsINReady()))
{ {
@ -206,17 +204,15 @@ static void USB_Device_GetDescriptor(void)
} }
} }
while (wLength && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize)) while (USB_ControlRequest.wLength && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
{ {
#if defined(USE_RAM_DESCRIPTORS) #if defined (USE_EEPROM_DESCRIPTORS)
Endpoint_Write_Byte(*((uint8_t*)DescriptorPointer++));
#elif defined (USE_EEPROM_DESCRIPTORS)
Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer++)); Endpoint_Write_Byte(eeprom_read_byte(DescriptorPointer++));
#else #else
Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer++)); Endpoint_Write_Byte(pgm_read_byte(DescriptorPointer++));
#endif #endif
wLength--; USB_ControlRequest.wLength--;
} }
SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize); SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
@ -230,20 +226,16 @@ static void USB_Device_GetDescriptor(void)
} }
while (!(Endpoint_IsOUTReceived())); while (!(Endpoint_IsOUTReceived()));
#endif
Endpoint_ClearOUT(); Endpoint_ClearOUT();
} }
static void USB_Device_GetStatus(const uint8_t bmRequestType) static void USB_Device_GetStatus(void)
{ {
uint8_t CurrentStatus = 0; uint8_t CurrentStatus = 0;
Endpoint_Discard_Word(); switch (USB_ControlRequest.bmRequestType)
#if !defined(FEATURELESS_CONTROL_ONLY_DEVICE)
uint8_t wIndex_LSB = Endpoint_Read_Byte();
#endif
switch (bmRequestType)
{ {
case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE): case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE):
if (USB_CurrentlySelfPowered) if (USB_CurrentlySelfPowered)
@ -255,15 +247,16 @@ static void USB_Device_GetStatus(const uint8_t bmRequestType)
break; break;
#if !defined(FEATURELESS_CONTROL_ONLY_DEVICE) #if !defined(FEATURELESS_CONTROL_ONLY_DEVICE)
case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT): case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT):
Endpoint_SelectEndpoint(wIndex_LSB); Endpoint_SelectEndpoint(USB_ControlRequest.wIndex);
CurrentStatus = Endpoint_IsStalled(); CurrentStatus = Endpoint_IsStalled();
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
break; break;
#endif #endif
} }
Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP);
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_Write_Word_LE(CurrentStatus); Endpoint_Write_Word_LE(CurrentStatus);
@ -275,17 +268,14 @@ static void USB_Device_GetStatus(const uint8_t bmRequestType)
} }
#if !defined(FEATURELESS_CONTROL_ONLY_DEVICE) #if !defined(FEATURELESS_CONTROL_ONLY_DEVICE)
static void USB_Device_ClearSetFeature(const uint8_t bRequest, const uint8_t bmRequestType) static void USB_Device_ClearSetFeature(void)
{ {
uint16_t wValue = Endpoint_Read_Word_LE(); switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT)
uint16_t wIndex = Endpoint_Read_Word_LE();
switch (bmRequestType & CONTROL_REQTYPE_RECIPIENT)
{ {
case REQREC_ENDPOINT: case REQREC_ENDPOINT:
if (wValue == FEATURE_ENDPOINT_HALT) if (USB_ControlRequest.wValue == FEATURE_ENDPOINT_HALT)
{ {
uint8_t EndpointIndex = (wIndex & ENDPOINT_EPNUM_MASK); uint8_t EndpointIndex = (USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK);
if (EndpointIndex != ENDPOINT_CONTROLEP) if (EndpointIndex != ENDPOINT_CONTROLEP)
{ {
@ -293,7 +283,7 @@ static void USB_Device_ClearSetFeature(const uint8_t bRequest, const uint8_t bmR
if (Endpoint_IsEnabled()) if (Endpoint_IsEnabled())
{ {
if (bRequest == REQ_ClearFeature) if (USB_ControlRequest.bRequest == REQ_ClearFeature)
{ {
Endpoint_ClearStall(); Endpoint_ClearStall();
Endpoint_ResetFIFO(EndpointIndex); Endpoint_ResetFIFO(EndpointIndex);

@ -39,6 +39,7 @@
#include "../HighLevel/StdDescriptors.h" #include "../HighLevel/StdDescriptors.h"
#include "../HighLevel/Events.h" #include "../HighLevel/Events.h"
#include "../HighLevel/StdRequestType.h" #include "../HighLevel/StdRequestType.h"
#include "../HighLevel/USBTask.h"
#include "LowLevel.h" #include "LowLevel.h"
/* Enable C linkage for C++ Compilers: */ /* Enable C linkage for C++ Compilers: */
@ -118,9 +119,9 @@
static void USB_Device_SetConfiguration(void); static void USB_Device_SetConfiguration(void);
static void USB_Device_GetConfiguration(void); static void USB_Device_GetConfiguration(void);
static void USB_Device_GetDescriptor(void); static void USB_Device_GetDescriptor(void);
static void USB_Device_GetStatus(const uint8_t bmRequestType); static void USB_Device_GetStatus(void);
#if !defined(FEATURELESS_CONTROL_ONLY_DEVICE) #if !defined(FEATURELESS_CONTROL_ONLY_DEVICE)
static void USB_Device_ClearSetFeature(const uint8_t bRequest, const uint8_t bmRequestType); static void USB_Device_ClearSetFeature(void);
#endif #endif
#endif #endif
#endif #endif

@ -292,8 +292,9 @@ uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length) uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
{ {
uint8_t* DataStream = (uint8_t*)Buffer; uint8_t* DataStream = (uint8_t*)Buffer;
bool SendZLP = true; bool LastPacketFull = false;
bool ShortTransfer = (Length < USB_ControlRequest.wLength);
while (Length && !(Endpoint_IsOUTReceived())) while (Length && !(Endpoint_IsOUTReceived()))
{ {
@ -306,14 +307,14 @@ uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
Length--; Length--;
} }
SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize); LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
Endpoint_ClearIN(); Endpoint_ClearIN();
} }
if (Endpoint_IsOUTReceived()) if (Endpoint_IsOUTReceived())
return ENDPOINT_RWCSTREAM_ERROR_HostAborted; return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
if (SendZLP) if (LastPacketFull || ShortTransfer)
{ {
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
Endpoint_ClearIN(); Endpoint_ClearIN();
@ -326,8 +327,9 @@ uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length) uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
{ {
uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1); uint8_t* DataStream = (uint8_t*)(Buffer + Length - 1);
bool SendZLP = true; bool LastPacketFull = false;
bool ShortTransfer = (Length < USB_ControlRequest.wLength);
while (Length && !(Endpoint_IsOUTReceived())) while (Length && !(Endpoint_IsOUTReceived()))
{ {
@ -340,14 +342,14 @@ uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
Length--; Length--;
} }
SendZLP = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize); LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
Endpoint_ClearIN(); Endpoint_ClearIN();
} }
if (Endpoint_IsOUTReceived()) if (Endpoint_IsOUTReceived())
return ENDPOINT_RWCSTREAM_ERROR_HostAborted; return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
if (SendZLP) if (LastPacketFull || ShortTransfer)
{ {
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
Endpoint_ClearIN(); Endpoint_ClearIN();

@ -35,15 +35,13 @@
#define INCLUDE_FROM_HOSTCHAPTER9_C #define INCLUDE_FROM_HOSTCHAPTER9_C
#include "HostChapter9.h" #include "HostChapter9.h"
USB_Host_Request_Header_t USB_HostRequest;
uint8_t USB_Host_SendControlRequest(void* BufferPtr) uint8_t USB_Host_SendControlRequest(void* BufferPtr)
{ {
uint8_t* HeaderStream = (uint8_t*)&USB_HostRequest; uint8_t* HeaderStream = (uint8_t*)&USB_ControlRequest;
uint8_t* DataStream = (uint8_t*)BufferPtr; uint8_t* DataStream = (uint8_t*)BufferPtr;
bool BusSuspended = USB_Host_IsBusSuspended(); bool BusSuspended = USB_Host_IsBusSuspended();
uint8_t ReturnStatus = HOST_SENDCONTROL_Successful; uint8_t ReturnStatus = HOST_SENDCONTROL_Successful;
uint16_t DataLen = USB_HostRequest.wLength; uint16_t DataLen = USB_ControlRequest.wLength;
USB_Host_ResumeBus(); USB_Host_ResumeBus();
@ -55,7 +53,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
Pipe_Unfreeze(); Pipe_Unfreeze();
for (uint8_t HeaderByte = 0; HeaderByte < sizeof(USB_Host_Request_Header_t); HeaderByte++) for (uint8_t HeaderByte = 0; HeaderByte < sizeof(USB_Request_Header_t); HeaderByte++)
Pipe_Write_Byte(*(HeaderStream++)); Pipe_Write_Byte(*(HeaderStream++));
Pipe_ClearSETUP(); Pipe_ClearSETUP();
@ -68,7 +66,7 @@ uint8_t USB_Host_SendControlRequest(void* BufferPtr)
if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful) if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful)
goto End_Of_Control_Send; goto End_Of_Control_Send;
if ((USB_HostRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_DEVICETOHOST) if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_DEVICETOHOST)
{ {
Pipe_SetToken(PIPE_TOKEN_IN); Pipe_SetToken(PIPE_TOKEN_IN);

@ -45,23 +45,6 @@
#endif #endif
/* Public Interface - May be used in end-application: */ /* Public Interface - May be used in end-application: */
/* Type Defines: */
/** Type define for a standard USB control request.
*
* \see StdRequestType.h for information on the request type and data.
* \see The USB 2.0 specification for more information on standard control requests.
*
* \ingroup Group_PipeControlReq
*/
typedef struct
{
uint8_t bmRequestType; /**< Type of the request. */
uint8_t bRequest; /**< Request command code. */
uint16_t wValue; /**< wValue parameter of the request. */
uint16_t wIndex; /**< wIndex parameter of the request. */
uint16_t wLength; /**< Length of the data to transfer in bytes. */
} USB_Host_Request_Header_t;
/* Enums: */ /* Enums: */
/** Enum for the USB_Host_SendControlRequest() return code, indicating the reason for the error /** Enum for the USB_Host_SendControlRequest() return code, indicating the reason for the error
* if the transfer of the request is unsuccessful. * if the transfer of the request is unsuccessful.
@ -81,17 +64,8 @@
HOST_SENDCONTROL_SoftwareTimeOut = 4, /**< The request or data transfer timed out. */ HOST_SENDCONTROL_SoftwareTimeOut = 4, /**< The request or data transfer timed out. */
}; };
/* Global Variables: */
/** Global for the request to send via the USB_Host_SendControlRequest() function. This
* global should be filled with the correct control request data before sending the request to
* the attached device while in host mode.
*
* \ingroup Group_PipeControlReq
*/
extern USB_Host_Request_Header_t USB_HostRequest;
/* Function Prototypes: */ /* Function Prototypes: */
/** Sends the request stored in the USB_HostRequest global structure to the attached device, /** Sends the request stored in the USB_ControlRequest global structure to the attached device,
* and transfers the data stored in the buffer to the device, or from the device to the buffer * and transfers the data stored in the buffer to the device, or from the device to the buffer
* as requested. The transfer is made on the currently selected pipe. * as requested. The transfer is made on the currently selected pipe.
* *

@ -37,7 +37,7 @@
uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; uint8_t USB_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE;
bool Pipe_ConfigurePipe(const uint8_t Number, const uint8_t Type, const uint8_t Token, const uint8_t EndpointNumber, bool Pipe_ConfigurePipe(const uint8_t Number, const uint8_t Type, const uint8_t Token, const uint8_t EndpointNumber,
const uint16_t Size, const uint8_t Banks) const uint16_t Size, const uint8_t Banks)
{ {
Pipe_SelectPipe(Number); Pipe_SelectPipe(Number);

@ -389,6 +389,8 @@
* is an IN direction and no packet (or an empty packet) has been received, or if the pipe is an OUT * is an IN direction and no packet (or an empty packet) has been received, or if the pipe is an OUT
* direction and the pipe bank is full. * direction and the pipe bank is full.
* *
* \note This function is not valid on CONTROL type pipes.
*
* \ingroup Group_PipePacketManagement * \ingroup Group_PipePacketManagement
* *
* \return Boolean true if the currently selected pipe may be read from or written to, depending on its direction * \return Boolean true if the currently selected pipe may be read from or written to, depending on its direction

@ -33,6 +33,9 @@
* - The Endpoint_ClearSetupReceived() macro has been renamed to Endpoint_ClearSETUP(). * - The Endpoint_ClearSetupReceived() macro has been renamed to Endpoint_ClearSETUP().
* - All endpoint read/write/discard aliases which did not have an explicitly endianness specifier (such as Endpoint_Read_Word()) have * - All endpoint read/write/discard aliases which did not have an explicitly endianness specifier (such as Endpoint_Read_Word()) have
* been removed for clarity. Existing projects should use the "_LE" suffix on such calls to use the explicit Little Endian versions. * been removed for clarity. Existing projects should use the "_LE" suffix on such calls to use the explicit Little Endian versions.
* - The USB_UnhandledControlPacket event no longer has any parameters. User code should no longer attempt to read in the remainder of
* the Control Request header as all Control Request header data is now preloaded by the library and made available in the
* USB_ControlRequest structure.
* *
* <b>Host Mode</b> * <b>Host Mode</b>
* - The USB_Host_SendControlRequest() function no longer automatically selects the Control pipe (pipe 0) to allow it to be used on * - The USB_Host_SendControlRequest() function no longer automatically selects the Control pipe (pipe 0) to allow it to be used on
@ -61,6 +64,8 @@
* and SetReportItemInfo() has been renamed to USB_GetHIDReportItemInfo(). * and SetReportItemInfo() has been renamed to USB_GetHIDReportItemInfo().
* - The values of the DSearch_Return_ErrorCodes_t and DSearch_Comp_Return_ErrorCodes_t enums have had their respective "Descriptor_Search" * - The values of the DSearch_Return_ErrorCodes_t and DSearch_Comp_Return_ErrorCodes_t enums have had their respective "Descriptor_Search"
* and "Descriptor_Search_Comp" prefixes changed to all caps. * and "Descriptor_Search_Comp" prefixes changed to all caps.
* - The USB_HostRequest global has been renamed to USB_ControlRequest, and is used in Device mode also. The USB_Host_Request_Header_t
* structure type has been renamed to USB_Request_Header_t.
* *
* \section Sec_Migration090401 Migrating from 090209 to 090401 * \section Sec_Migration090401 Migrating from 090209 to 090401
* *

@ -155,33 +155,20 @@ EVENT_HANDLER(USB_ConfigurationChanged)
EVENT_HANDLER(USB_UnhandledControlPacket) EVENT_HANDLER(USB_UnhandledControlPacket)
{ {
/* Handle HID Class specific requests */ /* Handle HID Class specific requests */
switch (bRequest) switch (USB_ControlRequest.bRequest)
{ {
case REQ_GetReport: case REQ_GetReport:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
USB_KeyboardReport_Data_t KeyboardReportData; USB_KeyboardReport_Data_t KeyboardReportData;
/* Create the next keyboard report for transmission to the host */ /* Create the next keyboard report for transmission to the host */
GetNextReport(&KeyboardReportData); GetNextReport(&KeyboardReportData);
/* Ignore report type and ID number value */
Endpoint_Discard_Word();
/* Ignore unused Interface number value */
Endpoint_Discard_Word();
/* Read in the number of bytes in the report to send to the host */
uint16_t wLength = Endpoint_Read_Word_LE();
/* If trying to send more bytes than exist to the host, clamp the value at the report size */
if (wLength > sizeof(KeyboardReportData))
wLength = sizeof(KeyboardReportData);
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Write the report data to the control endpoint */ /* Write the report data to the control endpoint */
Endpoint_Write_Control_Stream_LE(&KeyboardReportData, wLength); Endpoint_Write_Control_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData));
/* Finalize the stream transfer to send the last packet or clear the host abort */ /* Finalize the stream transfer to send the last packet or clear the host abort */
Endpoint_ClearOUT(); Endpoint_ClearOUT();
@ -189,7 +176,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_GetProtocol: case REQ_GetProtocol:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
@ -206,15 +193,12 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetProtocol: case REQ_SetProtocol:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Read in the wValue parameter containing the new protocol mode */
uint16_t wValue = Endpoint_Read_Word_LE();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* 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 = (USB_ControlRequest.wValue != 0x0000);
/* Acknowledge status stage */ /* Acknowledge status stage */
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
@ -223,15 +207,12 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_SetIdle: case REQ_SetIdle:
if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
/* Read in the wValue parameter containing the idle period */
uint16_t wValue = Endpoint_Read_Word_LE();
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
/* Get idle period in MSB */ /* Get idle period in MSB */
IdleCount = (wValue >> 8); IdleCount = (USB_ControlRequest.wValue >> 8);
/* Acknowledge status stage */ /* Acknowledge status stage */
while (!(Endpoint_IsINReady())); while (!(Endpoint_IsINReady()));
@ -240,7 +221,7 @@ EVENT_HANDLER(USB_UnhandledControlPacket)
break; break;
case REQ_GetIdle: case REQ_GetIdle:
if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{ {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();

Loading…
Cancel
Save