X-Git-Url: http://git.asbjorn.biz/?p=rapper.git;a=blobdiff_plain;f=new_cmsis%2Fusb%2Fusbcore.c;fp=new_cmsis%2Fusb%2Fusbcore.c;h=f80c7eee81c2e45a4ff433139766debdca9967d3;hp=0000000000000000000000000000000000000000;hb=0163b16211dc58d6619b923b370be8491fb984cb;hpb=ed7a4dbc9f9d17923417de5ebc515e76e979c6f9 diff --git a/new_cmsis/usb/usbcore.c b/new_cmsis/usb/usbcore.c new file mode 100755 index 0000000..f80c7ee --- /dev/null +++ b/new_cmsis/usb/usbcore.c @@ -0,0 +1,1112 @@ +/*---------------------------------------------------------------------------- + * U S B - K e r n e l + *---------------------------------------------------------------------------- + * Name: usbcore.c + * Purpose: USB Core Module + * Version: V1.20 + *---------------------------------------------------------------------------- + * This software is supplied "AS IS" without any warranties, express, + * implied or statutory, including but not limited to the implied + * warranties of fitness for purpose, satisfactory quality and + * noninfringement. Keil extends you a royalty-free right to reproduce + * and distribute executable files created using this software for use + * on NXP Semiconductors LPC family microcontroller devices only. Nothing + * else gives you the right to use this software. + * + * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. + *---------------------------------------------------------------------------- + * History: + * V1.20 Added vendor specific requests + * Changed string descriptor handling + * Reworked Endpoint0 + * V1.00 Initial Version + *----------------------------------------------------------------------------*/ +#include "lpc_types.h" + +#include "usb.h" +#include "usbcfg.h" +#include "usbhw.h" +#include "usbcore.h" +#include "usbdesc.h" +#include "usbuser.h" + +#if (USB_CLASS) + +#if (USB_AUDIO) +#include "audio.h" +#include "adcuser.h" +#endif + +#if (USB_HID) +#include "hid.h" +#include "hiduser.h" +#endif + +#if (USB_MSC) +#include "msc.h" +#include "mscuser.h" +extern MSC_CSW CSW; +#endif + +#if (USB_CDC) +#include "cdc.h" +#include "cdcuser.h" +#endif + +#endif + +#if (USB_VENDOR) +#include "vendor.h" +#endif + +#if defined ( __CC_ARM ) +#pragma diag_suppress 111,1441 +#endif + +#if defined ( __GNUC__ ) +#define __packed __attribute__((__packed__)) +#endif + +uint16_t USB_DeviceStatus; +uint8_t USB_DeviceAddress; +uint8_t USB_Configuration; +uint32_t USB_EndPointMask; +uint32_t USB_EndPointHalt; +uint32_t USB_EndPointStall; /* EP must stay stalled */ +uint8_t USB_NumInterfaces; +uint8_t USB_AltSetting[USB_IF_NUM]; + +uint8_t EP0Buf[USB_MAX_PACKET0]; + + +USB_EP_DATA EP0Data; + +USB_SETUP_PACKET SetupPacket; + + +/* + * Reset USB Core + * Parameters: None + * Return Value: None + */ + +void USB_ResetCore (void) { + + USB_DeviceStatus = USB_POWER; + USB_DeviceAddress = 0; + USB_Configuration = 0; + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; +} + + +/* + * USB Request - Setup Stage + * Parameters: None (global SetupPacket) + * Return Value: None + */ + +void USB_SetupStage (void) { + USB_ReadEP(0x00, (uint8_t *)&SetupPacket); +} + + +/* + * USB Request - Data In Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void USB_DataInStage (void) { + uint32_t cnt; + + if (EP0Data.Count > USB_MAX_PACKET0) { + cnt = USB_MAX_PACKET0; + } else { + cnt = EP0Data.Count; + } + cnt = USB_WriteEP(0x80, EP0Data.pData, cnt); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Data Out Stage + * Parameters: None (global EP0Data) + * Return Value: None + */ + +void USB_DataOutStage (void) { + uint32_t cnt; + + cnt = USB_ReadEP(0x00, EP0Data.pData); + EP0Data.pData += cnt; + EP0Data.Count -= cnt; +} + + +/* + * USB Request - Status In Stage + * Parameters: None + * Return Value: None + */ + +void USB_StatusInStage (void) { + USB_WriteEP(0x80, NULL, 0); +} + + +/* + * USB Request - Status Out Stage + * Parameters: None + * Return Value: None + */ + +void USB_StatusOutStage (void) { + USB_ReadEP(0x00, EP0Buf); +} + + +/* + * Get Status USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +#if defined ( __IAR_SYSTEMS_ICC__ ) +inline uint32_t USB_ReqGetStatus (void) { +#else +__inline uint32_t USB_ReqGetStatus (void) { +#endif + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + EP0Data.pData = (uint8_t *)&USB_DeviceStatus; + break; + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) { + *((__packed uint16_t *)EP0Buf) = 0; + *((uint16_t *)EP0Buf) = 0; + EP0Data.pData = EP0Buf; + } else { + return (FALSE); + } + break; + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (((USB_Configuration != 0) || ((n & 0x0F) == 0)) && (USB_EndPointMask & m)) { + *((__packed uint16_t *)EP0Buf) = (USB_EndPointHalt & m) ? 1 : 0; + *((uint16_t *)EP0Buf) = (USB_EndPointHalt & m) ? 1 : 0; + EP0Data.pData = EP0Buf; + } else { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set/Clear Feature USB Request + * Parameters: sc: 0 - Clear, 1 - Set + * (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +#if defined ( __IAR_SYSTEMS_ICC__ ) +inline uint32_t USB_ReqSetClrFeature (uint32_t sc) { +#else +__inline uint32_t USB_ReqSetClrFeature (uint32_t sc) { +#endif + uint32_t n, m; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + if (SetupPacket.wValue.W == USB_FEATURE_REMOTE_WAKEUP) { + if (sc) { + USB_WakeUpCfg(TRUE); + USB_DeviceStatus |= USB_GETSTATUS_REMOTE_WAKEUP; + } else { + USB_WakeUpCfg(FALSE); + USB_DeviceStatus &= ~USB_GETSTATUS_REMOTE_WAKEUP; + } + } else { + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + return (FALSE); + case REQUEST_TO_ENDPOINT: + n = SetupPacket.wIndex.WB.L & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if ((USB_Configuration != 0) && ((n & 0x0F) != 0) && (USB_EndPointMask & m)) { + if (SetupPacket.wValue.W == USB_FEATURE_ENDPOINT_STALL) { + if (sc) { + USB_SetStallEP(n); + USB_EndPointHalt |= m; + } else { + if ((USB_EndPointStall & m) != 0) { + return (TRUE); + } + USB_ClrStallEP(n); +#if (USB_MSC) + if ((n == MSC_EP_IN) && ((USB_EndPointHalt & m) != 0)) { + /* Compliance Test: rewrite CSW after unstall */ + if (CSW.dSignature == MSC_CSW_Signature) { + USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW)); + } + } +#endif + USB_EndPointHalt &= ~m; + } + } else { + return (FALSE); + } + } else { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Address USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +#if defined ( __IAR_SYSTEMS_ICC__ ) +inline uint32_t USB_ReqSetAddress (void) { +#else +__inline uint32_t USB_ReqSetAddress (void) { +#endif + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + USB_DeviceAddress = 0x80 | SetupPacket.wValue.WB.L; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Descriptor USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +#if defined ( __IAR_SYSTEMS_ICC__ ) +inline uint32_t USB_ReqGetDescriptor (void) { +#else +__inline uint32_t USB_ReqGetDescriptor (void) { +#endif + uint8_t *pD; + uint32_t len, n; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + switch (SetupPacket.wValue.WB.H) { + case USB_DEVICE_DESCRIPTOR_TYPE: + EP0Data.pData = (uint8_t *)USB_DeviceDescriptor; + len = USB_DEVICE_DESC_SIZE; + break; + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + pD = (uint8_t *)USB_ConfigDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) { + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength != 0) { + pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + } + } + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bLength == 0) { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + break; + case USB_STRING_DESCRIPTOR_TYPE: + pD = (uint8_t *)USB_StringDescriptor; + for (n = 0; n != SetupPacket.wValue.WB.L; n++) { + if (((USB_STRING_DESCRIPTOR *)pD)->bLength != 0) { + pD += ((USB_STRING_DESCRIPTOR *)pD)->bLength; + } + } + if (((USB_STRING_DESCRIPTOR *)pD)->bLength == 0) { + return (FALSE); + } + EP0Data.pData = pD; + len = ((USB_STRING_DESCRIPTOR *)EP0Data.pData)->bLength; + break; + default: + return (FALSE); + } + break; + case REQUEST_TO_INTERFACE: + switch (SetupPacket.wValue.WB.H) { +#if USB_HID + case HID_HID_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *)USB_ConfigDescriptor + HID_DESC_OFFSET; + len = HID_DESC_SIZE; + break; + case HID_REPORT_DESCRIPTOR_TYPE: + if (SetupPacket.wIndex.WB.L != USB_HID_IF_NUM) { + return (FALSE); /* Only Single HID Interface is supported */ + } + EP0Data.pData = (uint8_t *)HID_ReportDescriptor; + len = HID_ReportDescSize; + break; + case HID_PHYSICAL_DESCRIPTOR_TYPE: + return (FALSE); /* HID Physical Descriptor is not supported */ +#endif + default: + return (FALSE); + } +// break; + default: + return (FALSE); + } + + if (EP0Data.Count > len) { + EP0Data.Count = len; + } + + return (TRUE); +} + + +/* + * Get Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +#if defined ( __IAR_SYSTEMS_ICC__ ) +inline uint32_t USB_ReqGetConfiguration (void) { +#else +__inline uint32_t USB_ReqGetConfiguration (void) { +#endif + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + EP0Data.pData = &USB_Configuration; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Configuration USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +#if defined ( __IAR_SYSTEMS_ICC__ ) +inline uint32_t USB_ReqSetConfiguration (void) { +#else +__inline uint32_t USB_ReqSetConfiguration (void) { +#endif + USB_COMMON_DESCRIPTOR *pD; + uint32_t alt = 0; + uint32_t n, m; + uint32_t tmp; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + + if (SetupPacket.wValue.WB.L) { + pD = (USB_COMMON_DESCRIPTOR *)USB_ConfigDescriptor; + while (pD->bLength) { + switch (pD->bDescriptorType) { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue == SetupPacket.wValue.WB.L) { + USB_Configuration = SetupPacket.wValue.WB.L; + USB_NumInterfaces = ((USB_CONFIGURATION_DESCRIPTOR *)pD)->bNumInterfaces; + for (n = 0; n < USB_IF_NUM; n++) { + USB_AltSetting[n] = 0; + } + for (n = 1; n < 16; n++) { + if (USB_EndPointMask & (1 << n)) { + USB_DisableEP(n); + } + if (USB_EndPointMask & ((1 << 16) << n)) { + USB_DisableEP(n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall= 0x00000000; + USB_Configure(TRUE); + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bmAttributes & USB_CONFIG_POWERED_MASK) { + USB_DeviceStatus |= USB_GETSTATUS_SELF_POWERED; + } else { + USB_DeviceStatus &= ~USB_GETSTATUS_SELF_POWERED; + } + } else { +// (uint8_t *)pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + tmp = (uint32_t)pD; + tmp += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + pD = (USB_COMMON_DESCRIPTOR *)tmp; + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting; + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (alt == 0) { + n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + USB_EndPointMask |= m; + USB_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD); + USB_EnableEP(n); + USB_ResetEP(n); + } + break; + } +// (uint8_t *)pD += pD->bLength; + tmp = (uint32_t)pD; + tmp += pD->bLength; + pD = (USB_COMMON_DESCRIPTOR *)tmp; + } + } + else { + USB_Configuration = 0; + for (n = 1; n < 16; n++) { + if (USB_EndPointMask & (1 << n)) { + USB_DisableEP(n); + } + if (USB_EndPointMask & ((1 << 16) << n)) { + USB_DisableEP(n | 0x80); + } + } + USB_EndPointMask = 0x00010001; + USB_EndPointHalt = 0x00000000; + USB_EndPointStall = 0x00000000; + USB_Configure(FALSE); + } + + if (USB_Configuration != SetupPacket.wValue.WB.L) { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Get Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ + +#if defined ( __IAR_SYSTEMS_ICC__ ) +inline uint32_t USB_ReqGetInterface (void) { +#else +__inline uint32_t USB_ReqGetInterface (void) { +#endif + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_INTERFACE: + if ((USB_Configuration != 0) && (SetupPacket.wIndex.WB.L < USB_NumInterfaces)) { + EP0Data.pData = USB_AltSetting + SetupPacket.wIndex.WB.L; + } else { + return (FALSE); + } + break; + default: + return (FALSE); + } + return (TRUE); +} + + +/* + * Set Interface USB Request + * Parameters: None (global SetupPacket) + * Return Value: TRUE - Success, FALSE - Error + */ +#if defined ( __IAR_SYSTEMS_ICC__ ) +inline uint32_t USB_ReqSetInterface (void) { +#else +__inline uint32_t USB_ReqSetInterface (void) { +#endif + USB_COMMON_DESCRIPTOR *pD; + uint32_t ifn = 0, alt = 0, old = 0, msk = 0; + uint32_t n, m; + uint32_t set; + uint32_t tmp; + + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_INTERFACE: + if (USB_Configuration == 0) return (FALSE); + set = FALSE; + pD = (USB_COMMON_DESCRIPTOR *)USB_ConfigDescriptor; + while (pD->bLength) { + switch (pD->bDescriptorType) { + case USB_CONFIGURATION_DESCRIPTOR_TYPE: + if (((USB_CONFIGURATION_DESCRIPTOR *)pD)->bConfigurationValue != USB_Configuration) { +// (uint8_t *)pD += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + tmp = (uint32_t)pD; + tmp += ((USB_CONFIGURATION_DESCRIPTOR *)pD)->wTotalLength; + pD = (USB_COMMON_DESCRIPTOR *)tmp; + + continue; + } + break; + case USB_INTERFACE_DESCRIPTOR_TYPE: + ifn = ((USB_INTERFACE_DESCRIPTOR *)pD)->bInterfaceNumber; + alt = ((USB_INTERFACE_DESCRIPTOR *)pD)->bAlternateSetting; + msk = 0; + if ((ifn == SetupPacket.wIndex.WB.L) && (alt == SetupPacket.wValue.WB.L)) { + set = TRUE; + old = USB_AltSetting[ifn]; + USB_AltSetting[ifn] = (uint8_t)alt; + } + break; + case USB_ENDPOINT_DESCRIPTOR_TYPE: + if (ifn == SetupPacket.wIndex.WB.L) { + n = ((USB_ENDPOINT_DESCRIPTOR *)pD)->bEndpointAddress & 0x8F; + m = (n & 0x80) ? ((1 << 16) << (n & 0x0F)) : (1 << n); + if (alt == SetupPacket.wValue.WB.L) { + USB_EndPointMask |= m; + USB_EndPointHalt &= ~m; + USB_ConfigEP((USB_ENDPOINT_DESCRIPTOR *)pD); + USB_EnableEP(n); + USB_ResetEP(n); + msk |= m; + } + else if ((alt == old) && ((msk & m) == 0)) { + USB_EndPointMask &= ~m; + USB_EndPointHalt &= ~m; + USB_DisableEP(n); + } + } + break; + } +// (uint8_t *)pD += pD->bLength; + tmp = (uint32_t)pD; + tmp += pD->bLength; + pD = (USB_COMMON_DESCRIPTOR *)tmp; + } + break; + default: + return (FALSE); + } + + return (set); +} + + +/* + * USB Endpoint 0 Event Callback + * Parameters: event + * Return Value: none + */ + +void USB_EndPoint0 (uint32_t event) { + + switch (event) { + case USB_EVT_SETUP: + USB_SetupStage(); + USB_DirCtrlEP(SetupPacket.bmRequestType.BM.Dir); + EP0Data.Count = SetupPacket.wLength; /* Number of bytes to transfer */ + switch (SetupPacket.bmRequestType.BM.Type) { + + case REQUEST_STANDARD: + switch (SetupPacket.bRequest) { + case USB_REQUEST_GET_STATUS: + if (!USB_ReqGetStatus()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_CLEAR_FEATURE: + if (!USB_ReqSetClrFeature(0)) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_FEATURE_EVENT + USB_Feature_Event(); +#endif + break; + + case USB_REQUEST_SET_FEATURE: + if (!USB_ReqSetClrFeature(1)) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_FEATURE_EVENT + USB_Feature_Event(); +#endif + break; + + case USB_REQUEST_SET_ADDRESS: + if (!USB_ReqSetAddress()) { + goto stall_i; + } + USB_StatusInStage(); + break; + + case USB_REQUEST_GET_DESCRIPTOR: + if (!USB_ReqGetDescriptor()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_SET_DESCRIPTOR: +/*stall_o:*/ USB_SetStallEP(0x00); /* not supported */ + EP0Data.Count = 0; + break; + + case USB_REQUEST_GET_CONFIGURATION: + if (!USB_ReqGetConfiguration()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_SET_CONFIGURATION: + if (!USB_ReqSetConfiguration()) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_CONFIGURE_EVENT + USB_Configure_Event(); +#endif + break; + + case USB_REQUEST_GET_INTERFACE: + if (!USB_ReqGetInterface()) { + goto stall_i; + } + USB_DataInStage(); + break; + + case USB_REQUEST_SET_INTERFACE: + if (!USB_ReqSetInterface()) { + goto stall_i; + } + USB_StatusInStage(); +#if USB_INTERFACE_EVENT + USB_Interface_Event(); +#endif + break; + + default: + goto stall_i; + } + break; /* end case REQUEST_STANDARD */ + +#if USB_CLASS + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) { + + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) { /* IF number correct? */ + switch (SetupPacket.bRequest) { + case HID_REQUEST_GET_REPORT: + if (HID_GetReport()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_REPORT: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + case HID_REQUEST_GET_IDLE: + if (HID_GetIdle()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_IDLE: + if (HID_SetIdle()) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case HID_REQUEST_GET_PROTOCOL: + if (HID_GetProtocol()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case HID_REQUEST_SET_PROTOCOL: + if (HID_SetProtocol()) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_MSC + if (SetupPacket.wIndex.WB.L == USB_MSC_IF_NUM) { /* IF number correct? */ + switch (SetupPacket.bRequest) { + case MSC_REQUEST_RESET: + if ((SetupPacket.wValue.W == 0) && /* RESET with invalid parameters -> STALL */ + (SetupPacket.wLength == 0)) { + if (MSC_Reset()) { + USB_StatusInStage(); + goto setup_class_ok; + } + } + break; + case MSC_REQUEST_GET_MAX_LUN: + if ((SetupPacket.wValue.W == 0) && /* GET_MAX_LUN with invalid parameters -> STALL */ + (SetupPacket.wLength == 1)) { + if (MSC_GetMaxLUN()) { + EP0Data.pData = EP0Buf; + USB_DataInStage(); + goto setup_class_ok; + } + } + break; + } + } +#endif /* USB_MSC */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || + (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) { + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_IF_GetRequest()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) { + switch (SetupPacket.bRequest) { + case CDC_SEND_ENCAPSULATED_COMMAND: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_ENCAPSULATED_RESPONSE: + if (CDC_GetEncapsulatedResponse()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_COMM_FEATURE: + if (CDC_GetCommFeature(SetupPacket.wValue.W)) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_CLEAR_COMM_FEATURE: + if (CDC_ClearCommFeature(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SET_LINE_CODING: + EP0Data.pData = EP0Buf; /* data to be received, see USB_EVT_OUT */ + goto setup_class_ok; + case CDC_GET_LINE_CODING: + if (CDC_GetLineCoding()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case CDC_SET_CONTROL_LINE_STATE: + if (CDC_SetControlLineState(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + case CDC_SEND_BREAK: + if (CDC_SendBreak(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto setup_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; /* not supported */ + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_GET_CUR: + case AUDIO_REQUEST_GET_MIN: + case AUDIO_REQUEST_GET_MAX: + case AUDIO_REQUEST_GET_RES: + if (ADC_EP_GetRequest()) { + EP0Data.pData = EP0Buf; /* point to data to be sent */ + USB_DataInStage(); /* send requested data */ + goto setup_class_ok; + } + break; + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + EP0Data.pData = EP0Buf; /* data to be received */ + goto setup_class_ok; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } +setup_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev(TRUE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF(TRUE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP(TRUE)) { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + if (SetupPacket.wLength) { + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) { + USB_DataInStage(); + } + } else { + USB_StatusInStage(); + } + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: +stall_i: USB_SetStallEP(0x80); + EP0Data.Count = 0; + break; + } + break; /* end case USB_EVT_SETUP */ + + case USB_EVT_OUT: + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_HOST_TO_DEVICE) { + if (EP0Data.Count) { /* still data to receive ? */ + USB_DataOutStage(); /* receive data */ + if (EP0Data.Count == 0) { /* data complete ? */ + switch (SetupPacket.bmRequestType.BM.Type) { + + case REQUEST_STANDARD: + goto stall_i; /* not supported */ + +#if (USB_CLASS) + case REQUEST_CLASS: + switch (SetupPacket.bmRequestType.BM.Recipient) { + case REQUEST_TO_DEVICE: + goto stall_i; /* not supported */ + + case REQUEST_TO_INTERFACE: +#if USB_HID + if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) { /* IF number correct? */ + switch (SetupPacket.bRequest) { + case HID_REQUEST_SET_REPORT: + if (HID_SetReport()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_HID */ +#if USB_AUDIO + if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) || + (SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) { + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_IF_SetRequest()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_AUDIO */ +#if USB_CDC + if ((SetupPacket.wIndex.WB.L == USB_CDC_CIF_NUM) || /* IF number correct? */ + (SetupPacket.wIndex.WB.L == USB_CDC_DIF_NUM)) { + switch (SetupPacket.bRequest) { + case CDC_SEND_ENCAPSULATED_COMMAND: + if (CDC_SendEncapsulatedCommand()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_COMM_FEATURE: + if (CDC_SetCommFeature(SetupPacket.wValue.W)) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + case CDC_SET_LINE_CODING: + if (CDC_SetLineCoding()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } + } +#endif /* USB_CDC */ + goto stall_i; + /* end case REQUEST_TO_INTERFACE */ + + case REQUEST_TO_ENDPOINT: +#if USB_AUDIO + switch (SetupPacket.bRequest) { + case AUDIO_REQUEST_SET_CUR: +// case AUDIO_REQUEST_SET_MIN: +// case AUDIO_REQUEST_SET_MAX: +// case AUDIO_REQUEST_SET_RES: + if (ADC_EP_SetRequest()) { + USB_StatusInStage(); /* send Acknowledge */ + goto out_class_ok; + } + break; + } +#endif /* USB_AUDIO */ + goto stall_i; + /* end case REQUEST_TO_ENDPOINT */ + + default: + goto stall_i; + } +out_class_ok: /* request finished successfully */ + break; /* end case REQUEST_CLASS */ +#endif /* USB_CLASS */ + +#if USB_VENDOR + case REQUEST_VENDOR: + switch (SetupPacket.bmRequestType.BM.Recipient) { + + case REQUEST_TO_DEVICE: + if (!USB_ReqVendorDev(FALSE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_INTERFACE: + if (!USB_ReqVendorIF(FALSE)) { + goto stall_i; /* not supported */ + } + break; + + case REQUEST_TO_ENDPOINT: + if (!USB_ReqVendorEP(FALSE)) { + goto stall_i; /* not supported */ + } + break; + + default: + goto stall_i; + } + + USB_StatusInStage(); + + break; /* end case REQUEST_VENDOR */ +#endif /* USB_VENDOR */ + + default: + goto stall_i; + } + } + } + } else { + USB_StatusOutStage(); /* receive Acknowledge */ + } + break; /* end case USB_EVT_OUT */ + + case USB_EVT_IN : + if (SetupPacket.bmRequestType.BM.Dir == REQUEST_DEVICE_TO_HOST) { + USB_DataInStage(); /* send data */ + } else { + if (USB_DeviceAddress & 0x80) { + USB_DeviceAddress &= 0x7F; + USB_SetAddress(USB_DeviceAddress); + } + } + break; /* end case USB_EVT_IN */ + + case USB_EVT_OUT_STALL: + USB_ClrStallEP(0x00); + break; + + case USB_EVT_IN_STALL: + USB_ClrStallEP(0x80); + break; + + } +}