📄 usb_device_config.c
字号:
#include "def.h"
#include "2410addr.h"
#include "2410lib.h"
#include "uart.h"
#include "USB_device_lib.h"
#include "USB_device_config.h"
static struct USB_SETUP_DATA descSetup;
static struct USB_DEVICE_DESCRIPTOR descDev;
static struct USB_CONFIGURATION_DESCRIPTOR descConf;
static struct USB_INTERFACE_DESCRIPTOR descIf;
static struct USB_ENDPOINT_DESCRIPTOR descEndpt0;
static struct USB_ENDPOINT_DESCRIPTOR descEndpt1;
volatile U32 ep0State;
volatile U32 ep0SubState;
volatile U32 isUsbdSetConfiguration;
volatile U8 ep0_csr;
//volatile int ep0SubState;
static void Descriptor_Type_Handler(U8 type);
static void Standard_bRequest_Handler(U8 choice);
static void Class_bRequest_Handler(U8 choice);
static void Ep0State_Handler(U32 Ep0State);
static const U8 descStr0[]={
4,STRING_TYPE,LANGID_US_L,LANGID_US_H, //codes representing languages
};
static const U8 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 U8 descStr2[]={ //Product
(0x2a+2),STRING_TYPE,
'S',0x0,'E',0x0,'C',0x0,' ',0x0,'S',0x0,'3',0x0,'C',0x0,'2',0x0,
'4',0x0,'1',0x0,'0',0x0,'X',0x0,' ',0x0,'T',0x0,'E',0x0,'S',0x0,
'T',0x0,' ',0x0,'B',0x0,'/',0x0,'D',0x0
};
static const U8 descStr4[]={ //Product
(0x2a+2),STRING_TYPE,
'Y',0x0,'a',0x0,'n',0x0,'g',0x0,'Z',0x0,'h',0x0,'e',0x0,'n',0x0,
'g',0x0,'X',0x0,'i',0x0,'a',0x0,'n',0x0,'X',0x0,'X',0x0,'X',0x0,
'M',0x0,'o',0x0,'u',0x0,'s',0x0,'e',0x0
};
static const U8 descStr3[] =
{
(0x2a+2),STRING_TYPE,
'H',0,'I',0,'D',0,' ',0,'M',0,'o',0,'u',0,'s',0,'e',0
};
const char hid_report_desc_table[] =
{
Usage_Page, 0x01, /*usage page (generic desktop) */
Usage, 0x02, /*usage (mouse) */
Collection, 0x01, /*collection (application) */
Usage, 0x01, /*pointer*/
Collection, 0x00, /*physical*/
Usage_Page, 0x09, /*usage page (buttons) */
Usage_Min, 0x01, /*usage minimum (1) */
Usage_Max, 0x03, /*usage maximum (3) */
Logical_Min, 0x00, /*logical minimum (0) */
Logical_Max, 0x01, /*logical maximum (1) */
Report_Count, 0x03, /*report count (3 bytes) */
Report_Size, 0x01, /*report size (1) */
Input, 0x02, /*input (3 button bits) */
Report_Count, 0x01, /*report count (1) */
Report_Size, 0x05, /*report size (5) */
Input, 0x01, /*input (constant 5 bit padding) */
Usage_Page, 0x01, /*usage page (generic desktop) */
Usage, 0x30, /*X*/
Usage, 0x31, /*Y*/
Logical_Min, 0x81, /*logical minimum (-127) */
Logical_Max, 0x7F, /*logical maximum (127) */
Report_Size, 0x08, /*report size (8) */
Report_Count, 0x02, /*report count (2) */
Input, 0x06, /*input (2 position bytes X & Y) */
Usage_Page, 0x01, /*usage page (generic desktop) */
Usage, 0x38, /*wheel*/
Report_Size, 0x08, /*report size (8) */
Report_Count, 0x01, /*wheel size = 1 byte*/
Input, 0x06, /*variable data bit field with relative position*/
//Usage, 0x3c, /*motion wakeup*/
//Logical_Min, 0x00, /*0 no movement*/
//Logical_Max, 0x01, /*1 movement*/
//Report_Size, 0x01, /*1st bit represents movement*/
//Report_Count, 0x01, /*1 report*/
//Feature, 0x22, /*Variable Data Bit Field with absolute positioning and no preferred state*/
//Report_Count, 0x07, /*7 reports for reversing, upper 7 bits of byte 3*/
//Feature, 0x01, /*Constant Array Bit Field with absolute positioning*/
End, /*end collection*/
End /* end collection, end collection */
};
const char Class_Descriptor[] =
{
0x09, /* descriptor size (9 bytes) */
0x21, /* descriptor type (HID) */
0x10, 0x01,/* class specification (1.10) */
0x00, /* hardware target country */
0x01, /* number of hid class desriptors to follow (1) */
0x22, /* report descriptor type (2) */
sizeof(hid_report_desc_table),
0x00
};
static void InitDescriptorTable(U8 fun)
{
//UsbFunction = fun-1;
//Standard device descriptor
descDev.bLength = 0x12; //EP0_DEV_DESC_SIZE=0x12 bytes
descDev.bDescriptorType = 0x01;
descDev.bcdUSBL = 0x10;
descDev.bcdUSBH = 0x01; //Ver 1.10
descDev.bDeviceClass = 0x00; //0x0
descDev.bDeviceSubClass = 0x0;
descDev.bDeviceProtocol = 0x0;
descDev.bMaxPacketSize0 = 0x8;
descDev.idVendorL = 0x5e; //USB IF(0x04b4 0x6370 cypress) (0x045e mircosoft)
descDev.idVendorH = 0x04; //0x04
// if(fun==1)
// descDev.idProductL = 0x70;
// else
descDev.idProductL = 0x47;
descDev.idProductH = 0x00;
descDev.bcdDeviceL = 0x03;
descDev.bcdDeviceH = 0x00;
descDev.iManufacturer = 0x01; //index of string descriptor
descDev.iProduct = 0x02; //index of string descriptor
descDev.iSerialNumber = 0x0;
descDev.bNumConfigurations = 0x1;
//Standard configuration descriptor
descConf.bLength = 0x9;
descConf.bDescriptorType = 0x02;
descConf.wTotalLengthL = 0x22; //<cfg desc 9>+<interface desc 9>+<class 9>+<endp0 desc 7>+<endp1 desc 7>......
descConf.wTotalLengthH = 0;
descConf.bNumInterfaces = 1;
descConf.bConfigurationValue= 1;
descConf.iConfiguration = 3;
descConf.bmAttributes = 0xA0; //bus powered only. remote wake up
descConf.maxPower = 32; //draws 50mA current from the USB bus.
//Standard interface descriptor
descIf.bLength = 0x9;
descIf.bDescriptorType = 0x04;
descIf.bInterfaceNumber = 0x1;
descIf.bAlternateSetting = 0x0;
descIf.bNumEndpoints = 1; //# of endpoints except EP0
descIf.bInterfaceClass = 0x3; //HID
descIf.bInterfaceSubClass= 0x1; //boot protocol
descIf.bInterfaceProtocol= 0x2; //mouse
descIf.iInterface = 0x0;
//Standard endpoint0 descriptor
descEndpt0.bLength = 0x7;
descEndpt0.bDescriptorType = 5;
descEndpt0.bEndpointAddress = 0x81; // 2400Xendpoint 1 is IN endpoint.
descEndpt0.bmAttributes = 3;
descEndpt0.wMaxPacketSizeL = 64; //64
descEndpt0.wMaxPacketSizeH = 0x0;
descEndpt0.bInterval = 0x0a; //10ms
//Standard endpoint1 descriptor
descEndpt1.bLength = 0x7;
descEndpt1.bDescriptorType = 5;
descEndpt1.bEndpointAddress = 0x02; // 2400X endpoint 3 is OUT endpoint.
descEndpt1.bmAttributes = 3;
descEndpt1.wMaxPacketSizeL = 64; //64
descEndpt1.wMaxPacketSizeH = 0x0;
descEndpt1.bInterval = 0x0a; //10ms
}
//*****************************************
//change [ ep0State=EP0_STATE_INIT;]
//*****************************************
void ReconfigUsbd(void)
{
// *** End point information ***
// EP0: control
// EP1: bulk in end point
// EP2: not used
// EP3: bulk out end point
// EP4: not used
rPWR_REG = PWR_REG_DEFAULT_VALUE; //disable suspend mode
rINDEX_REG = 0;
rMAXP_REG = FIFO_SIZE_8; //EP0 max packit size = 8
rEP0_CSR = EP0_SERVICED_OUT_PKT_RDY|EP0_SERVICED_SETUP_END;
//EP0:clear OUT_PKT_RDY & SETUP_END
rINDEX_REG = 1;
#if (EP1_PKT_SIZE==32)
rMAXP_REG = FIFO_SIZE_32; //EP1:max packit size = 32
#else
rMAXP_REG = FIFO_SIZE_64; //EP1:max packit size = 64
#endif
rIN_CSR1_REG = EPI_FIFO_FLUSH|EPI_CDT;
rIN_CSR2_REG = EPI_MODE_IN|EPI_IN_DMA_INT_MASK|EPI_BULK; //IN mode, IN_DMA_INT=masked
rOUT_CSR1_REG= EPO_CDT;
rOUT_CSR2_REG= EPO_BULK|EPO_OUT_DMA_INT_MASK;
rINDEX_REG = 2;
rMAXP_REG = FIFO_SIZE_64; //EP2:max packit size = 64
rIN_CSR1_REG = EPI_FIFO_FLUSH|EPI_CDT|EPI_BULK; //EPI_BULK in IN_CSR1???
rIN_CSR2_REG = EPI_MODE_IN|EPI_IN_DMA_INT_MASK; //IN mode, IN_DMA_INT=masked, disable interrupt
rOUT_CSR1_REG= EPO_CDT;
rOUT_CSR2_REG= EPO_BULK|EPO_OUT_DMA_INT_MASK;
rINDEX_REG = 3;
#if (EP3_PKT_SIZE==32)
rMAXP_REG = FIFO_SIZE_32; //EP3:max packit size = 32
#else
rMAXP_REG = FIFO_SIZE_64; //EP3:max packit size = 64
#endif
rIN_CSR1_REG = EPI_FIFO_FLUSH|EPI_CDT|EPI_BULK;
rIN_CSR2_REG = EPI_MODE_OUT|EPI_IN_DMA_INT_MASK; //OUT mode, IN_DMA_INT=masked
rOUT_CSR1_REG = EPO_CDT;
//clear OUT_PKT_RDY, data_toggle_bit.
//The data toggle bit should be cleared when initialization.
rOUT_CSR2_REG = EPO_BULK|EPO_OUT_DMA_INT_MASK;
rINDEX_REG = 4;
rMAXP_REG = FIFO_SIZE_64; //EP4:max packit size = 64
rIN_CSR1_REG = EPI_FIFO_FLUSH|EPI_CDT|EPI_BULK;
rIN_CSR2_REG = EPI_MODE_OUT|EPI_IN_DMA_INT_MASK; //OUT mode, IN_DMA_INT=masked
rOUT_CSR1_REG= EPO_CDT;
//clear OUT_PKT_RDY, data_toggle_bit.
//The data toggle bit should be cleared when initialization.
rOUT_CSR2_REG= EPO_BULK|EPO_OUT_DMA_INT_MASK;
rEP_INT_REG = EP0_INT|EP1_INT|EP2_INT|EP3_INT|EP4_INT;
rUSB_INT_REG = RESET_INT|SUSPEND_INT|RESUME_INT;
//Clear all usbd pending bits
//EP0,1,3 & reset interrupt are enabled
rEP_INT_EN_REG = EP0_INT|EP1_INT|EP2_INT|EP3_INT|EP4_INT;
rUSB_INT_EN_REG = RESET_INT|SUSPEND_INT|RESUME_INT;
ep0State = EP0_STATE_INIT;
}
// INTERRUPT SOURCE
// 1.OUT_PKT_RDY BIT IS SET
// 2.IN_PKT_RDY BIT IS CLEARED
// 3.SENT_STALL BIT IS SET
// 4.SETUP_END BIT IS SET
// 5.DATA_END BIT IS CLEARED
void Ep0Handler(void)
{
rINDEX_REG=0;
//Ep0_Interrupt_Identify();
ep0_csr=rEP0_CSR;
if(ep0_csr & EP0_SETUP_END)
{ Uart_Puts("SETUP_END\n");
CLR_EP0_SETUP_END();
if(ep0_csr & EP0_OUT_PKT_READY)
{
FLUSH_EP0_FIFO();
CLR_EP0_OUT_PKT_RDY();
}
ep0State=EP0_STATE_INIT; //IMPORTANT !!
return;
}
if(ep0_csr & EP0_SENT_STALL) //protocol violation
{ Uart_Puts("SENT_STALL\n");
CLR_EP0_SENT_STALL();
if(ep0_csr & EP0_OUT_PKT_READY)
{
CLR_EP0_OUT_PKT_RDY();
}
ep0State=EP0_STATE_INIT;
return;
}
//USB 命令
else if((ep0_csr & EP0_OUT_PKT_READY) && (ep0State==EP0_STATE_INIT)) //HERE
{
RdPktEp0((U8 *)&descSetup,EP0_PKT_SIZE); //获得数据命令
if((descSetup.bmRequestType&RESERVED_TYPE)==STANDARD_TYPE){ //USB标准命令!!
//Uart_Puts("STANDARD\n");
Standard_bRequest_Handler(descSetup.bRequest);
}
else if(((descSetup.bmRequestType&RESERVED_TYPE)==CLASS_TYPE))//&&((descSetup.bmRequestType&INTERFACE_RECIPIENT)==INTERFACE_RECIPIENT))
{ //USB类标准命令!!
Uart_Puts("\nCLASS\n");
//Print_USB_SETUP_DATA(descSetup);
Class_bRequest_Handler(descSetup.bRequest);
}
else{ //其他命令 保留和厂商提供
//Uart_Puts("OTHER!\n");
//Print_USB_SETUP_DATA(descSetup);
CLR_EP0_OUTPKTRDY_DATAEND();
}
//Print_USB_SETUP_DATA(descSetup);
}
//else Uart_Puts("other ep0 int\n");
Ep0State_Handler(ep0State);
}
static void Standard_bRequest_Handler(U8 choice){
switch(choice)
{
case GET_DESCRIPTOR:
// Uart_Puts("GET_DESCRIPTOR !\n");
Descriptor_Type_Handler(descSetup.bValueH);
break;
case SET_ADDRESS:
// Uart_Puts("SET_ADDRESS !\n");
rFUNC_ADDR_REG=descSetup.bValueL | 0x80;
CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
ep0State=EP0_STATE_INIT;
break;
case SET_CONFIGURATION:
CLR_EP0_OUTPKTRDY_DATAEND(); //Because of no data control transfers.
// Uart_Puts("SET_CONFIGURATION !\n");
ep0State=EP0_STATE_INIT;
isUsbdSetConfiguration=1;
break;
default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -