|
|
View previous topic :: View next topic |
Author |
Message |
Markdem
Joined: 24 Jun 2005 Posts: 206
|
Joystick HID |
Posted: Sat Mar 07, 2009 4:36 am |
|
|
Hi All, I have been tring to get a joystick HID to work , but just can't seem to get it doing.
The hardware is OK, as I can use the HID demo's OK.
The following is my HID code,
Code: |
#IFNDEF __USB_DESCRIPTORS__
#DEFINE __USB_DESCRIPTORS__
#include <usb.h>
//////////////////////////////////////////////////////////////////
///
/// HID Report. Tells HID driver how to handle and deal with
/// received data. HID Reports can be extremely complex,
/// see HID specifcation for help on writing your own.
///
/// CCS example uses a vendor specified usage, that sends and
/// receives 2 absolute bytes ranging from 0 to 0xFF.
///
//////////////////////////////////////////////////////////////////
const char USB_CLASS_SPECIFIC_DESC[] = {
5, 1, // Usage Page = Vendor Defined
9, 4, // Usage = Joystick
0xa1, 1, // Collection = Application
0x05, 2, // Usage_Page = Sim Controls
9, 0xba, // Usage = Rudder
15, 81, // Logical_Min = -127
25, 0x7f, // Logical_Max = 127
95, 1, // Report_Count = 1
75, 8, // Report_Size = 8
81, 2, // Input = Data, Var, Abs
9, 0xbb, // Usage = Throttle
15, 81, // Logical_Min = -127
25, 0x7f, // Logical_Max = 127
95, 1, // Report_Count = 1
75, 8, // Report_Size = 8
81, 2, // Input = Data, Var, Abs
0x05, 1, // Usage_Page = Generic Desktop
9, 1, // Usage = Joystick
0xa1, 0, // Collection = Physical
9, 30, // Usage = X
9, 31, // Usage = Y
95, 2, // Report_Count = 2
81, 2, // Input = Data, Var, Abs
0xC0, // End_Collection
0x05, 9, // Usage_Page = Button
19, 1, // Usage_Min (Button 1)
29, 4, // Usage_Max (Button 4)
15, 0, // Logical_Min = 0
25, 1, // Logical_Max = 1
75, 1, // Report_Size = 1
95, 4, // Report_Count = 4
55, 0, // Report_Exponent
65, 0, // Unit = None
81, 2, // Input = Data, Var, Abs
0xC0
};
//if a class has an extra descriptor not part of the config descriptor,
// this lookup table defines where to look for it in the const
// USB_CLASS_SPECIFIC_DESC[] array.
//first element is the config number (if your device has more than one config)
//second element is which interface number
//set element to 0xFFFF if this config/interface combo doesn't exist
const int16 USB_CLASS_SPECIFIC_DESC_LOOKUP[USB_NUM_CONFIGURATIONS][1] =
{
//config 1
//interface 0
0
};
//if a class has an extra descriptor not part of the config descriptor,
// this lookup table defines the size of that descriptor.
//first element is the config number (if your device has more than one config)
//second element is which interface number
//set element to 0xFFFF if this config/interface combo doesn't exist
const int16 USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[USB_NUM_CONFIGURATIONS][1] =
{
//config 1
//interface 0
32
};
//////////////////////////////////////////////////////////////////
///
/// start config descriptor
/// right now we only support one configuration descriptor.
/// the config, interface, class, and endpoint goes into this array.
///
//////////////////////////////////////////////////////////////////
#DEFINE USB_TOTAL_CONFIG_LEN 34 //config+interface+class+endpoint
const char USB_CONFIG_DESC[] = {
//IN ORDER TO COMPLY WITH WINDOWS HOSTS, THE ORDER OF THIS ARRAY MUST BE:
// config(s)
// interface(s)
// class(es)
// endpoint(s)
//config_descriptor for config index 1
USB_DESC_CONFIG_LEN, //length of descriptor size ==1
USB_DESC_CONFIG_TYPE, //constant CONFIGURATION (CONFIGURATION 0x02) ==2
USB_TOTAL_CONFIG_LEN,0, //size of all data returned for this config ==3,4
1, //number of interfaces this device supports ==5
0x01, //identifier for this configuration. (IF we had more than one configurations) ==6
0x00, //index of string descriptor for this configuration ==7
0xC0, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 unused and bit7=1 ==8
0x32, //maximum bus power required (maximum milliamperes/2) (0x32 = 100mA)
//interface descriptor 1
USB_DESC_INTERFACE_LEN, //length of descriptor =10
USB_DESC_INTERFACE_TYPE, //constant INTERFACE (INTERFACE 0x04) =11
0x00, //number defining this interface (IF we had more than one interface) ==12
0x00, //alternate setting ==13
1, //number of endpoins, except 0 (pic167xx has 3, but we dont have to use all). ==14
0x03, //class code, 03 = HID ==15
0x00, //subclass code //boot ==16
0x00, //protocol code ==17
0x00, //index of string descriptor for interface ==18
//class descriptor 1 (HID)
USB_DESC_CLASS_LEN, //length of descriptor ==19
USB_DESC_CLASS_TYPE, //dscriptor type (0x21 == HID) ==20
0x00,0x01, //hid class release number (1.0) (try 1.10) ==21,22
0x00, //localized country code (0 = none) ==23
0x01, //number of hid class descrptors that follow (1) ==24
0x22, //report descriptor type (0x22 == HID) ==25
USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[0][0], 0x00, //length of report descriptor ==26,27
//endpoint descriptor
USB_DESC_ENDPOINT_LEN, //length of descriptor ==28
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==29
0x81, //endpoint number and direction (0x81 = EP1 IN) ==30
0x03, //transfer type supported (0x03 is interrupt) ==31
USB_EP1_TX_SIZE,0x00, //maximum packet size supported ==32,33
10, //polling interval, in ms. (cant be smaller than 10) ==34
};
//****** BEGIN CONFIG DESCRIPTOR LOOKUP TABLES ********
//since we can't make pointers to constants in certain pic16s, this is an offset table to find
// a specific descriptor in the above table.
//NOTE: DO TO A LIMITATION OF THE CCS CODE, ALL HID INTERFACES MUST START AT 0 AND BE SEQUENTIAL
// FOR EXAMPLE, IF YOU HAVE 2 HID INTERFACES THEY MUST BE INTERFACE 0 AND INTERFACE 1
#define USB_NUM_HID_INTERFACES 1
//the maximum number of interfaces seen on any config
//for example, if config 1 has 1 interface and config 2 has 2 interfaces you must define this as 2
#define USB_MAX_NUM_INTERFACES 1
//define how many interfaces there are per config. [0] is the first config, etc.
const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={1};
//define where to find class descriptors
//first dimension is the config number
//second dimension specifies which interface
//last dimension specifies which class in this interface to get, but most will only have 1 class per interface
//if a class descriptor is not valid, set the value to 0xFFFF
const int16 USB_CLASS_DESCRIPTORS[USB_NUM_CONFIGURATIONS][1][1]=
{
//config 1
//interface 0
//class 1
18
};
#if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN)
#error USB_TOTAL_CONFIG_LEN not defined correctly
#endif
//////////////////////////////////////////////////////////////////
///
/// start device descriptors
///
//////////////////////////////////////////////////////////////////
const char USB_DEVICE_DESC[USB_DESC_DEVICE_LEN] ={
//starts of with device configuration. only one possible
USB_DESC_DEVICE_LEN, //the length of this report ==1
0x01, //the constant DEVICE (DEVICE 0x01) ==2
0x10,0x01, //usb version in bcd (pic167xx is 1.1) ==3,4
0x00, //class code ==5
0x00, //subclass code ==6
0x00, //protocol code ==7
USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint 0. (SLOW SPEED SPECIFIES 8) ==8
0x61,0x03, //vendor id (0x04D8 is Microchip, or is it 0x0461 ??)
0x20,0x00, //product id ==11,12 //don't use ffff says usb-by-example guy. oops
0x00,0x01, //device release number ==13,14
0x01, //index of string description of manufacturer. therefore we point to string_1 array (see below) ==15
0x02, //index of string descriptor of the product ==16
0x00, //index of string descriptor of serial number ==17
USB_NUM_CONFIGURATIONS //number of possible configurations ==18
};
//////////////////////////////////////////////////////////////////
///
/// start string descriptors
/// String 0 is a special language string, and must be defined. People in U.S.A. can leave this alone.
///
/// You must define the length else get_next_string_character() will not see the string
/// Current code only supports 10 strings (0 thru 9)
///
//////////////////////////////////////////////////////////////////
//the offset of the starting location of each string. offset[0] is the start of string 0, offset[1] is the start of string 1, etc.
char USB_STRING_DESC_OFFSET[]={0,4,12};
char const USB_STRING_DESC[]={
//string 0
4, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
0x09,0x04, //Microsoft Defined for US-English
//string 1
8, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
'C',0,
'C',0,
'S',0,
//string 2
26, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
'C',0,
'O',0,
'N',0,
'T',0,
'R',0,
'O',0,
'L',0,
' ',0,
'Y',0,
'O',0,
'K',0,
'E',0
};
#ENDIF
|
Code seems to compile OK. When I connect the device to the PC, windows will display the "control yoke" when it first detects it, but them will put a yellow ! on the device.
If I replaced the USB_CLASS_SPECIFIC_DESC array with the original as in the demo, it will all start working again, which make me think there is something that I have not changed.
The following 3 vars I am not too sure about.
USB_CLASS_SPECIFIC_DESC_LOOKUP[USB_NUM_CONFIGURATIONS]
USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[USB_NUM_CONFIGURATIONS]
USB_CLASS_DESCRIPTORS[USB_NUM_CONFIGURATIONS]
I just can work out what they are, or how to set them correctly.
Is anyone able to point me in the right direction?
Thanks
Mark |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Mar 07, 2009 9:39 am |
|
|
How do you know that this is a valid joystick descriptor? Did you check with USBView and comapre with a known operational joystick device? |
|
|
Markdem
Joined: 24 Jun 2005 Posts: 206
|
|
Posted: Sat Mar 07, 2009 6:50 pm |
|
|
Hi FvM, I should of mentioned that I used the HID Descriptor Tool from usb.org.
Is there a tool that can show me why the device fail in windows?
Thanks
Mark |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Mar 08, 2009 1:45 am |
|
|
I didn't yet use the said tool. I meant to use USBView (a MS tool) to check the descriptors. Generally, when a device has a descriptor according to an USB class specification, it's not necessarily accepted by MS Windows, too. This is the case at least with CDC, where only specific combinations of device options are supported, and I guess, it's also true with HID. Thus I suggested to use an existing device as a template. |
|
|
Markdem
Joined: 24 Jun 2005 Posts: 206
|
|
Posted: Sun Mar 08, 2009 4:18 am |
|
|
Ok, after some more hunting on the web, I found(on a page with nothing to do with joysticks) the fact that I must return the data in full bytes.
In my original code, I was sending rudder (8 bits), throttle(8 bits), position(16 bits) and 4 buttons(4 bits), meaning I am sending 3.5 bytes. When I made the descriptor have 8 buttons, it works fine.
Hope that helps someone
Thanks
Mark |
|
|
adalucio
Joined: 16 Mar 2009 Posts: 29
|
|
Posted: Mon Feb 22, 2010 8:56 am |
|
|
Hi all
I tried the code, changing to 8 buttons:
Code: |
...
0x05, 9, // Usage_Page = Button
19, 1, // Usage_Min (Button 1)
29, 8, // Usage_Max (Button 8)
15, 0, // Logical_Min = 0
25, 1, // Logical_Max = 1
75, 1, // Report_Size = 1
95, 8, // Report_Count = 8
...
|
but it doesn't work (yellow ! on the device). What is wrong?
Thanks |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|