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

📄 kchap9.c

📁 在USB 固件程序设计中的主循环程序
💻 C
字号:
#include <stdio.h>
#include <string.h>
#include "khal.h"
#include "kd12ci.h"
#include "kmain.h"
#include "kUSB100.h"
#include "kchap9.h"

//以下定义的是一些外部函数//
extern void single_transmit(unsigned char * buf, unsigned char len);
extern void code_transmit(unsigned char code * pRomData, unsigned short len);
extern void stall_ep0(void);
extern void init_unconfig(void);
extern void init_config(void);
//以上定义的是一些外部函数//

#define NUM_ENDPOINTS	4
#define CONFIG_DESCRIPTOR_LENGTH    sizeof(USB_CONFIGURATION_DESCRIPTOR) \
									+ sizeof(USB_INTERFACE_DESCRIPTOR) \
									+ (NUM_ENDPOINTS * sizeof(USB_ENDPOINT_DESCRIPTOR))
extern CONTROL_XFER ControlData;
extern IO_REQUEST idata ioRequest;
extern EPPFLAGS bEPPflags;

//以下定义一些结构体类型的变量///
code USB_DEVICE_DESCRIPTOR DeviceDescr =   //设备描述符//
{
    sizeof(USB_DEVICE_DESCRIPTOR),      //描述符大小
    USB_DEVICE_DESCRIPTOR_TYPE,         //描述符类型
    SWAP(0x0200),                       //USB版本号码
    USB_CLASS_CODE_TEST_CLASS_DEVICE,   //类别码
    0,                                  //子类别
    0,                                  //协议码
    EP0_PACKET_SIZE,                    //端点0的最大信息包大小
    SWAP(0x0471),	                //VID厂商ID
    SWAP(0x0666),	                //PID产品ID
    SWAP(0x0100),                       //设备版本号码
    0, 			                //Manufactory制造者的字符串描述符索引值
    0,			                //Product    产品的字符串描述符索引值
    0,			                //Serial Number序号的字符串描述符索引值
    25			                //可能配置的数目
};

code USB_CONFIGURATION_DESCRIPTOR ConfigDescr =  //配置描述符
{
    sizeof(USB_CONFIGURATION_DESCRIPTOR),//描述符大小
    USB_CONFIGURATION_DESCRIPTOR_TYPE,//配置描述符类型
    SWAP(CONFIG_DESCRIPTOR_LENGTH),   //此配置传回的所有数据大小
    1,                                //此配置支持的接口数目
    1,                                //Set_Configuration与Get_Configuration要求的标识符
    0,                                //此配置的字符串描述符的索引值
    0x60,                             //自身电源/总线电源设置
    0xf0                              //需要总线电源
	};

code USB_INTERFACE_DESCRIPTOR InterfaceDescr =   //接口描述符
{
    sizeof(USB_INTERFACE_DESCRIPTOR), //描述符大小
    USB_INTERFACE_DESCRIPTOR_TYPE,    //描述符类型
    0,                                //识别此接口的数字
    0,                                //用来选择一个替代设置的数值
    NUM_ENDPOINTS,                    //出了端点0外,支持的端点数目
    USB_CLASS_CODE_TEST_CLASS_DEVICE, //类别码
    USB_SUBCLASS_CODE_TEST_CLASS_D12, //子类别码
    USB_PROTOCOL_CODE_TEST_CLASS_D12, //协议码
    0                                 //此接口的字符串描述符的索引值
};

code USB_ENDPOINT_DESCRIPTOR EP1_TXDescr =        //发送端点1描述符
{
    sizeof(USB_ENDPOINT_DESCRIPTOR), //描述符大小
    USB_ENDPOINT_DESCRIPTOR_TYPE,    //端点描述符类型
    0x81,                            //端点数目与方向
    USB_ENDPOINT_TYPE_INTERRUPT,     //支持的传输类型
    SWAP(EP1_PACKET_SIZE),           //支持的最大信息包大小
    10                               //最大迟延/轮询时距
};

code USB_ENDPOINT_DESCRIPTOR EP1_RXDescr =       //接受端点1描述符
{
	sizeof(USB_ENDPOINT_DESCRIPTOR),//描述符大小
	USB_ENDPOINT_DESCRIPTOR_TYPE,   //端点描述符类型
	0x1,                            //端点数目与方向
	USB_ENDPOINT_TYPE_INTERRUPT,    //支持的传输类型
	SWAP(EP1_PACKET_SIZE),          //支持的最大信息包大小
	10                              //最大迟延/轮询时距
};

code USB_ENDPOINT_DESCRIPTOR EP2_TXDescr =         //发送端点2描述符
{
	sizeof(USB_ENDPOINT_DESCRIPTOR),  //描述符大小
	USB_ENDPOINT_DESCRIPTOR_TYPE,     //端点描述符类型
	0x82,                             //端点数目与方向
	USB_ENDPOINT_TYPE_BULK,           //支持的传输类型
	SWAP(EP2_PACKET_SIZE),            //支持的最大信息包大小
	10                                //最大迟延/轮询时距
};

code USB_ENDPOINT_DESCRIPTOR EP2_RXDescr =         //接受端点2描述符
{
	sizeof(USB_ENDPOINT_DESCRIPTOR),   //描述符大小
	USB_ENDPOINT_DESCRIPTOR_TYPE,      //端点描述符类型
	0x2,                               //端点数目与方向
	USB_ENDPOINT_TYPE_BULK,            //支持的传输类型
	SWAP(EP2_PACKET_SIZE),             //支持的最大信息包大小
	10                                 //最大迟延/轮询时距
};

//以上定义了一些结构体类型的变量//
   //*************************************************************************
   // USB Protocol LayerUSB协议层
   //*************************************************************************
*/

void reserved(void)
{
	stall_ep0();
}

   
// USB standard device requestsUSB标准设备请求

void get_status(void)
{
	unsigned char endp, txdat[2];
	unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT;
	unsigned char 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 = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (unsigned char)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)
{
	unsigned char endp;
	unsigned char 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 = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (unsigned char)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)
{
	unsigned char endp;
	unsigned char 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 = (unsigned char)(ControlData.DeviceRequest.wIndex & MAX_ENDPOINTS);
		if (ControlData.DeviceRequest.wIndex & (unsigned char)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((unsigned char)(ControlData.DeviceRequest.wValue &
		DEVICE_ADDRESS_MASK), 1);
	single_transmit(0, 0);
}

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

	if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE) {
		code_transmit((unsigned char code *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR));
	} 
	else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) {
		code_transmit((unsigned char code *)&ConfigDescr, CONFIG_DESCRIPTOR_LENGTH);
	} 
	else
		stall_ep0();
}

void get_configuration(void)
{
	unsigned char 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)
{
	unsigned char 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 + -