📄 chap9.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 + -