📄 usb_otg_dev_setup.c
字号:
/*******************************************************************************
* File Name : usb_otg_dev_setup.c
* Description : S3C2460A USB OTG setup stage operations
* Author : Haksoo Kim
* Dept : Mobile solution, AP
* Created Date : 2005.06.02
* Version : 1.0
* History
* R1.0 (2005.06.02): First Release
********************************************************************************/
#include <string.h>
#include "def.h"
#include "Option.h"
#include "2460addr.h"
#include "2460lib.h"
#include "2460usb_otg_dev.h"
#include "usb_otg_dev_main.h"
#include "usb_otg.h"
#include "usb_otg_dev_lib.h"
#include "usb_otg_dev_setup.h"
// *** End point information ***
// EP0: control
// EP1: bulk in end point
// EP2: not used
// EP3: bulk out end point
// EP4: not used
// *** VERY IMPORTANT NOTE ***
// Every descriptor size of EP0 should be 8n+m(m=1~7).
// Otherwise, USB will not operate normally because the program
// doesn't prepare the case that the descriptor size is 8n+0.
// If the size of a descriptor is 8n, the 0 length packit should be sent.
// Special thanks to E.S.Choi for reminding me of this USB specification.
unsigned int ep0State;
unsigned int ep0SubState;
extern volatile int isUsbOtgSetConfiguration;
volatile unsigned char Rwuen;
volatile unsigned char Configuration=1;
volatile unsigned char AlterSetting;
volatile unsigned char Selfpwr=TRUE;
volatile unsigned char device_status;
volatile unsigned char interface_status;
volatile unsigned char endpoint0_status;
volatile unsigned char endpoint1_status;
volatile unsigned char endpoint3_status;
USB_SETUP_DATA descSetup;
USB_DEVICE_DESCRIPTOR descDev;
USB_CONFIGURATION_DESCRIPTOR descConf;
struct USB_INTERFACE_DESCRIPTOR descIf;
struct USB_ENDPOINT_DESCRIPTOR descEndpt0;
struct USB_ENDPOINT_DESCRIPTOR descEndpt1;
struct USB_CONFIGURATION_SET ConfigSet;
struct USB_INTERFACE_GET InterfaceGet;
struct USB_GET_STATUS StatusGet; //={0,0,0,0,0};
static const unsigned char descStr0[]={
4,STRING_TYPE,LANGID_US_L,LANGID_US_H, //codes representing languages
};
static const unsigned char descStr1[]={ //Manufacturer
(0x14+2),STRING_TYPE,
'S',0x0,'y',0x0,'s',0x0,'t',0x0,'e',0x0,'m',0x0,' ',0x0,'M',0x0,
'C',0x0,'U',0x0,
};
static const unsigned char descStr2[]={ //Product
(0x2a+2),STRING_TYPE,
'S',0x0,'E',0x0,'C',0x0,' ',0x0,'S',0x0,'3',0x0,'C',0x0,'2',0x0,
'4',0x0,'6',0x0,'0',0x0,'A',0x0,' ',0x0,'T',0x0,'e',0x0,'s',0x0,
't',0x0,' ',0x0,'B',0x0,'/',0x0,'D',0x0
};
void InitDescriptorTable(void)
{
//Standard device descriptor
descDev.bLength=0x12; //EP0_DEV_DESC_SIZE=0x12 bytes
descDev.bDescriptorType=DEVICE_TYPE; // descriptor types refer to USB spec, p187
descDev.bcdUSBL=0x10;
descDev.bcdUSBH=0x01; //Ver 1.10
descDev.bDeviceClass=0xFF; //device class is vendor specfic
descDev.bDeviceSubClass=0x0; //assignment by te USB
descDev.bDeviceProtocol=0x0; //class-specific protocols on an interface basis.
descDev.bMaxPacketSize0=0x8; // 8/16/32/64 are valid
descDev.idVendorL=0x45;
descDev.idVendorH=0x53; //vendor id : 0x5345
descDev.idProductL=0x34;
descDev.idProductH=0x12; //product id : 0x1234
descDev.bcdDeviceL=0x00; //device release number "0100"
descDev.bcdDeviceH=0x01;
descDev.iManufacturer=0x1; //index of string descriptor
descDev.iProduct=0x2; //index of string descriptor
descDev.iSerialNumber=0x0;
descDev.bNumConfigurations=0x1;
//Standard configuration descriptor
descConf.bLength=0x9;
descConf.bDescriptorType=CONFIGURATION_TYPE;
descConf.wTotalLengthL=0x20; //<cfg desc>+<if desc>+<endp0 desc>+<endp1 desc>
descConf.wTotalLengthH=0;
descConf.bNumInterfaces=1; //??
//dbg descConf.bConfigurationValue=2; //why 2? There's no reason.
descConf.bConfigurationValue=1; //??
descConf.iConfiguration=0;
descConf.bmAttributes=CONF_ATTR_DEFAULT|CONF_ATTR_SELFPOWERED; //bus powered only.
descConf.maxPower=25; //draws 50mA current from the USB bus.
//Standard interface descriptor
descIf.bLength=0x9;
descIf.bDescriptorType=INTERFACE_TYPE;
descIf.bInterfaceNumber=0x0;
descIf.bAlternateSetting=0x0; //?
descIf.bNumEndpoints=2; //# of endpoints except EP0
descIf.bInterfaceClass=0xff; //0x0 ?
descIf.bInterfaceSubClass=0x0;
descIf.bInterfaceProtocol=0x0;
descIf.iInterface=0x0;
//Standard endpoint1 descriptor
descEndpt0.bLength=0x7;
descEndpt0.bDescriptorType=ENDPOINT_TYPE;
descEndpt0.bEndpointAddress=OTG_DEV_BULKIN_ENDP|EP_ADDR_IN; // 24a0Aendpoint 1 is IN endpoint.
descEndpt0.bmAttributes=OTG_EP_ATTR_BULK;
descEndpt0.wMaxPacketSizeL=OTG_BULK_PKT_SIZE; //64
descEndpt0.wMaxPacketSizeH=0x0;
descEndpt0.bInterval=0x0; //not used
//Standard endpoint3 descriptor
descEndpt1.bLength=0x7;
descEndpt1.bDescriptorType=ENDPOINT_TYPE;
descEndpt1.bEndpointAddress=OTG_DEV_BULKOUT_ENDP|EP_ADDR_OUT; // 2400X endpoint 3 is OUT endpoint.
descEndpt1.bmAttributes=OTG_EP_ATTR_BULK;
descEndpt1.wMaxPacketSizeL=OTG_BULK_PKT_SIZE; //64
descEndpt1.wMaxPacketSizeH=0x0;
descEndpt1.bInterval=0x0; //not used
}
//->
//khs.050117
// for debug
#ifdef KHS_USBD_DEBUG
Usbd_Ep0_Data_s Usbd_Ep0_Data[100];
unsigned char count_Ep0_Data=0;
extern int first;
#endif
//<-
void UsbOtg_SetupHandler(void)
{
uint32 i, setupStatus,tmpData1, tmpData2;
uint8 *ptrSetupData = (uint8 *)&descSetup;
setupStatus = apOTG_TLI_DEV_G->setupStatus;
ep0State = EP0_STATE_INIT;
//* Read from Setup FIFO and then copy them to setup data structure
tmpData1 = apOTG_TLI_DEV_G->setupData1;
tmpData2 = apOTG_TLI_DEV_G->setupData2;
for(i = 0; i < 4; i++)
{
*ptrSetupData++ = (uint8)(tmpData1 & 0xff);
tmpData1 >>= 8;
}
for(i = 0; i < 4; i++)
{
*ptrSetupData++ = (uint8)(tmpData2 & 0xff);
tmpData2 >>= 8;
}
#ifdef KHS_USBD_DEBUG
if(first == 1)
{
PrintEp0Pkt((uint8 *)(&descSetup));
}
#endif
if((setupStatus & OTG_DEV_SETUP_GOOD_STATUS)&&(setupStatus & OTG_DEV_SETUP_STATUS_INTR))
{
apOTG_TLI_DEV_S->InEP[OTG_DEV_CTRL_ENDP].status = OTG_DEV_TX_NAK_INTR | OTG_DEV_TX_STATUS_INTR | OTG_DEV_TX_GOOD_STATUS;
apOTG_TLI_DEV_S->InEP[OTG_DEV_CTRL_ENDP].control = OTG_DEV_TX_FLUSHFIFO;
apOTG_TLI_DEV_S->InEP[OTG_DEV_CTRL_ENDP].txCount = 0;
switch(descSetup.bRequest)
{
case GET_DESCRIPTOR:
switch(descSetup.bValueH){
case DEVICE_TYPE:
ep0State=EP0_STATE_GD_DEV_0;
break;
case CONFIGURATION_TYPE:
if((descSetup.bLengthL+(descSetup.bLengthH<<8))>0x9)
//bLengthH should be used for bLength=0x209 at WIN2K.
ep0State=EP0_STATE_GD_CFG_0; //for WIN98,WIN2K
else
ep0State=EP0_STATE_GD_CFG_ONLY_0; //for WIN2K
break;
case STRING_TYPE:
switch(descSetup.bValueL)
{
case 0:
ep0State=EP0_STATE_GD_STR_I0;
break;
case 1:
ep0State=EP0_STATE_GD_STR_I1;
break;
case 2:
ep0State=EP0_STATE_GD_STR_I2;
break;
default:
break;
}
ep0SubState=0;
break;
case INTERFACE_TYPE:
ep0State=EP0_STATE_GD_IF_ONLY_0; //for WIN98
break;
case ENDPOINT_TYPE:
switch(descSetup.bValueL&0xf)
{
case 0:
ep0State=EP0_STATE_GD_EP0_ONLY_0;
break;
case 1:
ep0State=EP0_STATE_GD_EP1_ONLY_0;
break;
default:
break;
}
break;
default:
break;
}
break;
case SET_ADDRESS:
// not necessary because processed in OTG h/w
/*
rFUNC_ADDR_REG=descSetup.bValueL | 0x80;
ep0State=EP0_STATE_INIT;
*/
break;
case SET_CONFIGURATION:
// not necessary because processed in OTG h/w
/*
ConfigSet.ConfigurationValue=descSetup.bValueL;
ep0State=EP0_STATE_INIT;
isUsbOtgSetConfiguration=1;
*/
break;
//////////////////////// For chapter 9 test ////////////////////
case CLEAR_FEATURE:
// not necessary because processed in OTG h/w
/*
switch (descSetup.bmRequestType)
{
case DEVICE_RECIPIENT: //* clear remote wake up feature
if (descSetup.bValueL == 1)
Rwuen = FALSE;
break;
case ENDPOINT_RECIPIENT: //* clear endpoint halt feature
if (descSetup.bValueL == 0)
{
if((descSetup.bIndexL & 0x7f) == 0x00){
StatusGet.Endpoint0= 0;
}
if((descSetup.bIndexL & 0x8f) == 0x81){ // IN Endpoint 1
StatusGet.Endpoint1= 0;
}
if((descSetup.bIndexL & 0x8f) == 0x03){ // OUT Endpoint 3
StatusGet.Endpoint3= 0;
}
}
break;
default:
break;
}
ep0State=EP0_STATE_INIT;
*/
break;
case GET_CONFIGURATION:
// not necessary because processed in OTG h/w
/*
ep0State=EP0_CONFIG_SET;
*/
break;
case GET_INTERFACE:
// not necessary because processed in OTG h/w
/*
ep0State=EP0_INTERFACE_GET;
*/
break;
case GET_STATUS:
// not necessary because processed in OTG h/w
/*
switch(descSetup.bmRequestType)
{
case (0x80):
StatusGet.Device=((unsigned char)Rwuen<<1)|(unsigned char)Selfpwr;
ep0State=EP0_GET_STATUS0;
break;
case (0x81):
StatusGet.Interface=0;
ep0State=EP0_GET_STATUS1;
break;
case (0x82):
if((descSetup.bIndexL & 0x7f) == 0x00){
ep0State=EP0_GET_STATUS2;
}
if((descSetup.bIndexL & 0x8f) == 0x81){
ep0State=EP0_GET_STATUS3;
}
if((descSetup.bIndexL & 0x8f) == 0x03){
ep0State=EP0_GET_STATUS4;
}
break;
default:
break;
}
*/
break;
case SET_DESCRIPTOR:
//...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -