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

📄 chap9.c

📁 USB固件开发源程序,以单片机为核心,转贴的
💻 C
字号:
#include "reg52.h"                
#include "usb.h"


//单片机调用以下各个函数解决USB中的各个对应的设备请求


/*---------------------------
extern void single_transmit(uchar * buf, uchar len);
extern void code_transmit(uchar code * pRomData, unsigned short len);
extern void stall_ep0(void);
extern void init_unconfig(void);
extern void init_config(void);
/*
extern uchar D12_SelectEndpoint(uchar bEndp);
extern void D12_SetMode(uchar bConfig, uchar bClkDiv);
extern void D12_SetEndpointStatus(uchar bEndp, uchar bStalled);
extern void D12_SetAddressEnable(uchar Address);
*/
#define NUM_ENDPOINTS	4

#define CONFIG_DESCRIPTOR_LENGTH    sizeof(USB_CONFIGURATION_DESCRIPTOR) \
									+ sizeof(USB_INTERFACE_DESCRIPTOR) \
									+ (NUM_ENDPOINTS * sizeof(USB_ENDPOINT_DESCRIPTOR))


//extern xdata CONTROL_XFER ControlData;
//extern xdata IO_REQUEST ioRequest;
//extern xdata EPPFLAGS bEPPflags;

/*************************************设备描述符***/
code USB_DEVICE_DESCRIPTOR DeviceDescr =
{
	sizeof(USB_DEVICE_DESCRIPTOR),		//0X12	
	0X01,					//设备描述符类型,
	SWAP(0x0100),				//USB规划发布号
	0xdc,					//类型代码,参考USB协议书36页
	0, 					//子类型代码,参考同上
	0,					//协议代码,0表示无特别协议
	EP0_PACKET_SIZE,			//端点0最大分组大小,8,16,32,64有效
	SWAP(0x0471),				//VID
	SWAP(0x0666),				//PID
	SWAP(0x0100),				//设备出厂编码
	0, 					//厂商描述符字符串索引
	0,					//产品描述符字符索引
	0,					//设备序列号字符串索引
	25					//可能的配置数
};

/************************************配置描述符***/
code USB_CONFIGURATION_DESCRIPTOR ConfigDescr =
{
	sizeof(USB_CONFIGURATION_DESCRIPTOR),	//0x09
	0x02,					//配置描述符类型
	SWAP(CONFIG_DESCRIPTOR_LENGTH),		//描述符总长度
	1,					//接口数,当然是1啦
	1,					//配置值??
    	0,					//用于描述配置字符串描述符的索引
	0x60,					//7:总线供电 6:自供电 5:远程唤醒 4~0:保留
	0x32					//电流,0x32*2MA,这个数值可以在'我的电脑' '属性'上看到
	//0x1
};

/*************************************接口描述符***/
code USB_INTERFACE_DESCRIPTOR InterfaceDescr =
{
	sizeof(USB_INTERFACE_DESCRIPTOR),	//0x09
	0x04,					//接口描述符类型		
	0,					//接口的编号(只有一个接口)
	0,					//用于上一个字段选择可供替换的设置
	0x04,					//使用的端点数目
	0xdc,					//测试设备类型
	0xa0,					//子类代码
	0xb0,					//协议代码
	0					//字符串描述符索引
};


/**************************************端点描述符***/
//端点1输入
code USB_ENDPOINT_DESCRIPTOR EP1_TXDescr =
{
	sizeof(USB_ENDPOINT_DESCRIPTOR),	//0x07
	0x05,					//端点描述符类型
	0x81,					//7:0-out,1-IN, 4-6保留,3-0:端点号
	0x03,					//00-控制,01-同步,02-批量,03-中断
	SWAP(EP1_PACKET_SIZE),			//端点最大信息包大小,对于同步端点,为预留时间
	10					//中断传输有效,为时间间隔ms
};

//端点1输出
code USB_ENDPOINT_DESCRIPTOR EP1_RXDescr =
{
	sizeof(USB_ENDPOINT_DESCRIPTOR),	//x07
	0x05,					//
	0x1,					//端点1OUT
	0x03,					//
	SWAP(EP1_PACKET_SIZE),
	10
};

//端点2输入
code USB_ENDPOINT_DESCRIPTOR EP2_TXDescr =
{
	sizeof(USB_ENDPOINT_DESCRIPTOR),	//0x07
	0x05,
	0x82,
	0x02,
	SWAP(EP2_PACKET_SIZE),
	10
};

//端点2输出
code USB_ENDPOINT_DESCRIPTOR EP2_RXDescr =
{
	sizeof(USB_ENDPOINT_DESCRIPTOR),
	0x05,
	0x2,
	0x02,
	SWAP(EP2_PACKET_SIZE),
	10
};


void reserved(void)
{
	stall_ep0();
}

/*
   //*************************************************************************
   // USB标准设备请求
   //*************************************************************************
*/

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 & (uchar)USB_ENDPOINT_DIRECTION_MASK)
			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;

	if (bRecipient == USB_RECIPIENT_DEVICE
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_REMOTE_WAKEUP) {
		DISABLE;
		bEPPflags.bits.remote_wakeup = 0;
		ENABLE;
		single_transmit(0, 0);
	}
	else if (bRecipient == USB_RECIPIENT_ENDPOINT
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) {
		endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
			// clear TX stall for IN on EPn. 
			D12_SetEndpointStatus(endp*2 + 1, 0);
		else
			// clear RX stall for OUT on EPn. 
			D12_SetEndpointStatus(endp*2, 0);
		single_transmit(0, 0);
	} else
		stall_ep0();
}

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) {
		DISABLE;
		bEPPflags.bits.remote_wakeup = 1;
		ENABLE;
		single_transmit(0, 0);
	}
	else if (bRecipient == USB_RECIPIENT_ENDPOINT
		&& ControlData.DeviceRequest.wValue == USB_FEATURE_ENDPOINT_STALL) {
		endp = (uchar)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (uchar)USB_ENDPOINT_DIRECTION_MASK)
			// clear TX stall for IN on EPn. 
			D12_SetEndpointStatus(endp*2 + 1, 1);
		else
			// clear RX stall for OUT on EPn. 
			D12_SetEndpointStatus(endp*2, 1);
		single_transmit(0, 0);
	} else
		stall_ep0();
}

void set_address(void)
{
	D12_SetAddressEnable((uchar)(ControlData.DeviceRequest.wValue & DEVICE_ADDRESS_MASK) );
	single_transmit(0, 0);
}

void get_descriptor(void)
{
	uchar bDescriptor = MSB(ControlData.DeviceRequest.wValue);

	if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE) {
		code_transmit((uchar code *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
	} 
	else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) {
		code_transmit((uchar code *)&ConfigDescr, CONFIG_DESCRIPTOR_LENGTH);
	} 
	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);
		DISABLE;
		bEPPflags.bits.configuration = 0;
		ENABLE;
		init_unconfig();
	} else if (ControlData.DeviceRequest.wValue == 1) {
		// Configure device 
		single_transmit(0, 0);

		init_unconfig();
		init_config();
		
		DISABLE;
		bEPPflags.bits.configuration = 1;
		ENABLE;
	} 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();
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -