⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb_protocol.c

📁 一个linux下的usb接口源代码
💻 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 + -