📄 usb_protocol.c
字号:
/*********************************************************************
** Module Name: USB_Protocol.c **
** Author: ZhangQuan **
** Version: 1.0 **
** CreateDate: 2001-05-18 **
** Description: Declarations of the Functions Handled USB **
** Standard Device Requests(Support USB Mass **
** Storage Class **
** Remark: **
** Revision History: **
**********************************************************************/
//#include <linux/interrupt.h>
#include "DataType.h"
#include "MC68VZ328.h"
#define USB_DEBUG 0
// Descriptor
UCHAR DeviceDescr[] =
{
0x12, // Size of this descriptor in bytes
0x01, // DEVICE descriptor type
0x10,0x01, // USBSpecification Release Number in Binary-Codec Decimal
0x00, // Class is specified in the interface descriptor
0x00, // Subclass is specified in the interface descriptor
0x00, // Protocol is specified in the interface descriptor
0x10, // Maximum packet size for endpoint zero.
0x9b,0x05, // Vendor ID (IOMEGA)
0x6d,0x00, // Product ID
0x00,0x01, // Device release number in binary-coded decimal
0x00,//01, // Index of string descriptor describing the manufacturer
0x00,//02, // Index of string descriptor describing the product
0x00,//03, // Index of string descriptor describing the device's serial number
0x01
};
UCHAR ConfigDescr[] =
{
0x09, // Size of this descriptor in bytes
0x02, // CONFIGURATION Descriptor Type
0x20,0x00, // Total length of data returned for this configuration
0x01, // Number of Interfaces supported by this configuration
0x01, // Value to use as an argument to the SetConfiguration() request to select this configuration
0x00,//04, // Index of string descriptor describing this configuration
0x80, // Configuration characteristics
0x64 // Maximum power consumption of the USB device from the bus in this specific configuration when the device is fully operational.
// Interface
,0x09, // Seze of this descriptor in bytes
0x04, // INTERFACE Descriptor Type
0x00, // Number of interface.
0x00, // Value used to select alternate setting for the interface identified in the prior field
0x02, // Number of endpoints used by this interface
0x08, // MASS STORAGE Class
//0x06, // Subclass code.(0x01: RBC, 0x06: SCSI)
0x05, // Subclass code.(0x02:ATAPI)
0x50, // BULK-ONLY TRANSPORT
0x00//05 // Index to string descriptor describing this interface
//EP2_TXDescr
,0x07, // Size of this descriptor in bytes
0x05, // ENDPOINT Descriptor Type
0x82, // The Address of this endpoint on the USB device.
0x02, // This is a Bulk endpoint
0x40,0x00, // Maximum packet size.
// 0x00,0x40,
0x00 // Does not apply to Bulk endpoints.
//EP2_RXDescr
,0x07, // Size of this descriptor in bytes
0x05, // ENDPOINT Descriptor Type
0x02, // The Address of this endpoint on the USB device.
0x02, // This is a Bulk endpoint
0x40,0x00, // Maximum packet size.
// 0x00,0x40,
0x00 // Does not apply to Bulk endpoints.
};
// String Descriptors
// 0x00
UCHAR StringDescrLanguage[] = // Language String
{
0x04, // Length
0x03, // Type (3=string)
0x09, // Language: English
0x04 // Sub-language: Default
};
// 0x01
UCHAR StringDescrManufacturer[] = // Manufacturer String
{
0x46,0x03,
'B',0,'e',0,'i',0,'j',0,'i',0,'n',0,'g',0,
' ',0,'E',0,'-',0,'w',0,'o',0,'r',0,'l',0,'d',0,
' ',0,'T',0,'e',0,'c',0,'h',0,'n',0,'o',0,'l',0,'o',0,'g',0,
' ',0,'C',0,'o',0,'.',0,',',0,'L',0,'t',0,'d',0,'.',0
};
// 0x02
UCHAR StringDescrProduct[] = // Product String
{
0x3e,0x03,
'E',0,'-',0,'w',0,'o',0,'r',0,'l',0,'d',0,
' ',0,'A',0,'u',0,'d',0,'i',0,'o',0,
' ',0,'P',0,'l',0,'a',0,'y',0,'e',0,'r',0,
' ',0,'V',0,'e',0,'r',0,'1',0,'.',0,'1',0,'1',0
};
// 0x03
UCHAR StringDescrSerial[] = // Serial String
{
0x10,0x03,
'1',0,'2',0,'3',0,'4',0,'3',0,'2',0,'1',0
};
// 0x04
UCHAR StringDescrInterface[] = // Interface String
{
0x2a,0x03,
'E',0,'-',0,'w',0,'o',0,'r',0,'l',0,'d',0,
' ',0,'A',0,'u',0,'d',0,'i',0,'o',0,
' ',0,'P',0,'l',0,'a',0,'y',0,'e',0,'r',0
};
// 0x05
UCHAR StringDescrEndpoint[] = // Endpoint String
{
0x32,0x03,
'E',0,'n',0,'d',0,'P',0,'o',0,'i',0,'n',0,'t',0,'2',0,
' ',0,'B',0,'u',0,'l',0,'k',0,'-',0,'O',0,'n',0,'l',0,'y',0,
' ',0,'P',0,'i',0,'p',0,'e',0
};
// USB standard device requests
void get_status(void);
void clear_feature(void);
void set_feature(void);
void set_address(void);
void get_descriptor(void);
void get_configuration(void);
void set_configuration(void);
void get_interface(void);
void set_interface(void);
void reserved(void);
// USB Protocol Layer
// USB standard device requests
void get_status(void)
{
UCHAR endp, txdat[2];
UCHAR bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
UCHAR c;
if(bRecipient == USB_RECIPIENT_DEVICE)
{
if(bEPPflags.bits.remote_wakeup == 1)
{
txdat[0] = 3;
}
else
{
txdat[0] = 1;
}
txdat[1]=0;
single_transmit(txdat, 2);
}
else if(bRecipient == USB_RECIPIENT_INTERFACE)
{
txdat[0]=0;
txdat[1]=0;
single_transmit(txdat, 2);
}
else if(bRecipient == USB_RECIPIENT_ENDPOINT)
{
endp = (UCHAR )(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
if(ControlData.DeviceRequest.wIndex & (unsigned char)USB_DATA_TRANSMIT_DEVICE_TO_HOST)
{
c = D12_SelectEndpoint(endp*2 + 1); /* Control-in */
}
else
{
c = D12_SelectEndpoint(endp*2); /* Control-out */
}
if(c & D12_STALL) txdat[0] = 1;
else txdat[0] = 0;
txdat[1] = 0;
single_transmit(txdat, 2);
}
else stall_ep0();
}
void clear_feature(void)
{
UCHAR endp;
UCHAR bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
// D12_ReadLastTransactionStatus(0);
// D12_ReadLastTransactionStatus(1);
if(bRecipient == USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)
{
bEPPflags.bits.remote_wakeup = 0;
single_transmit(0, 0);
}
else if(bRecipient == USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)
{
endp = (UCHAR )(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
// clear TX stall for IN on EPn.
if(ControlData.DeviceRequest.wIndex & (UCHAR )USB_DATA_TRANSMIT_DEVICE_TO_HOST)
{
outportb(D12_COMMAND, 0x40 + endp*2 + 1);
outportb(D12_DATA, 0);
}
else
{
D12_SetEndpointStatus(endp*2, 0);
}
single_transmit(0, 0);
}
else
{
stall_ep0();
}
// D12_ReadLastTransactionStatus(0);
// D12_ReadLastTransactionStatus(1);
bD12flags.bits.BOT_state == USBFSM4BOT_IDLE; //Added by Mike Chan
}
void set_feature(void)
{
UCHAR endp;
UCHAR bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
if(bRecipient == USB_RECIPIENT_DEVICE && ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP)
{
bEPPflags.bits.remote_wakeup = 1;
single_transmit(0, 0);
}
else if(bRecipient == USB_RECIPIENT_ENDPOINT && ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL)
{
endp = (UCHAR )(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
// clear TX stall for IN on EPn.
if(ControlData.DeviceRequest.wIndex & (UCHAR )USB_DATA_TRANSMIT_DEVICE_TO_HOST) D12_SetEndpointStatus(endp*2 + 1, 1);
// clear RX stall for OUT on EPn.
else D12_SetEndpointStatus(endp*2, 1);
single_transmit(0, 0);
}
else
{
stall_ep0();
}
}
void set_address(void)
{
UCHAR addr;
addr = (UCHAR )(ControlData.DeviceRequest.wValue);
addr &= DEVICE_ADDRESS_MASK;
D12_SetAddressEnable(addr, 1);
single_transmit(0, 0);
}
void get_descriptor(void)
{
UCHAR bDescriptor,bIndex;
bDescriptor = (UCHAR )(SWAP(ControlData.DeviceRequest.wValue));//Get the high byte
if(bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE)
{
code_transmit(DeviceDescr, 0x12);
}
else if(bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE)
{
if(ControlData.DeviceRequest.wLength<0x20)
{
code_transmit(ConfigDescr, 0x09);
}
else
{
code_transmit(ConfigDescr, 0x20); //Modified by CHenXiaotian
}
}
else if(bDescriptor == USB_STRING_DESCRIPTOR_TYPE)
{
bIndex = ControlData.DeviceRequest.wIndex;
switch(bIndex)
{
case 0x00: code_transmit(StringDescrLanguage, StringDescrLanguage[0]); break;
case 0x01: code_transmit(StringDescrManufacturer, StringDescrManufacturer[0]); break;
case 0x02: code_transmit(StringDescrProduct, StringDescrProduct[0]); break;
case 0x03: code_transmit(StringDescrSerial, StringDescrSerial[0]); break;
case 0x04: code_transmit(StringDescrInterface, StringDescrInterface[0]); break;
case 0x05: code_transmit(StringDescrEndpoint, StringDescrEndpoint[0]); break;
default: printk(" nonknow string request!\n"); stall_ep0(); break;
}
}
else
{
stall_ep0();
}
}
void get_configuration(void)
{
UCHAR c = bEPPflags.bits.configuration;
single_transmit(&c, 1);
}
void set_configuration(void)
{
if(ControlData.DeviceRequest.wValue == 0)
{ // put device in unconfigured state
single_transmit(0, 0);
bEPPflags.bits.configuration = 0;
init_unconfig();
}
else if(ControlData.DeviceRequest.wValue == 1)
{ // Configure device
single_transmit(0, 0);
init_unconfig();
init_config();
bEPPflags.bits.configuration = 1;
}
else stall_ep0();
}
void get_interface(void)
{
UCHAR txdat = 0; //Only/Current interface = 0
single_transmit(&txdat, 1);
}
void set_interface(void)
{
if(ControlData.DeviceRequest.wValue == 0 && ControlData.DeviceRequest.wIndex == 0)
single_transmit(0, 0);
else stall_ep0();
}
void reserved(void)
{
stall_ep0();
}
// USB protocol function pointer arrays
void (*ClassDeviceRequest[])(void) =
{
TPBulk_ClassRequestHandler
};
void (*StandardDeviceRequest[])(void) =
{
get_status,
clear_feature,
reserved,
set_feature,
reserved,
set_address,
get_descriptor,
reserved,
get_configuration,
set_configuration,
get_interface,
set_interface,
reserved,
reserved,
reserved,
reserved
};
void control_handler()
{
UCHAR type, req;
cli();
type = ControlData.DeviceRequest.bmRequestType & USB_REQUEST_TYPE_MASK;
req = ControlData.DeviceRequest.bRequest & USB_REQUEST_MASK;
if(type == USB_STANDARD_REQUEST)
(*StandardDeviceRequest[req])();
else
if(type == USB_CLASS_REQUEST)
(*ClassDeviceRequest[0])();
else
stall_ep0();
sti();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -