1268 lines
28 KiB
C
1268 lines
28 KiB
C
|
/*----------------------------------------------------------------------------
|
||
|
* 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 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 "type.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
|
||
|
|
||
|
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
|
||
|
*/
|
||
|
|
||
|
__inline uint32_t
|
||
|
USB_ReqGetStatus (void)
|
||
|
{
|
||
|
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))
|
||
|
{
|
||
|
*((uint16_t __attribute__ ((packed)) *) 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))
|
||
|
{
|
||
|
*((uint16_t __attribute__ ((packed)) *) 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
|
||
|
*/
|
||
|
|
||
|
__inline uint32_t
|
||
|
USB_ReqSetClrFeature (uint32_t sc)
|
||
|
{
|
||
|
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
|
||
|
*/
|
||
|
|
||
|
__inline uint32_t
|
||
|
USB_ReqSetAddress (void)
|
||
|
{
|
||
|
|
||
|
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
|
||
|
*/
|
||
|
|
||
|
__inline uint32_t
|
||
|
USB_ReqGetDescriptor (void)
|
||
|
{
|
||
|
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
|
||
|
*/
|
||
|
|
||
|
__inline uint32_t
|
||
|
USB_ReqGetConfiguration (void)
|
||
|
{
|
||
|
|
||
|
switch (SetupPacket.bmRequestType.BM.Recipient)
|
||
|
{
|
||
|
case REQUEST_TO_DEVICE:
|
||
|
EP0Data.pData = &USB_Configuration;
|
||
|
break;
|
||
|
default:
|
||
|
return (FALSE);
|
||
|
}
|
||
|
return (TRUE);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Add a number of bytes to a pointer's address
|
||
|
* Harder than you might think. Some compilers say:
|
||
|
* Expected an lvalue -- Assignment expects its first operand to be
|
||
|
* an lvalue. Please note that a cast removes the lvaluedness of an
|
||
|
* expression.
|
||
|
*
|
||
|
* vpptr = void pointer to pointer
|
||
|
* n = number of bytes to add to pointer
|
||
|
* Call looks like: AddPtr((void **)&myPointer, 8);
|
||
|
*/
|
||
|
|
||
|
__inline void
|
||
|
UsbAddPtr (void **vpptr, uint32_t n)
|
||
|
{
|
||
|
/* Declare a pointer to a pointer to a byte. Only a byte pointer
|
||
|
* can be incremented by a number of bytes. Other pointers will
|
||
|
* increment by a multiple of what they point to.
|
||
|
*/
|
||
|
uint8_t **bpptr;
|
||
|
|
||
|
/* Convert our void pointer to a pointer to a byte pointer to a pointer */
|
||
|
bpptr = (uint8_t **) vpptr;
|
||
|
|
||
|
/* Add 'n' bytes to our pointer value */
|
||
|
(*bpptr) += n;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Set Configuration USB Request
|
||
|
* Parameters: None (global SetupPacket)
|
||
|
* Return Value: TRUE - Success, FALSE - Error
|
||
|
*/
|
||
|
|
||
|
__inline uint32_t
|
||
|
USB_ReqSetConfiguration (void)
|
||
|
{
|
||
|
USB_COMMON_DESCRIPTOR *pD;
|
||
|
uint32_t alt = 0;
|
||
|
uint32_t n, m;
|
||
|
|
||
|
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
|
||
|
{
|
||
|
UsbAddPtr ((void **) &pD, ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength);
|
||
|
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;
|
||
|
}
|
||
|
UsbAddPtr ((void **) &pD, pD->bLength);
|
||
|
}
|
||
|
}
|
||
|
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
|
||
|
*/
|
||
|
|
||
|
__inline uint32_t
|
||
|
USB_ReqGetInterface (void)
|
||
|
{
|
||
|
|
||
|
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
|
||
|
*/
|
||
|
|
||
|
__inline uint32_t
|
||
|
USB_ReqSetInterface (void)
|
||
|
{
|
||
|
USB_COMMON_DESCRIPTOR *pD;
|
||
|
uint32_t ifn = 0, alt = 0, old = 0, msk = 0;
|
||
|
uint32_t n, m;
|
||
|
uint32_t set;
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
UsbAddPtr ((void **) &pD, ((USB_CONFIGURATION_DESCRIPTOR *) pD)->wTotalLength);
|
||
|
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;
|
||
|
}
|
||
|
UsbAddPtr ((void **) &pD, pD->bLength);
|
||
|
}
|
||
|
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;
|
||
|
|
||
|
}
|
||
|
}
|