Related
I know the default setting value for 'VIRTUAL_COM_PORT_DATA_SIZE 64' at usb_desc.h for STM32 Library.
however, I want to get the 255 bytes at one time due to the long packets of our project.
So I have changed the following modify code point, I couldn't get the right value with problem for 'USB defect problem'.
/****** usb_prop.c **********/
DEVICE_PROP Device_Property = {
Virtual_Com_Port_init,
Virtual_Com_Port_Reset,
Virtual_Com_Port_Status_In,
Virtual_Com_Port_Status_Out,
Virtual_Com_Port_Data_Setup,
Virtual_Com_Port_NoData_Setup,
Virtual_Com_Port_Get_Interface_Setting,
Virtual_Com_Port_GetDeviceDescriptor,
Virtual_Com_Port_GetConfigDescriptor,
Virtual_Com_Port_GetStringDescriptor,
0,
0xFF /*MAX PACKET SIZE*/ // default : 0x40
};
/****** usb_desc.c **********/
/* USB Standard Device Descriptor */
const uint8_t Virtual_Com_Port_DeviceDescriptor[] = {
0x12, /* bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x00,
0x02, /* bcdUSB = 2.00 */
0x02, /* bDeviceClass: CDC */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0xFF, /* bMaxPacketSize0 */ // default : 0x40
0x83,
0x04, /* idVendor = 0x0483 */
0x40,
0x57, /* idProduct = 0x7540 */
0x00,
0x02, /* bcdDevice = 2.00 */
1, /* Index of string descriptor describing manufacturer */
2, /* Index of string descriptor describing product */
3, /* Index of string descriptor describing the device's serial number */
0x01 /* bNumConfigurations */ };
/****** usb_desc.h **********/
#define VIRTUAL_COM_PORT_DATA_SIZE 255 // 0xFF, default : 64
please tell me how to modify in order to send as 255 bytes from USB packets.
You can't do it this way. The size of the packet is USB endpoint related and for the FS USB it is always 64 bytes. My advice is: do not modify any descriptors unless you really know what are you doing (which is not the case here).
How to receive larger chunks of data:
create a buffer
when data arrives copy it (append) to that buffer
check if you have received all data needed
if not go to point (2) else goto point(5)
Do something with the data (your large packet)
Reset the buffer and goto point 2
I'm implementing a custom HID device that has the following interface:
0x06, 0xA0, 0xFF, // Usage Page (Vendor Defined 0xFFA0)
0x09, 0x01, // Usage (0x01)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x15, 0x00, // Logical Minimum (0)
0x26, 0x01, 0x00, // Logical Maximum (1)
0x75, 0x08, // Report Size (8)
0x95, 0x01, // Report Count (1)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x01, // Report ID (1)
0x15, 0x00, // Logical Minimum (0)
0x26, 0x01, 0x00, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x06, // Report Size (6)
0x95, 0x01, // Report Count (1)
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x03, // Report ID (1)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0xFF, // Logical Maximum (65535)
0x75, 0x10, // Report Size (16)
0x95, 0x01, // Report Count (1)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
When I plug this device into the computer through a USB logic analyzer I see it enumerate, then something (I'm not sure what, any ideas?) uses the HID report descriptor to intelligently grab a bunch of reports:
(control)(endpoint 0) Get Input Report[1]
(control)(endpoint 0) Get Feature Report[1]
The "Get Input Report" entry confused me as I thought input reports were sent via an interrupt transfer. If I use usbhid's hid_write, I see the following entry, so I must be at least half right about input reports being sent via interrupt transfers...:
(interrupt)(endpoint 1) Input Report[1]"
I have been unable to find information that describes the difference between control "get input reports" and interrupt "input report" transfers which I am hoping one of you will know about.
Why do control "get input reports" exist?
Why not just have the spec mandate a "get feature report" entry exist for every "input report" id entry?
Why is whatever is grabbing input/feature reports for every defined input/feature report using a control transfer for the input reports vs. an interrupt transfer?
Have a look at USB HID v1.1. There is definition for Get_Report request on page 51:
This request is useful at initialization time for absolute items and for determining the state of feature items. This request is not intended to be used for polling the device state on a regular basis.
Here, this is exactly what the driver is doing: it is retrieving the various reports to initialize its current state. Note the host cannot request the device to send a report on its interrupt pipe. Hence the request on control pipe.
Chapter 4.4 explains various endpoints usage.
Also note feature reports and input reports do not address the same data, even if they have the same report ID (report IDs are per report type).
For the past two weeks I have been trying to configure my card (STM32F4) to dialogue with USB HID with a PC under Windows 7. I make success with this descriptor:
__ALIGN_BEGIN static uint8_t HID_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
0x06, 0xFF, 0x00, // USAGE_PAGE (Vendor Page: 0xFF00)
0x09, 0x01, // USAGE (Demo Kit)
0xa1, 0x01, // COLLECTION (Application)
//0x85, 0x01, // REPORT_ID (1)
0x09, 0x02, // USAGE (DATA)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff,0x00, // LOGICAL_MAXIMUM (255)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x04, // REPORT_COUNT (4)
0x81, 0x02, // INPUT (Data,Var,Abs,Vol)
0xc0 // END_COLLECTION
};
Like this, Windows recognizeS my card like a compliant HID component.
Now if I want to send 32 bit data like a uint32, Windows recognizes the card, but it sees an error to tell that it can't start it! My descriptor:
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
0x06, 0xFF, 0x00, // USAGE_PAGE (Vendor Page: 0xFF00)
0x09, 0x01, // USAGE (Demo Kit)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x02, // USAGE (DATA)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x27, 0xff,0xff,0xff,0xff, // LOGICAL_MAXIMUM (65535)
0x75, 0x20, // REPORT_SIZE (32)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs,Vol)
0xc0 // END_COLLECTION
};
I didn't understand why it din't work!
After that, I use USBlyser to scan my other USB device on my PC, and I take this descriptor about my spacespilot 3D mouse:
Endpoint Descriptor 83 3 In, Interrupt, 16 ms
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 83h 3 In
3 bmAttributes 1 03h Interrupt
1..0: Transfer Type ......11 Interrupt
7..2: Reserved 000000..
4 wMaxPacketSize 2 0007h 7 bytes
6 bInterval 1 08h 16 ms
Interface 1 HID Report Descriptor Multi-Axis Controller
Item Tag (Value) Raw Data
Usage Page (Generic Desktop) 05 01
Usage (Multi-Axis Controller) 09 08
Collection (Application) A1 01
Collection (Physical) A1 00
Report ID (1) 85 01
Logical Minimum (-500) 16 0C FE
Logical Maximum (500) 26 F4 01
Physical Minimum (-32768) 36 00 80
Physical Maximum (32767) 46 FF 7F
Usage (X) 09 30
Usage (Y) 09 31
Usage (Z) 09 32
Report Size (16) 75 10
Report Count (3) 95 03
Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
End Collection C0
If I try this, it works fine:
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x08, //Usage (Multi-Axis Controller)
0xa1, 0x01, // COLLECTION (Application)
0xa1, 0x00, // Collection (Physical)
0x85, 0x01, // Report ID (1)
0x16,0x0c,0xfe, // Logical minimum (-500)
0x26,0xf4,0x01, // Logical maximum (500)
0x35,0x00, // Physical Minimum (0)
0x46,0xff,0x00, // Physical Maximum (255)
0x09,0x30, // Usage(X)
0x09,0x31, // Usage(Y)
0x09,0x32, // Usage(Z)
0x09,0x33, // Usage(RX)
0x09,0x34, // Usage(RY)
0x09,0x35, // //Usage(RZ)
0x75, 0x08, // REPORT_SIZE (16)
0x95, 0x06, // REPORT_COUNT (6)
0x81, 0x02, // INPUT (Data,Var,Abs,Vol)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
But if I try the same descriptor that my 3D mouse:
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END =
{
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x08, // Usage (Multi-Axis Controller)
0xa1, 0x01, // COLLECTION (Application)
0xa1, 0x00, // Collection (Physical)
0x85, 0x01, // Report ID (1)
0x16,0x0c,0xfe, // Logical minimum (-500)
0x26,0xf4,0x01, // Logical maximum (500)
0x35,0x00,0x80, // Physical Minimum (-32768)
0x46,0xff,0x7f, // Physical Maximum (32767)
0x09,0x30, // Usage(X)
0x09,0x31, // Usage(Y)
0x09,0x32, // Usage(Z)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs,Vol)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
Windows gives me the same error, and it can't start the device!!!
What is wrong? Do I need a special driver for Windows to send 32 bit data (int32)? For information, I use the HID library for my application PC side.
How can I resolve this?
The LOGICAL_MAXIMUM four-byte descriptor tag (0x27) is only valid up to 0x7FFFFFFF as it is describing a maximum for a signed int data field. If you want to describe an unsigned int data field you would need to use the LOGICAL_MAXIMUM 8 byte descriptor tag like this:
0x28, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
Your second example would work, I think. Except for the typo for the Physical maximum descriptor tag. It should be 0x36, not 0x35.
When I tried your last descriptor (using my Arduino USBComposite library for STM32F1), Windows gave me an error about the descriptor having an unknown item. But when I changed the 0x35 in the Physical Minimum line to 0x36, Windows recognized the item.
I'm debugging some CCCrypto code in Cocoa and I noticed the IV I'm hard setting (yes, I know it should be randomized) is giving me weird results when I debug.
This is my IV:
unsigned char iv[17] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x00};
And this is the contents of my memory after I step past the above line when debugging:
(lldb) p iv
(unsigned char [17]) $1 = "\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10"
Where do \a\b\t\n\v\f\r come from? I fully expected to see
\x07\x08\x09\x0a\x0b\x0c\x0d
Those are the normal representations of those character values in ASCII and UTF-8. Remember, these may be eight-bit integers, but they're being interpreted as characters in a string. The character with the value 7 is '\a', also known as the "bell character" (it is supposed to make your computer beep if you print it). The character with the value 8 is backspace, or '\b'. 9 is tab, or '\t'. Then come line feed, vertical tab, form feed and carriage return.
To use the beagleboard xm as an HID peripheral I plan to do the following:
Discover how to build things with angstrom.
Get the kernel source 2.6.32.
Compile omap_udc and g_hid
Insert those modules into the kernel
Compile the example from gadget_hid.txt
Send keyboard commands with hid_gadget_test /dev/hidg0 keyboard
Is that a good way to do what I want?
http://www.edaboard.com/thread145675.html is a somewhat related issue from '09.
Looking for Example Embedded Linux HID Device Code is very similar.
I figured I would post this here because I looked and looked for an answer but to no avail so I had to get creative.
First
Go here and get the Kernel
http://eewiki.net/display/linuxonarm/BeagleBone
Second in
The KERNEL/arch/arm/mach-omap2/board-am335xevm.c
Add:
enter code here
#include <linux/usb/g_hid.h>
/* hid descriptor for a keyboard */
static struct hidg_func_descriptor my_hid_data = {
.subclass = 0, /* No subclass */
.protocol = 1, /* Keyboard */
.report_length = 8,
.report_desc_length = 63,
.report_desc = {
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
0x09, 0x06, /* USAGE (Keyboard) */
0xa1, 0x01, /* COLLECTION (Application) */
0x05, 0x07, /* USAGE_PAGE (Keyboard) */
0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */
0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x95, 0x08, /* REPORT_COUNT (8) */
0x81, 0x02, /* INPUT (Data,Var,Abs) */
0x95, 0x01, /* REPORT_COUNT (1) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x81, 0x03, /* INPUT (Cnst,Var,Abs) */
0x95, 0x05, /* REPORT_COUNT (5) */
0x75, 0x01, /* REPORT_SIZE (1) */
0x05, 0x08, /* USAGE_PAGE (LEDs) */
0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */
0x29, 0x05, /* USAGE_MAXIMUM (Kana) */
0x91, 0x02, /* OUTPUT (Data,Var,Abs) */
0x95, 0x01, /* REPORT_COUNT (1) */
0x75, 0x03, /* REPORT_SIZE (3) */
0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */
0x95, 0x06, /* REPORT_COUNT (6) */
0x75, 0x08, /* REPORT_SIZE (8) */
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
0x25, 0x65, /* LOGICAL_MAXIMUM (101) */
0x05, 0x07, /* USAGE_PAGE (Keyboard) */
0x19, 0x00, /* USAGE_MINIMUM (Reserved) */
0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */
0x81, 0x00, /* INPUT (Data,Ary,Abs) */
0xc0 /* END_COLLECTION */
}
};
static struct platform_device my_hid = {
.name = "hidg",
.id = 0,
.num_resources = 0,
.resource = 0,
.dev = {
.platform_data = &my_hid_data,
},
};
static void __init am33xx_hidg_init(void)
{
int ret;
ret = platform_device_register(&my_hid);
if (ret)
printk("HID Gadget registration failed\n");
}
In the:
static void __init am335x_evm_init(void)
{
am33xx_cpuidle_init();
am33xx_mux_init(board_mux);
omap_serial_init();
am335x_rtc_init();
**am33xx_hidg_init();**
clkout2_enable();
}
Build the kernel following the Guide from earlier
In the makemenu config section of the kernel build
go to the device drivers->usb support-> USB Gadget Support-> USB Gadget Drivers -> Compile HID Gadget as Module ( you may have to hunt for it but it's around this section in a couple more sub menus)
Take the sample code section from the kernel documentation
or this page http://www.mjmwired.net/kernel/Documentation/usb/gadget_hid.txt
Compile with GCC
insmod the g_hid.ko driver
and then run the compiled sample code