usb传输模式
控制传输
可靠的双向数据传输方式,usb设备必须支持的传输方式,用于通过端点0(usb的所有端点中,默认端点0用于初始化,不用于用户数据传输),进行usb设备的枚举、参数的配置等。
最大传输字节512字节,1个突发。
中断传输
可靠的单向传输,如果需要双向的传输,必须要使用IN端点和OUT端点,IN/OUT是相当于主机HOST的in和out而言。中断传输采用定时轮询的方式收发数据,主机轮询中断端点时,如果设备数据没有准备好,则返回NRDY,同理主机发送数据,设备没有准备好接收,也会返回NRDY。中断传输的延时是可以保证的,一般用于对延时比较苛刻,同时数据量小的传输,比如鼠标、键盘。
支持突发大小大于 1 的中断端点,允许的最大的数据包负载大小为 1024 字节;对于突发大小等于 1 的中断端点,最大的数据包负载大小可以在 1 到 1024 之间任意大小。中断端点的最大突发大小是 3。
批量传输
批量传输是一种可靠的单向传输,传输延迟没有保证,它会尽可能的利用可以利用的带宽完成传输,适合数据量比较大的传输。如果说总线上只有批量传输,那么延迟也是能保证的,实际中,U盘就是采用批量传输,因为它对时间延迟不是那么严格,只要可靠的完成大量数据的传输即可。
bulk端点最大数据传输1024字节,最大突发16。
同步传输
同步传输是四大传输中唯一不可靠的传输方式,但是可以保证带宽,并且没有延迟,而且因为是不可靠的传输,所以没有握手包,也不支持 PID 翻转,主机在安排这些传输事务时,同步传输拥有最高的优先级。在现实中,这种传输用于USB摄像头、USB音响等,因为它们对实时性要求比较高,但是可以容忍错误。
对于支持突发大小大于1的同步端点,唯一允许的最大数据负载大小是1024字节,对于突发大小等于1的同步端点,可以是0到1024之间的任何大小。同步端点允许的最大突发大小是16。
然而,在相同的服务间隔内,一个同步端点最多可以请求3个突发。
usb描述符
设备 (Device) :就是一个实实在在的USB设备,比如USB鼠标,U盘。
配置 (Configuration):一个USB设备可以有多种配置。比如4G上网卡就有2种配置:U盘、上网卡。第1次把4G上网卡插入电脑时,它是一个U盘,可以安装里面的程序。装好程序后,把它再次插入电脑,它就是一个上网卡。驱动程序可以选择让它工作于哪种配置,同一时间只能有一种配置有效。大多数的USB设备只有一种配置。
接口 (Interface) :每个配置下可以有多个接口,这个接口不是硬件上的接口,可以把这个接口理解为功能,一个接口就代表该设备当前支持的一种功能,多用于usb复合设备。
端点 (Endpoint) :每个接口可以有多个端点。USB主机和设备就是通过端点进行数据交互的。每个端点地址对应一个方向,有IN和OUT两种。
标准USB描述符
设备描述符
二进制设备对象存储BOS描述符
设备能力描述符
设备能力类型编码
usb30设备能力描述符
超速设备能力描述符
配置描述符
接口关联描述符
接口描述符
端点描述符
超速端点伙伴描述符
字符串描述符,指定设备支持的语言
编码字符串描述符
USB类设备描述符
类设备描述符应该遵循标准描述的格式要求,比如第一个字节必须是长度。
usb键盘
USB3014是超速接口,所以描述符支持superspeed、highspeed、fullspeed三种方式,采用usb中断端点进行数据传输。
描述符
/*
## Cypress FX3 Example Source File (cyhid_dscr.c)
## ===========================
##
## Copyright Cypress Semiconductor Corporation, 2010-2018,
## All Rights Reserved
## UNPUBLISHED, LICENSED SOFTWARE.
##
## CONFIDENTIAL AND PROPRIETARY INFORMATION
## WHICH IS THE PROPERTY OF CYPRESS.
##
## Use of this file is governed
## by the license agreement included in the file
##
## <install>/license/license.txt
##
## where <install> is the Cypress software
## installation root directory path.
##
## ===========================
*/
/* This file contains the USB descriptors for the HID application example */
#include "cyfx3_hid.h"
#ifdef REPORT_65
/******************************************************/
// bit7-4 3:2 1:0
// Tag Type Szie
//example 0x05,0x01, Tag=0,Type=1,size=1,data=0x01
/*****************************************************/
/* HID Report Descriptor 65 = 0x41 */
const uint8_t CyFxUSBReportDscr[] __attribute__ ((aligned (32))) =
{
0x05, 0x01, //Usage Page (Generic Desktop), global
0x09, 0x06, //Usage (Keyboard), local
0xA1, 0x01, //Collection (Application), mian
0x05, 0x07, //Usage Page (Keyboard), global
0x19, 0xE0, //Usage Minimum (224), local item
0x29, 0xE7, //Usage Maximum (231), local item
0x15, 0x00, //Logical Minimum (0), global item
0x25, 0x01, //Logical Maximum (1), global item
0x75, 0x01, //Report Size (1), global item
0x95, 0x08, //Report Count (8), gloabl
0x81, 0x02, //Input (Data, Variable, Absolute), input
0x75, 0x08, //Report Size (8), gloabl
0x95, 0x01, //Report Count (1), global
0x81, 0x01, //Input (Constant), input
0x19, 0x00, //Usage Minimum (0), local
0x29, 0x65, //Usage Maximum (101), local
0x15, 0x00, //Logical Minimum (0), global
0x25, 0x65, //Logical Maximum (101), global
0x75, 0x08, //Report Size (8),
0x95, 0x06, //Report Count (6),
0x81, 0x00, //Input (Data, Array),
0x05, 0x08, //Usage Page (LEDs),
0x19, 0x01, //Usage Minimum (1),
0x29, 0x05, //Usage Maximum (5),
0x15, 0x00, //Logical Minimum (0),
0x25, 0x01, //Logical Maximum (1),
0x75, 0x01, //Report Size (1),
0x95, 0x05, //Report Count (5),
0x91, 0x02, //Output (Data, Variable,Absolute),
0x75, 0x03, //Report Size (3),
0x95, 0x01, //Report Count (1),
0x91, 0x01, //Output (Constant),
0xC0 //End Collection
};
#else
/* HID Report Descriptor 63 = 0x3F */
const uint8_t CyFxUSBReportDscr[] __attribute__ ((aligned (32))) =
{
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x05, 0x07, // Usage Page (Key codes)
0x19, 0xE0, // Usage minimum (234)
0x29, 0xE7, // Usage maximum (231)
0x15, 0x00, // Logical minimum (0)
0x25, 0x01, // Logical maximum (1)
0x75, 0x01, // Report size (1)
0x95, 0x08, // Report count (8)
0x81, 0x02, // Input (data, variable, absolute)
0x95, 0x01, // Report count (1)
0x75, 0x08, // Report size (8)
0x81, 0x01, // Input (constant)
0x95, 0x05, // Report count (5)
0x75, 0x01, // Report size (1)
0x05, 0x08, // Usage Page (LED)
0x19, 0x01, // Usage minimum (1)
0x29, 0x05, // Usage maximum (5)
0x91, 0x02, // Output (data, variable, absolute)
0x95, 0x01, // Report count (1)
0x75, 0x03, // Report size (3)
0x91, 0x01, // Output (constant)
0x95, 0x03, // Report count (3)
0x75, 0x08, // Report size (8)
0x15, 0x00, // Logical minimum (0)
0x25, 0x65, // Logical maximum (101)
0x05, 0x07, // Usage page (key codes)
0x19, 0x00, // Usage minimum (0)
0x29, 0x65, // Usage maximum (101)
0x81, 0x00, // Input (data, array)
0xC0 // End Collection
};
#endif
/* Standard Device Descriptor for 2.0 */
const uint8_t CyFxUSB20DeviceDscr[] __attribute__ ((aligned (32))) =
{
0x12, /* Descriptor Size */
CY_U3P_USB_DEVICE_DESCR, /* Device Descriptor Type */
0x10,0x02, /* USB 2.1 */
0x00, /* Device Class */
0x00, /* Device Sub-class */
0x00, /* Device protocol */
0x40, /* Maxpacket size for EP0 : 64 bytes */
0xB4,0x04, /* Vendor ID */
0x25,0x60, /* Product ID */
0x00,0x00, /* Device release number */
0x01, /* Manufacture string index */
0x02, /* Product string index */
0x03, /* Serial number string index */
0x01 /* Number of configurations */
};
/* Standard Device Descriptor for USB 3.0 */
const uint8_t CyFxUSB30DeviceDscr[] __attribute__ ((aligned (32))) =
{
0x12, /* Descriptor Size */
CY_U3P_USB_DEVICE_DESCR, /* Device Descriptor Type */
0x10,0x03, /* USB 3.1 */
0x00, /* Device Class */
0x00, /* Device Sub-class */
0x00, /* Device protocol */
0x09, /* Maxpacket size for EP0 : 2^9 */
0xB4,0x04, /* Vendor ID */
0x25,0x60, /* Product ID */
0x00,0x00, /* Device release number */
0x01, /* Manufacture string index */
0x02, /* Product string index */
0x03, /* Serial number string index */
0x01 /* Number of configurations */
};
/* Standard Device Qualifier Descriptor */
const uint8_t CyFxUSBDeviceQualDscr[] __attribute__ ((aligned (32))) =
{
0x0A, /* Descriptor Size */
CY_U3P_USB_DEVQUAL_DESCR, /* Device Qualifier Descriptor Type */
0x01,0x02, /* USB 2.1 */
0x00, /* Device Class */
0x00, /* Device Sub-class */
0x00, /* Device protocol */
0x40, /* Maxpacket size for EP0 : 64 bytes */
0x01, /* Number of configurations */
0x00 /* Reserved */
};
/* Binary Device Object Store Descriptor */
const uint8_t CyFxUSBBOSDscr[] __attribute__ ((aligned (32))) =
{
0x05, /* Descriptor Size */
CY_FX_BOS_DSCR_TYPE, /* Device Descriptor Type */
0x16,0x00, /* Length of this descriptor and all sub descriptors */
0x02, /* Number of device capability descriptors */
/* USB 2.0 Extension */
0x07, /* Descriptor Size */
CY_FX_DEVICE_CAPB_DSCR_TYPE, /* Device Capability Type descriptor */
CY_U3P_USB2_EXTN_CAPB_TYPE, /* USB 2.0 Extension Capability Type */
0x1E,0x64,0x00,0x00, /* Supported device level features: LPM support, BESL supported,
Baseline BESL=400 us, Deep BESL=1000 us. */
/* SuperSpeed Device Capability */
0x0A, /* Descriptor Size */
CY_FX_DEVICE_CAPB_DSCR_TYPE, /* Device Capability Type descriptor */
CY_U3P_SS_USB_CAPB_TYPE, /* SuperSpeed Device Capability Type */
0x00, /* Supported device level features */
0x0E,0x00, /* Speeds Supported by the device : SS, HS and FS */
0x03, /* Functionality support */
0x00, /* U1 Device Exit Latency */
0x00,0x00 /* U2 Device Exit Latency */
};
/* Standard Full Speed Configuration Descriptor */
const uint8_t CyFxUSBFSConfigDscr[] __attribute__ ((aligned (32))) =
{
/* Configuration Descriptor Type */
0x09, /* Descriptor Size */
CY_U3P_USB_CONFIG_DESCR, /* Configuration Descriptor Type */
0x22,0x00, /* Length of this descriptor and all sub descriptors */
0x01, /* Number of interfaces */
0x01, /* Configuration number */
0x00, /* Configuration string index */
0xC0, /* Self powered device. */
0x32, /* Max power consumption of device (in 2mA unit) : 100mA */
/* Interface Descriptor */
0x09, /* Descriptor size */
CY_U3P_USB_INTRFC_DESCR, /* Interface Descriptor type */
CY_FX_USB_HID_INTF, /* Interface number */
0x00, /* Alternate setting number */
0x01, /* Number of end points */
0x03, /* Interface class : HID Class */ //add,must is 0x03
0x00, /* Interface sub class : None */
//0x02, /* Interface protocol code : Mouse */ //add,0x01 is keyboard,0x02 is mouse
0x01, /* Interface protocol code : Keyboard */
0x00, /* Interface descriptor string index */
/* HID Descriptor (Keyboard) */
0x09, /* Descriptor size */
CY_FX_USB_HID_DESC_TYPE, /* Descriptor Type */ //add, must is 0x21
0x10,0x11, /* HID Class Spec 11.1 */
0x00, /* Target Country */
0x01, /* Total HID Class Descriptors */
0x22, /* Report Descriptor Type */ //add,must is 0x22
#ifdef REPORT_65
0x41,0x00, /* Total Length of Report Descriptor */
#else
0x3F,0x00, /* Total Length of Report Descriptor */
#endif
/* Endpoint Descriptor (Mouse) */
0x07, /* Descriptor size */
CY_U3P_USB_ENDPNT_DESCR, /* Endpoint Descriptor Type */
CY_FX_HID_EP_INTR_IN, /* Endpoint address and description */
CY_U3P_USB_EP_INTR, /* Interrupt Endpoint Type */
0x40,0x00, /* Max packet size = 8 bytes */
0x0A /* Servicing interval for data transfers : 2 msec */
};
/* Standard High Speed Configuration Descriptor */
const uint8_t CyFxUSBHSConfigDscr[] __attribute__ ((aligned (32))) =
{
/* Configuration Descriptor Type */
0x09, /* Descriptor Size */
CY_U3P_USB_CONFIG_DESCR, /* Configuration Descriptor Type */
0x22,0x00, /* Length of this descriptor and all sub descriptors */
0x01, /* Number of interfaces */
0x01, /* Configuration number */
0x00, /* Configuration string index */
0xC0, /* Self powered device. */
0x32, /* Max power consumption of device (in 2mA unit) : 100mA */
/* Interface Descriptor */
0x09, /* Descriptor size */
CY_U3P_USB_INTRFC_DESCR, /* Interface Descriptor type */
CY_FX_USB_HID_INTF, /* Interface number */
0x00, /* Alternate setting number */
0x01, /* Number of end points */
0x03, /* Interface class : HID Class */
0x00, /* Interface sub class : None */
0x01, /* Interface protocol code : Keyboard */
0x00, /* Interface descriptor string index */
/* HID Descriptor (Mouse) */
0x09, /* Descriptor size */
CY_FX_USB_HID_DESC_TYPE, /* Descriptor Type */
0x10,0x11, /* HID Class Spec 11.1 */
0x00, /* Target Country */
0x01, /* Total HID Class Descriptors */
0x22, /* Report Descriptor Type */
#ifdef REPORT_65
0x41,0x00, /* Total Length of Report Descriptor */
#else
0x3F,0x00, /* Total Length of Report Descriptor */
#endif
/* Endpoint Descriptor (Mouse) */
0x07, /* Descriptor size */
CY_U3P_USB_ENDPNT_DESCR, /* Endpoint Descriptor Type */
CY_FX_HID_EP_INTR_IN, /* Endpoint address and description */
CY_U3P_USB_EP_INTR, /* Interrupt Endpoint Type */
0x00,0x02, /* Max packet size = 8 Bytes */
0x0A /* Polling interval : 2 ** (5-1) = 16 MicroFrames == 2 msec */
};
/* Standard Super Speed Configuration Descriptor */
const uint8_t CyFxUSBSSConfigDscr[] __attribute__ ((aligned (32))) =
{
/* Configuration Descriptor Type */
0x09, /* Descriptor Size */
CY_U3P_USB_CONFIG_DESCR, /* Configuration Descriptor Type */
0x28,0x00, /* Length of this descriptor and all sub descriptors */
0x01, /* Number of interfaces */
0x01, /* Configuration number */
0x00, /* Configuration string index */
0xC0, /* Self powered device. */
0x0C, /* Max power consumption of device (in 8mA unit) : 96 mA */
/* Interface Descriptor */
0x09, /* Descriptor size */
CY_U3P_USB_INTRFC_DESCR, /* Interface Descriptor type */
CY_FX_USB_HID_INTF, /* Interface number */
0x00, /* Alternate setting number */
0x01, /* Number of end points */
0x03, /* Interface class */
0x00, /* Interface sub class : None */
0x01, /* Interface protocol code, Keyboard */
0x00, /* Interface descriptor string index */
/* HID Descriptor (Mouse) */
0x09, /* Descriptor size */
CY_FX_USB_HID_DESC_TYPE, /* Descriptor Type */
0x10,0x11, /* HID Class Spec 11.1 */
0x00, /* Target Country */
0x01, /* Total HID Class Descriptors */
0x22, /* Report Descriptor Type */
#ifdef REPORT_65
0x41,0x00, /* Total Length of Report Descriptor */
#else
0x3F,0x00, /* Total Length of Report Descriptor */
#endif
/* Endpoint Descriptor (Mouse) */
0x07, /* Descriptor size */
CY_U3P_USB_ENDPNT_DESCR, /* Endpoint Descriptor Type */
CY_FX_HID_EP_INTR_IN, /* Endpoint address and description */
CY_U3P_USB_EP_INTR, /* Bulk End point Type */
0x00,0x04, /* Max packet size = 8 bytes */
0x0A, /* Servicing interval is 2 ** (5 - 1) = 16 Intervals = 2 ms. */
/* Super Speed Endpoint Companion Descriptor (Mouse) */
0x06, /* Descriptor size */
CY_FX_SS_EP_COMPN_DSCR_TYPE, /* SS Endpoint Companion Descriptor Type */
0x00, /* Max no. of packets in a Burst. */
0x00, /* No streaming for Interrupt Endpoints. */
0x00,0x04 /* Number of bytes per interval = 2. */
};
/* Standard Language ID String Descriptor */
const uint8_t CyFxUSBStringLangIDDscr[] __attribute__ ((aligned (32))) =
{
0x04, /* Descriptor Size */
CY_U3P_USB_STRING_DESCR, /* String Descriptor Type */
0x09,0x04 /* Language ID supported: US English */
};
/* Standard Manufacturer String Descriptor */
const uint8_t CyFxUSBManufactureDscr[] __attribute__ ((aligned (32))) =
{
0x10, /* Descriptor Size */
CY_U3P_USB_STRING_DESCR, /* String Descriptor Type */
'C',0x00,
'y',0x00,
'p',0x00,
'r',0x00,
'e',0x00,
's',0x00,
's',0x00
};
/* Standard Product String Descriptor */
const uint8_t CyFxUSBProductDscr[] __attribute__ ((aligned (32))) =
{
0x08, /* Descriptor Size */
CY_U3P_USB_STRING_DESCR, /* String Descriptor Type */
'F',0x00,
'X',0x00,
'3',0x00
};
/* Product Serial Number String Descriptor */
const uint8_t CyFxUSBSerialNumberDscr[] __attribute__ ((aligned (32))) =
{
0x1A, /* Descriptor Size */
CY_U3P_USB_STRING_DESCR, /* String Descriptor Type */
0x30, 0x00, 0x31, 0x00,
0x32, 0x00, 0x33, 0x00,
0x34, 0x00, 0x35, 0x00,
0x36, 0x00, 0x37, 0x00,
0x38, 0x00, 0x39, 0x00,
0x30, 0x00, 0x31, 0x00
};
/*[]*/
按键值上传
通过GPIO的中断方式模拟键盘的按下,当按下时,发送相应的键值给HOST,这里模拟上下左右四个按键,
//a keyValue : 4 0x04
//w keyValue : 26 0x1A
//s keyValue : 22 0x16
//d keyValue : 7 0x07
//uparrow keyValue : 82 0x52
//downarrow keyValue : 81 0x51
//leftarrow keyValue : 80 0x50
//rightarrow keyValue : 79 0x4F
/* Send Reports containing pre-defined patterns to Host through interrupt EP */
void
CyFxHidSendReport (
uint8_t *chr)
{
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
CyU3PDmaBuffer_t outBuf;
/* Retrieve Free Buffer */
status = CyU3PDmaChannelGetBuffer (&glChHandleIntrCPU2U, &outBuf, CYU3P_WAIT_FOREVER);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyFxHidSendReport CyU3PDmaChannelGetBuffer failed\r\n");
}
//CyU3PDebugPrint (4, "CyFxHidSendReport outBuf.size = %d\r\n", outBuf.size);
/* Copy Report Data into the output buffer */
outBuf.buffer[0] = 0x00;
outBuf.buffer[1] = 0x00;
if(strcmp((const char *)chr, (const char *)"up") == 0)
{
outBuf.buffer[2] = 0x52;
}
if(strcmp((const char *)chr, (const char *)"down") == 0)
{
outBuf.buffer[2] = 0x51;
}
if(strcmp((const char *)chr, (const char *)"left") == 0)
{
outBuf.buffer[2] = 0x50;
}
if(strcmp((const char *)chr, (const char *)"right") == 0)
{
//outBuf.buffer[2] = 0x4F;
outBuf.buffer[2] = 0x51;
}
outBuf.buffer[3] = 0x00;
outBuf.buffer[4] = 0x00;
outBuf.buffer[5] = 0x00;
outBuf.buffer[6] = 0x00;
outBuf.buffer[7] = 0x00;
outBuf.count = 8;
status = CyU3PDmaChannelCommitBuffer (&glChHandleIntrCPU2U, outBuf.count, 0);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyFxHidSendReport CyU3PDmaChannelCommitBuffer failed\r\n");
}
}
发送完一个键值之后发送一个空帧,否则会一直显示发送的按键值,
void
CyFxSendEmptyFrame (
void)
{
CyU3PReturnStatus_t status = CY_U3P_SUCCESS;
CyU3PDmaBuffer_t outBuf;
/* Retrieve Free Buffer */
status = CyU3PDmaChannelGetBuffer (&glChHandleIntrCPU2U, &outBuf, CYU3P_WAIT_FOREVER);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyFxSendEmptyFrame CyU3PDmaChannelGetBuffer 0 failed\r\n");
}
/* Copy Report Data into the output buffer */
outBuf.buffer[0] = 0x00;
outBuf.buffer[1] = 0x00;
outBuf.buffer[2] = 0x00;
outBuf.buffer[3] = 0x00;
outBuf.buffer[4] = 0x00;
outBuf.buffer[5] = 0x00;
outBuf.buffer[6] = 0x00;
outBuf.buffer[7] = 0x00;
outBuf.count = 8;
status = CyU3PDmaChannelCommitBuffer (&glChHandleIntrCPU2U, outBuf.count, 0);
if (status != CY_U3P_SUCCESS)
{
CyU3PDebugPrint (4, "CyFxSendEmptyFrame CyU3PDmaChannelCommitBuffer failed\r\n");
}
}