由于自我感觉对USB的理解还不是很清楚,外加机器上正好装了CodeWarrior for HC08,所以本着学习借鉴的态度,从早上开始看着Datasheet和参考书,又开始编程了。(为什么说“又”呢?因为好久没有干这个工作了,估计已经有大半年没在HC08上编程了,还是有点生疏了)
看书看到一些以前虽然看到过,但是并没有深刻理解的东西
标识域
数据包类型 | 标识域名称 | 标识符值PID[3:0] | 标识域意义 |
令牌包 | 输出(OUT) | 0001 | 启动一个方向为主机到设备的数据传输,并且包含了设备地址和端点信号 |
输入(IN) | 1001 | 启动一个方向为设备到主机的数据传输,并且包含了设备地址和端点信号 | |
帧起始(SOF) | 0101 | 表示一个帧的开始,并且包含了相应的帧号 | |
设置(SETUP) | 1101 | 启动一个方向为通过控制传输管道进行的数据传输,并且包含了设备地址和端点信号 | |
数据包 | 数据0(DATA0) | 0011 | 偶数据包 |
数据1(DATA1) | 1011 | 奇数据包 | |
握手包 | 确认(ACK) | 0010 | 接收到没有错误的数据包 |
无效(NAK) | 1010 | 接收端无法接收或发送端无法发送数据 | |
错误(STALL) | 1110 | 端点被禁止或不支持控制管道请求 | |
特殊包 | 前导(PRE) | 1100 | 用于启动下行端口的低速设备的数据传输 |
完整的PID
标识域名称 | 标识符值(二进制) | 标识符值(十六进制) |
OUT | 1000 0111 | 0x87 |
IN | 1001 0110 | 0x96 |
SOF | 1010 0101 | 0xa5 |
SETUP | 1011 0100 | 0xb4 |
DATA0 | 1101 0010 | 0xc3 |
DATA1 | 1101 0010 | 0xd2 |
ACK | 0100 1011 | 0x4b |
NAK | 0101 1010 | 0x5a |
STALL | 0111 1000 | 0x78 |
PRE | 0011 1100 | 0x3c |
令牌包
8bit | 8bit | 7bit | 4bit | 5bit |
SYNC | PID | ADDR | ENDP | CRC5 |
IN、OUT、SETUP包的数据格式
数据包
8bit | 8bit | 0~1023Byte | 5bit |
SYNC | PID | DATA | CRC5 |
数据包DATA0、DATA1的数据格式
握手包
8bit | 8bit |
SYNC | PID |
确认包ACK:用于表示数据包被成功接收,具体说
l 标识域PID被正确接收
l 并没有发生数据位错误
l 没有发生数据域的CRC校验错误
无效包NAK:属于暂态,设备结束“忙”后,就会处于空闲,主要应用于2种场合
l 接到主机发送的OUT命令后,设备无法接收数据
l 接到主机发送的IN命令后,设备没有数据发送给主机
错误包STALL:主要应用于3种场合
l 设备无法发送数据
l 设备无法接收数据
l 不支持某一种控制管道的命令
数据传输类型
数据传输类型 | 支持设备类型 | 包含的基本事务 | ||||
低速 | 全速 | 高速 | IN | OUT | SETUP | |
中断传输 | ○ | ○ | ○ | ○ | ○ | × |
批量传输 | × | ○ | ○ | ○ | ○ | × |
同步传输 | × | ○ | ○ | ○ | ○ | × |
控制传输 | ○ | ○ | ○ | ○ | ○ | ○ |
写不动了,明天再补吧
//-------------------------------------------------//
//-------------以下为3月26日补充-------------//
标准USB描述符
l 设备描述符(Device Descriptor)
l 配制描述符(Configuration Descriptor)
l 接口描述符(Interface Descriptor)
l 端点描述符(Endpoint Descriptor)
l 字符描述符(String Descriptor,可选)
USB描述符编号
编号 | 描述符类型 |
1 | 设备描述符 |
2 | 配置描述符 |
3 | 接口描述符 |
4 | 端点描述符 |
5 | 字符描述符 |
设备描述符的字段组成
偏移量 | 字段名称 | 长度(字节) | 字段值 | 意义 |
0 | bLength | 1 | 数字 | 设备描述符的字节数大小 |
1 | bDescriptorType | 1 | 常数 | 设备描述符类型编号 |
2 | bcdUSB | 2 | BCD码 | USB版本号 |
4 | bDeviceClass | 1 | 类 | USB分配的设备类代码 |
5 | bDeviceSubClass | 1 | 子类 | USB分配的子类代码 |
6 | bDeviceProtocol | 1 | 协议 | USB分配的设备协议代码 |
7 | bMaxPacketSize0 | 1 | 数字 | 端点0的最大包的大小 |
8 | idVendor | 2 | ID编号 | 厂商编号 |
10 | idProduct | 2 | ID编号 | 产品编号 |
12 | bcdDevice | 2 | BCD码 | 设备出厂编号 |
14 | iManufacturer | 1 | 索引 | 描述厂商字符串的索引 |
15 | iProduct | 1 | 索引 | 描述产品字符串的索引 |
16 | iSerialNumber | 1 | 索引 | 描述设备序列号字符串的索引 |
17 | bNumConfigurations | 1 | 索引 | 可能的配制数量 |
字段名称 | 说明 |
bLength | 0x12 |
bDescriptorType | 0x01 |
bcdUSB | USB1.1->0x0110 USB2.0->0x0200 |
bDeviceClass | USB标准设备类:0x00~0xfe 厂商定义设备类:0xff |
bDeviceSubClass | USB标准设备子类:0x00~0xfe 厂商定义设备子类:0xff |
bDeviceProtocol | USB标准设备协议:0x00~0xfe 厂商定义设备协议:0xff |
bMaxPacketSize0 | 低速:0x08 全速:0x08、0x10、0x20、0x40 高速:0x40 |
idVendor | 厂商从USB IF获得的ID |
idProduct | 厂商定义的产品ID |
bcdDevice | 厂商定义设备出厂编号(版本号) |
iManufacturer | 0表示没有使用该字段 |
iProduct | 0表示没有使用该字段 |
iSerialNumber | 每个设备都有一个特定的序列号,供主机识别不同的设备 |
bNumConfigurations | 该设备总共支持的配置描述符的数量 |
配置描述符的字段组成
偏移量 | 字段名称 | 长度(字节) | 字段值 | 意义 |
0 | bLength | 1 | 数字 | 配置描述符的字节数大小 |
1 | bDescriptorType | 1 | 常数 | 配置描述符类型编号 |
2 | wTotalLength | 2 | 数字 | 此配置所返回的所有数据大小 |
4 | bNumInterfaces | 1 | 数字 | 此配置所支持的接口数量 |
5 | bConfigurationValue | 1 | 数字 | Set_Configuration命令需要的参数值 |
6 | iConfiguration | 1 | 索引 | 描述该配制的字符串的索引值 |
7 | bmAttributes | 1 | 位图 | 供电模式的选择 |
8 | MaxPower | 1 | mA | 设备从总线提取的最大电流 |
字段名称 | 说明 |
bLength | 0x09 |
bDescriptorType | 0x02 |
wTotalLength | 返回的所有描述符(配置、接口和端点)的数据大小总和 |
bNumInterfaces |
|
bConfigurationValue | 可被Get_Configuration和Set_Configuration命令调用 |
iConfiguration | 0表示没有使用字符串描述该配置 |
bmAttributes | D7=1,固定(保留); D6=1自供电,D6=0总线供电; D5=1支持远程唤醒,D5=0不支持; D4D3D2D1D0 =00000,固定 |
MaxPower | 最大电流=2* MaxPower(mA),且必须<500mA(总线供电最大值),否则此配置会被主机禁止 |
接口描述符的字段组成
偏移量 | 字段名称 | 长度(字节) | 字段值 | 意义 |
0 | bLength | 1 | 数字 | 接口描述符的字节数大小 |
1 | bDescriptorType | 1 | 常数 | 接口描述符类型编号 |
2 | bInterfaceNumber | 1 | 数字 | 该接口的编号 |
3 | bAlternateSetting | 1 | 数字 | 备用的接口描述符编号 |
4 | bNumEndpoints | 1 | 数字 | 接口使用的端点数,不含端点0 |
5 | bInterfaceClass | 1 | 类 | 接口类型 |
6 | bInterfaceSubClass | 1 | 子类 | 接口子类型 |
7 | bInterfaceProtocol | 1 | 协议 | 接口遵循的协议 |
8 | iInterface | 1 | 索引 | 描述该接口的字符串的索引值 |
字段名称 | 说明 |
bLength | 0x09 |
bDescriptorType | 0x04 |
bInterfaceNumber | 默认值:0 |
bAlternateSetting | 一个接口可以有多个接口描述符 |
bNumEndpoints | 若为0 表示该接口只使用了端点0 |
bInterfaceClass | USB接口类:0x01~0xfe,0x00保留 厂商定义接口类:0xff |
bInterfaceSubClass | USB接口子类:0x01~0xfe,0x00保留 厂商定义接口子类:0xff |
bInterfaceProtocol | 与bInterfaceClass和bInterfaceSubClass相关 0x00:接口不遵循任何类协议 0x01~0xfe:USB不同标准设备类的协议 0xff:接口应用了厂商定义的类协议 |
iInterface | 0表示没有使用字符串描述 |
端点描述符的字段组成
偏移量 | 字段名称 | 长度(字节) | 字段值 | 意义 |
0 | bLength | 1 | 数字 | 端点描述符的字节数大小 |
1 | bDescriptorType | 1 | 常数 | 端点描述符类型编号 |
2 | bEndpointAddress | 1 | 端点 | 端点地址及输入输出属性 |
3 | bmAttributes | 1 | 位图 | 端点的传输类型属性 |
4 | wMaxPacketSize | 2 | 数字 | 端点收发的最大包的大小 |
6 | bInterval | 1 | 数字 | 主机查询端点的时间间隔 |
字段名称 | 说明 |
bLength | 0x07 |
bDescriptorType | 0x05 |
bEndpointAddress | D7=1输出OUT端点,D7=0输入IN端点; D6D5D4=000,固定(保留); D3D2D1D0:表示该端点端点号 |
bmAttributes | D1D0=00控制传输, D1D0=01同步传输, D1D0=10批量传输, D1D0=11中断传输, D7D6D5D4D3D2:USB1.1中保留,USB2.0有新含意 |
wMaxPacketSize | D10~D0为有效内容,且范围是0~1023; D 15~D11 USB1.1中保留,值为0 |
bInterval | 中断端点:1~255,时间单位m S 同步端点:1 批量端点和控制端点:忽略 |
字符串描述符的字段组成
偏移量 | 字段名称 | 长度(字节) | 字段值 | 意义 |
0 | bLength | 1 | 数字 | 字符串描述符的字节数大小 |
1 | bDescriptorType | 1 | 常数 | 字符串描述符类型编号 |
2 | bEndpointAddress | N | 数字 | Unicode编码的字符串 |
字段名称 | 说明 |
bLength | 2+N |
bDescriptorType | 0x03 |
bEndpointAddress |
|
标准USB请求命令的格式
偏移量 | 0 | 1 | 2 | 4 | 6 |
请求 | bmRequestType | bRequest | wValue | wIndex | wLength |
大小 | 1字节 | 1字节 | 2字节 | 2字节 | 2字节 |
bmRequestType
位 | 描述 | 说明 |
D7 | 选择数据传输方向 | D7=0,主机->从机;D7=1,从机->主机, |
D6 | 命令类型 | D6 D5=00,标准请求命令;D6 D5=01,类请求命令; D6 D5=10,用户定义请求命令;D6 D5=11,保留; |
D5 | ||
D4 | 命令接收者的类型 | D4D3D2D1D0=00000,接收者为设备 D4D3D2D1D0=00001,接收者为接口 D4D3D2D1D0=00010,接收者为端点 D4D3D2D1D0=00011,其他接收者 D4D3D2D1D0=其他,保留 |
D3 | ||
D2 | ||
D1 | ||
D0 |
bRequest
标准请求命令的编号
请求命令名称 | 编号(bRequest字段的值) |
GET_STATUS | 0x00 |
CLEAR_FEATURE | 0x01 |
SET_FEATURE | 0x03 |
SET_ADDRESS | 0x05 |
GET_DESCRIPTOR | 0x06 |
SET_DESCRIPTOR | 0x07 |
GET_CONFIGURATION | 0x08 |
SET_CONFIGURATION | 0x09 |
GET_INTERFACE | 0x0A |
SET_INTERFACE | 0x0B |
SYNC_FRAME | 0x0C |
GET_STATUS
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x80 0x81 0x82 | 0x00 | 0 | 0 bInterfaceNumber bEndpointAddress | 2 | 设备、接口或端口的状态 |
CLEAR_FEATURE
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x00 0x01 0x02 | 0x01 | 特性选择器 | 0 bInterfaceNumber bEndpointAddress | 0 | 无 |
特性选择器
选择器特性 | 接收者 | wValue的值 | 说明 |
DEVICE_REMOTE_WAKEUP | 设备 | 1 | 禁用 |
ENDPOINT_HALT | 端点 | 0 | 解禁 |
注:由于接收者不同,此字段的值要与bmRequestType字段的值匹配
SET_FEATURE
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x00 0x01 0x02 | 0x03 | 特性选择器 | 0 bInterfaceNumber bEndpointAddress | 0 | 无 |
注:特性选择器用法与CLEAR_FEATURE相同,只是在禁用和解禁方面是相反的
SET_ADDRESS
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x00 | 0x05 | 主机分配的设备地址 | 0 | 0 | 无 |
GET_DESCRIPTOR
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x80 | 0x06 | High byte: bDescriptorType Low byte: iDescriptor | 0(设备、配置)或语言ID(字符串) | 描述符长度 | 描述符 |
SET_DESCRIPTOR
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x00 | 0x07 | High byte: bDescriptorType Low byte: iDescriptor | 0(设备、配置)或语言ID(字符串) | 描述符长度 | 描述符 |
GET_CONFIGURATION
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x80 | 0x08 | 0 | 0 | 1 | bConfigurationValue |
SET_CONFIGURATION
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x00 | 0x09 | bConfigurationValue | 0 | 0 | 无 |
GET_INTERFACE
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x81 | 0x0A | 0 | bInterfaceNumber | 1 | bAlternateSetting |
SET_INTERFACE
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x01 | 0x0B | bAlternateSetting | bInterfaceNumber | 0 | 无 |
SYNC_FRAME
字段 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
内容 | 0x82 | 0x0C | 0 | bEndpointAddress | 2 | 帧号 |
//-------------------------------------------------//
//-------------以下为3月28日补充-------------//
既然文章摘要里有MC68HC908JB8,那当然要放点程序上来罗。不过,本来想把JB的程序写得完整点再把程序发上来,懒了,先发上来吧,有空再加
我的main.c文件
#include <hidef.h> /* for EnableInterrupts macro */
#include <MC68HC908JB8.h> /* include peripheral declarations */
#include "descriptor.h"
static byte qbf @0x80;
void usb_init()
{
UADDR_USBEN=1;//启用USB
//UIR0_TXD2IE=1;//端点2发送中断
UIR0_RXD2IE=1;//端点2接收中断
//UIR0_RXD1IE=1;//端点1接收中断
UIR0_RXD0IE=1;//端点0接收中断
//------------------------//
UCR0_RX0E=1;//端点0接收允许
//------------------------//
UCR1_STALL1=1;//端点1强制禁止
//------------------------//
UCR2_STALL=1;//端点2强制禁止//怀疑Motorola搞错了,算了懒得改了
//------------------------//
UCR3_OSTALL0=1;//端点0OUT事务强制返回STALL
UCR3_ISTALL0=1;//端点0IN事务强制返回STALL
}
void usb_EOP()
{
UIR2_EOPFR=1;//将EOPF清0
}
void setup_in_device()
{
switch(REQUEST_REQ)
{
case USB_REQUEST_GET_STATUS:
break;
case USB_REQUEST_GET_DESCRIPTOR:
break;
case USB_REQUEST_GET_CONFIGURATION:
break;
}
}
void setup_in_interface()
{
switch(REQUEST_REQ)
{
case USB_REQUEST_GET_STATUS:
break;
case USB_REQUEST_GET_INTERFACE:
break;
}
}
void setup_in_endpoint()
{
switch(REQUEST_REQ)
{
case USB_REQUEST_GET_STATUS:
break;
case USB_REQUEST_SYNC_FRAME:
break;
}
}
void setup_out_device()
{
byte temp;
switch(REQUEST_REQ)
{
case USB_REQUEST_CLEAR_FEATURE:
if(REQUEST_VAL==USB_DEVICE_REMOTE_WAKEUP)
{
//清除远程唤醒
}
break;
case USB_REQUEST_SET_FEATURE:
if(REQUEST_VAL==USB_DEVICE_REMOTE_WAKEUP)
{
//恢复远程唤醒
}
break;
case USB_REQUEST_SET_ADDRESS:
temp=REQUEST_VAL;
UADDR_UADD=temp;
break;
case USB_REQUEST_SET_DESCRIPTOR:
break;
case USB_REQUEST_SET_CONFIGURATION:
break;
}
}
void setup_out_interface()
{
switch(REQUEST_REQ)
{
case USB_REQUEST_CLEAR_FEATURE:
break;
case USB_REQUEST_SET_FEATURE:
break;
case USB_REQUEST_SET_INTERFACE:
break;
}
}
void setup_out_endpoint()
{
switch(REQUEST_REQ)
{
case USB_REQUEST_CLEAR_FEATURE:
break;
}
}
void usb_do_setup()
{
switch(REQUEST_REQTYPE)
{
case 0x00:setup_out_device(); break;//数据方向:主机到设备,标准请求命令,接收者:设备
case 0x01:setup_out_interface(); break;//数据方向:主机到设备,标准请求命令,接收者:接口
case 0x02:setup_out_endpoint(); break;//数据方向:主机到设备,标准请求命令,接收者:端口
case 0x80:setup_in_device(); break;//数据方向:设备到主机,标准请求命令,接收者:设备
case 0x81:setup_in_interface(); break;//数据方向:设备到主机,标准请求命令,接收者:接口
case 0x82:setup_in_endpoint(); break;//数据方向:设备到主机,标准请求命令,接收者:端口
default : break;
}
}
void usb_RX0()
{
if(USR0_SETUP==1)//端点0接收到了SETUP令牌
{
//处理SETUP令牌
REQUEST_REQTYPE=UE0D0;
REQUEST_REQ=UE0D1;
REQUEST_VAL=UE0D2;
REQUEST_VAL=REQUEST_VAL<<8;
REQUEST_VAL=REQUEST_VAL+UE0D3;
REQUEST_IND=UE0D4;
REQUEST_IND=REQUEST_IND<<8;
REQUEST_IND=REQUEST_IND+UE0D5;
REQUEST_LEN=UE0D6;
REQUEST_LEN=REQUEST_LEN<<8;
REQUEST_LEN=REQUEST_LEN+UE0D7;
usb_do_setup();
}
UIR2_RXD0FR=1;
}
void main(void)
{
CONFIG_COPD=1; //禁止看门狗
usb_init();
qbf=0x55;
EnableInterrupts;
for(;;);
}
void interrupt 2 usb_int()
{
qbf=0xaa;
if(UIR1_EOPF==1)//检测到EOP
{
usb_EOP();
}
if(UIR1_RXD0F==1)//检测到端点0接收到数据
{
usb_RX0();
}
}
我的descriptor.h文件
/*
*********************************************************************************************
* USB 描述符结构体及其成员取值宏定义
*********************************************************************************************
*/
typedef unsigned char INT8U; /* 无符号8位整型变量 */
typedef unsigned int INT16U; /* 无符号16位整型变量 */
typedef unsigned long INT32U; /* 无符号32位整型变量 */
/*********** USB 设备描述符结构体 ****************/
typedef struct _USB_DEVICE_DESCRIPTOR {
INT8U bLength;
INT8U bDescriptorType;
INT8U bcdUSB0;
INT8U bcdUSB1;
INT8U bDeviceClass;
INT8U bDeviceSubClass;
INT8U bDeviceProtocol;
INT8U bMaxPacketSize0;
INT8U idVendor0;
INT8U idVendor1;
INT8U idProduct0;
INT8U idProduct1;
INT8U bcdDevice0;
INT8U bcdDevice1;
INT8U iManufacturer;
INT8U iProduct;
INT8U iSerialNumber;
INT8U bNumConfigurations;
} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
/*********** USB 配置描述符结构体 ****************/
typedef struct _USB_CONFIGURATION_DESCRIPTOR {
INT8U bLength;
INT8U bDescriptorType;
INT8U wTotalLength0;
INT8U wTotalLength1;
INT8U bNumInterfaces;
INT8U bConfigurationValue;
INT8U iConfiguration;
INT8U bmAttributes;
INT8U MaxPower;
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
/*********** USB 接口描述符结构体 ****************/
typedef struct _USB_INTERFACE_DESCRIPTOR {
INT8U bLength;
INT8U bDescriptorType;
INT8U bInterfaceNumber;
INT8U bAlternateSetting;
INT8U bNumEndpoints;
INT8U bInterfaceClass;
INT8U bInterfaceSubClass;
INT8U bInterfaceProtocol;
INT8U iInterface;
} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
/*********** USB 端点描述符结构体 ****************/
typedef struct _USB_ENDPOINT_DESCRIPTOR {
INT8U bLength;
INT8U bDescriptorType;
INT8U bEndpointAddress;
INT8U bmAttributes;
INT8U wMaxPacketSize0;
INT8U wMaxPacketSize1;
INT8U bInterval;
} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
/*********** USB 字符串描述符结构体 ****************/
typedef struct _USB_STRING_DESCRIPTOR {
INT8U bLength;
INT8U bDescriptorType;
INT8U bString[3];
} USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;
//USB最大字符长度
#define MAXIMUM_USB_STRING_LENGTH 255
/*******************************************************
** USB 设备请求类型
********************************************************/
#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
#define USB_STRING_DESCRIPTOR_TYPE 0x03
#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
//#define USB_POWER_DESCRIPTOR_TYPE 0x06
/*******************************************************
** 下面为基于USB 1.0规范的正确值
********************************************************/
#define USB_REQUEST_GET_STATUS 0x00
#define USB_REQUEST_CLEAR_FEATURE 0x01
#define USB_REQUEST_SET_FEATURE 0x03
#define USB_REQUEST_SET_ADDRESS 0x05
#define USB_REQUEST_GET_DESCRIPTOR 0x06
#define USB_REQUEST_SET_DESCRIPTOR 0x07
#define USB_REQUEST_GET_CONFIGURATION 0x08
#define USB_REQUEST_SET_CONFIGURATION 0x09
#define USB_REQUEST_GET_INTERFACE 0x0A
#define USB_REQUEST_SET_INTERFACE 0x0B
#define USB_REQUEST_SYNC_FRAME 0x0C
/*******************************************************
** USB 设备类
********************************************************/
#define USB_DEVICE_CLASS_RESERVED 0x00
#define USB_DEVICE_CLASS_AUDIO 0x01
#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
//#define USB_DEVICE_CLASS_MONITOR 0x04
#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
#define USB_DEVICE_CLASS_POWER 0x06
#define USB_DEVICE_CLASS_PRINTER 0x07
#define USB_DEVICE_CLASS_STORAGE 0x08
#define USB_DEVICE_CLASS_HUB 0x09
#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
/*******************************************************
** USB 特性选择符
********************************************************/
#define USB_ENDPOINT_STALL 0x0000
#define USB_DEVICE_REMOTE_WAKEUP 0x0001
/*******************************************************
** USB 端点描述符结构体: 端点属性
********************************************************/
#define USB_ENDPOINT_TYPE_CONTROL 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define USB_ENDPOINT_TYPE_BULK 0x02
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
/**********************************************************************/
#define USB_ENDPOINT1_IN 0x81
#define USB_ENDPOINT2_IN 0x82
#define USB_ENDPOINT1_OUT 0x01
#define USB_ENDPOINT2_OUT 0x02
typedef struct _USB_REQUEST {
INT8U bmRequestType;
INT8U bRequest;
INT16U wValue;
INT16U wIndex;
INT16U wLength;
} USB_REQUEST;
static USB_REQUEST _REQUEST;
#define REQUEST _REQUEST
#define REQUEST_REQTYPE _REQUEST.bmRequestType
#define REQUEST_REQ _REQUEST.bRequest
#define REQUEST_VAL _REQUEST.wValue
#define REQUEST_IND _REQUEST.wIndex
#define REQUEST_LEN _REQUEST.wLength
/*********** USB 设备描述符的实例 ****************/
static USB_DEVICE_DESCRIPTOR Device_Descriptor=
{
0x12,//bLength;
0x01,//bDescriptorType;
0x10,//bcdUSB0;
0x01,//bcdUSB1;
0x00,//bDeviceClass;
0x00,//bDeviceSubClass;
0x00,//bDeviceProtocol;
0x08,//bMaxPacketSize0;
0x81,//idVendor0;
0x07,//idVendor1;
0x13,//idProduct0;
0x71,//idProduct1;
0x05,//bcdDevice0;
0x0a,//bcdDevice1;
0x02,//iManufacturer;
0x00,//iProduct;
0x04,//iSerialNumber;
0x01 //bNumConfigurations;
};
/*********** USB 配置描述符的实例 ****************/
static USB_CONFIGURATION_DESCRIPTOR Configuration_Descriptor=
{
0x09,//bLength;
0x02,//bDescriptorType;
0x27,//wTotalLength0;
0x00,//wTotalLength1;
0x01,//bNumInterfaces;
0x01,//bConfigurationValue;
0x00,//iConfiguration;
0x80,//bmAttributes//总线供电,不支持远程唤醒
0xfa //MaxPower;250*2=500mA
};
/*********** USB 接口描述符的实例 ****************/
static USB_INTERFACE_DESCRIPTOR Interface_Descriptor=
{
0x09,//bLength;
0x04,//bDescriptorType;
0x00,//bInterfaceNumber;
0x00,//bAlternateSetting;
0x02,//bNumEndpoints;
0xff,//bInterfaceClass;
0xff,//bInterfaceSubClass;
0x00,//bInterfaceProtocol;
0x00 //iInterface;
};
/*********** USB 端点描述符的实例 ****************/
static USB_ENDPOINT_DESCRIPTOR Endpoint_Descriptor[4]=
{
/* 端点1输入描述符 */
{
0x07,//bLength;
0x05,//bDescriptorType;
USB_ENDPOINT1_IN,//bEndpointAddress;
USB_ENDPOINT_TYPE_INTERRUPT,//bmAttributes;
0x08,//wMaxPacketSize0;
0x00,//wMaxPacketSize1;
0x10 //bInterval;
},
/* 端点1输出描述符 */
{
0x07,//bLength;
0x05,//bDescriptorType;
USB_ENDPOINT1_OUT,//bEndpointAddress;
USB_ENDPOINT_TYPE_INTERRUPT,//bmAttributes;
0x08,//wMaxPacketSize0;
0x00,//wMaxPacketSize1;
0x10 //bInterval;
},
/* 端点2输入描述符 */
{
0x07,//bLength;
0x05,//bDescriptorType;
USB_ENDPOINT1_IN,//bEndpointAddress;
USB_ENDPOINT_TYPE_BULK,//bmAttributes;
0x08,//wMaxPacketSize0;
0x00,//wMaxPacketSize1;
0x00 //bInterval;
},
/* 端点2输出描述符 */
{
0x07,//bLength;
0x05,//bDescriptorType;
USB_ENDPOINT1_IN,//bEndpointAddress;
USB_ENDPOINT_TYPE_BULK,//bmAttributes;
0x08,//wMaxPacketSize0;
0x00,//wMaxPacketSize1;
0x00 //bInterval;
}
};
/*********** USB 字符串描述符的实例 ****************/
static USB_STRING_DESCRIPTOR String_Descriptor=
{
0x05,//bLength;
0x03,//bDescriptorType;
"OK" //bString[3];
};
在CodeWarrior for HC08 上用Hiwave仿真过,能接收到setup事务,能设置设备地址,并返回ACK