|
|
View previous topic :: View next topic |
Author |
Message |
ghostjager
Joined: 19 Jun 2017 Posts: 2
|
PIC18F4550 as a 4 player arcade joystick (only 3 working) |
Posted: Mon Jun 19, 2017 10:20 pm |
|
|
Hi,
I am developing an USB composite device with 4 HID Joystick interfaces, 16 buttons each, using a PIC 18F4550, for myself. So far I am able to make it work as a 3 player usb arcade, but I cannot make the 4th USB endpoint to work at all and I can't find the problem.
If I make it a 3 player arcade joystick, I am able to send to Windows the button keypresses of each joystick., but when I try sending anything to the 4th one, then all of the others stop receiving data. Actually, even if I try to send data only to the 4th endpoint, it won't work. I double checked that I wasn't missing any updating on offsets on descriptors as I was copy pasting from 2 to 3 and then to 4 players (adding interfaces to the composite device).
Before I quit trying, I decide asking for some help from you guys. Is this even achievable? Here is my code:
JOYSTICK.C:
Code: | #include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL2,CPUDIV1,VREGEN,NOPBADEN
#device ADC=8
#use delay(clock=48000000)
#define USB_HID_DEVICE TRUE
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 64 //size to allocate for the tx endpoint 1 buffer (MAX 64)
#define USB_EP1_RX_SIZE 64 //size to allocate for the rx endpoint 1 buffer (MAX 64)
#define USB_EP2_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP2(EndPoint2) for IN bulk/interrupt transfers
#define USB_EP2_RX_ENABLE USB_ENABLE_INTERRUPT //turn on EP2(EndPoint2) for OUT bulk/interrupt transfers
#define USB_EP2_TX_SIZE 64 //size to allocate for the tx endpoint 2 buffer (MAX 64)
#define USB_EP2_RX_SIZE 64 //size to allocate for the rx endpoint 2 buffer (MAX 64)
#define USB_EP3_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP3(EndPoint3) for IN bulk/interrupt transfers
#define USB_EP3_RX_ENABLE USB_ENABLE_INTERRUPT //turn on EP3(EndPoint3) for OUT bulk/interrupt transfers
#define USB_EP3_TX_SIZE 64 //size to allocate for the tx endpoint 3 buffer (MAX 64)
#define USB_EP3_RX_SIZE 64 //size to allocate for the rx endpoint 3 buffer (MAX 64)
#define USB_EP4_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP4(EndPoint4) for IN bulk/interrupt transfers
#define USB_EP4_RX_ENABLE USB_ENABLE_INTERRUPT //turn on EP4(EndPoint4) for OUT bulk/interrupt transfers
#define USB_EP4_TX_SIZE 64 //size to allocate for the tx endpoint 4 buffer (MAX 64)
#define USB_EP4_RX_SIZE 64 //size to allocate for the rx endpoint 4 buffer (MAX 64)
#define USB_USE_FULL_SPEED TRUE
#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <joystick.h>
#include <usb.c> //handles usb setup tokens and get descriptor reports
typedef struct
{
int1 B0:1;
int1 B1:1;
int1 B2:1;
int1 B3:1;
int1 B4:1;
int1 B5:1;
int1 B6:1;
int1 B7:1;
}un_bit;
typedef union
{
un_bit bit;
unsigned char cbyte;
}bit_byte;
bit_byte botones1; //buttons from 0 to 7
bit_byte botones2; //buttons from 8 to 15
char write[64];
unsigned char pov;
signed char x_axis,y_axis,throttle;
void main(void)
{
usb_init();
usb_task();
usb_wait_for_enumeration();
throttle=0;
while(1)
{
x_axis=0;
y_axis=0;
botones1.bit.B0=input(PIN_D0);
botones1.bit.B1=input(PIN_D1);
botones1.bit.B2=input(PIN_D2);
botones1.bit.B3=input(PIN_D3);
botones1.bit.B4=input(PIN_D4);
botones1.bit.B5=1;
botones1.bit.B6=1;
botones1.bit.B7=1;
botones2.bit.B0=1;
botones2.bit.B1=1;
botones2.bit.B2=1;
botones2.bit.B3=1;
botones2.bit.B4=1;
botones2.bit.B5=1;
botones2.bit.B6=1;
botones2.bit.B7=1;
write[0]=1;
write[1]=throttle;
write[2]=x_axis;
write[3]=y_axis;
write[4]=pov;
write[5]=botones1.cbyte;
write[6]=botones2.cbyte;
while(!usb_put_packet(1, write, 7, USB_DTS_TOGGLE));
write[0]=2;
write[1]=throttle;
write[2]=x_axis;
write[3]=y_axis;
write[4]=pov;
write[5]=botones1.cbyte;
write[6]=botones2.cbyte;
while(!usb_put_packet(2, write, 7, USB_DTS_TOGGLE));
write[0]=3;
write[1]=throttle;
write[2]=x_axis;
write[3]=y_axis;
write[4]=pov;
write[5]=botones1.cbyte;
write[6]=botones2.cbyte;
while(!usb_put_packet(3, write, 7, USB_DTS_TOGGLE));
//HERE IS WHERE I GET THE PROBLEM, IF I UNCOMMENT THIS FOLLOWING PART, EVERYTHING ABOVE STOPS WORKING (ALL OF THE DEVICES WILL BE ENUMERATED, BUT NONE OF THEM WILL RECEIVE ANY BUTTON PRESS)
//! write[0]=4;
//! write[1]=throttle;
//! write[2]=x_axis;
//! write[3]=y_axis;
//! write[4]=pov;
//! write[5]=botones1.cbyte;
//! write[6]=botones2.cbyte;
//! while(!usb_put_packet(4, write, 7, USB_DTS_TOGGLE));
}
} |
JOYSTICK.H:
Code: | #IFNDEF __USB_DESCRIPTORS__
#DEFINE __USB_DESCRIPTORS__
#include <usb.h>
//****** 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 4
//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 4
//define how many interfaces there are per config. [0] is the first config, etc.
const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={4};
//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][4][1]=
{
//config 1
//interface 0
//class 1
18, //indica el indice del array Config Descriptor[] donde comienza el class descriptor
//interface 1
//class 1
50,
//interface 2
//class 1
82,
//interface 3
//class 1
114
};
//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][4] =
{
//config 1
//interface 0
0,
//interface 1
79,
//interface 2
158,
//interface 3
237
};
//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][4] =
{
//config 1
//interface 0
79,
//interface 1
79,
//interface 2
79,
//interface 3
79
};
//////////////////////////////////////////////////////////////////
///
/// 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
0x00,0x02, //usb version in bcd (2.0) ==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
0x34,0x12, //vendor id (0x04D8 is Microchip, or is it 0x0461 ??) ==9,10
0x01,0xAB, //product id ==11,12 //don't use ffff says usb-by-example guy. oops
0x01,0x00, //device release number ==13,14
0x01, //index of 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 (1) ==18
};
//////////////////////////////////////////////////////////////////
///
/// 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 137 //config+interface+class+endpoint+endpoint (4 endpoints)
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
4, //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
0x80, //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) ==9
//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
0x02, //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
0x01,0x01, //hid class release number (1.0) (try 1.10) ==21,22
0x00, //localized country code (0 = none) ==23
0x00, //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 1 IN
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
#if USB_USE_FULL_SPEED
1, //polling interval, in ms. (cant be smaller than 10) ==34
#else
10, //polling interval, in ms. (cant be smaller than 10) ==34
#endif
//endpoint descriptor 1 OUT
USB_DESC_ENDPOINT_LEN, //length of descriptor ==35
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==36
0x01, //endpoint number and direction (0x01 = EP1 OUT) ==37
0x03, //transfer type supported (0x03 is interrupt) ==38
USB_EP1_RX_SIZE,0x00, //maximum packet size supported ==39,40
#if USB_USE_FULL_SPEED
1,
#else
10, //polling interval, in ms. (cant be smaller than 10) ==41
#endif
//interface descriptor 2
USB_DESC_INTERFACE_LEN, //length of descriptor =42
USB_DESC_INTERFACE_TYPE, //constant INTERFACE (INTERFACE 0x04) =43
0x01, //number defining this interface (IF we had more than one interface) ==43
0x00, //alternate setting ==45
1, //number of endpoins, except 0 (pic167xx has 3, but we dont have to use all). ==46
0x03, //class code, 03 = HID ==47
0x00, //subclass code //boot ==48
0x00, //protocol code ==49
0x03, //index of string descriptor for interface ==50
//class descriptor 2 (HID)
USB_DESC_CLASS_LEN, //length of descriptor ==51
USB_DESC_CLASS_TYPE, //dscriptor type (0x21 == HID) ==52
0x01,0x01, //hid class release number (1.0) (try 1.10) ==53,54
0x00, //localized country code (0 = none) ==55
0x00, //number of hid class descrptors that follow (0) ==56
0x22, //report descriptor type (0x22 == HID) ==57
USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[0][1], 0x00, //length of report descriptor ==58,59
//endpoint descriptor 2 IN
USB_DESC_ENDPOINT_LEN, //length of descriptor ==60
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==61
0x82, //endpoint number and direction (0x82 = EP2 IN) ==62
0x03, //transfer type supported (0x03 is interrupt) ==63
USB_EP2_TX_SIZE,0x00, //maximum packet size supported ==64,65
#if USB_USE_FULL_SPEED
1, //polling interval, in ms. (cant be smaller than 10)
#else
10, //polling interval, in ms. (cant be smaller than 10) ==66
#endif
//endpoint descriptor 2 OUT
USB_DESC_ENDPOINT_LEN, //length of descriptor ==67
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==68
0x02, //endpoint number and direction (0x02 = EP2 OUT) ==69
0x03, //transfer type supported (0x03 is interrupt) ==70
USB_EP2_RX_SIZE,0x00, //maximum packet size supported ==71,72
#if USB_USE_FULL_SPEED
1,
#else
10, //polling interval, in ms. (cant be smaller than 10) ==73
#endif
//interface descriptor 3
USB_DESC_INTERFACE_LEN, //length of descriptor =74
USB_DESC_INTERFACE_TYPE, //constant INTERFACE (INTERFACE 0x04) =75
0x02, //number defining this interface (IF we had more than one interface) ==76
0x00, //alternate setting ==77
1, //number of endpoins, except 0 (pic167xx has 3, but we dont have to use all). ==78
0x03, //class code, 03 = HID ==79
0x00, //subclass code //boot ==80
0x00, //protocol code ==81
0x04, //index of string descriptor for interface ==82
//class descriptor 3 (HID)
USB_DESC_CLASS_LEN, //length of descriptor ==83
USB_DESC_CLASS_TYPE, //dscriptor type (0x21 == HID) ==84
0x01,0x01, //hid class release number (1.0) (try 1.10) ==85,86
0x00, //localized country code (0 = none) ==87
0x00, //number of hid class descrptors that follow (0) ==88
0x22, //report descriptor type (0x22 == HID) ==89
USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[0][2], 0x00, //length of report descriptor ==90,91
//endpoint descriptor 3 IN
USB_DESC_ENDPOINT_LEN, //length of descriptor ==92
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==93
0x83, //endpoint number and direction (0x83 = EP3 IN) ==94
0x03, //transfer type supported (0x03 is interrupt) ==95
USB_EP3_TX_SIZE,0x00, //maximum packet size supported ==96,97
#if USB_USE_FULL_SPEED
1, //polling interval, in ms. (cant be smaller than 10)
#else
10, //polling interval, in ms. (cant be smaller than 10) ==98
#endif
//endpoint descriptor 3 OUT
USB_DESC_ENDPOINT_LEN, //length of descriptor ==99
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==100
0x03, //endpoint number and direction (0x03 = EP3 OUT) ==101
0x03, //transfer type supported (0x03 is interrupt) ==102
USB_EP3_RX_SIZE,0x00, //maximum packet size supported ==103,104
#if USB_USE_FULL_SPEED
1,
#else
10, //polling interval, in ms. (cant be smaller than 10) ==105
#endif
//interface descriptor 4
USB_DESC_INTERFACE_LEN, //length of descriptor =106
USB_DESC_INTERFACE_TYPE, //constant INTERFACE (INTERFACE 0x04) =107
0x03, //number defining this interface (IF we had more than one interface) ==108
0x00, //alternate setting ==109
1, //number of endpoins, except 0 (pic167xx has 3, but we dont have to use all). ==110
0x03, //class code, 03 = HID ==111
0x00, //subclass code //boot ==112
0x00, //protocol code ==113
0x05, //index of string descriptor for interface ==114
//class descriptor 4 (HID)
USB_DESC_CLASS_LEN, //length of descriptor ==115
USB_DESC_CLASS_TYPE, //dscriptor type (0x21 == HID) ==116
0x01,0x01, //hid class release number (1.0) (try 1.10) ==117,118
0x00, //localized country code (0 = none) ==119
0x00, //number of hid class descrptors that follow (0) ==120
0x22, //report descriptor type (0x22 == HID) ==121
USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[0][3], 0x00, //length of report descriptor ==122,123
//endpoint descriptor 4 IN
USB_DESC_ENDPOINT_LEN, //length of descriptor ==124
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==125
0x84, //endpoint number and direction (0x84 = EP4 IN) ==126
0x04, //transfer type supported (0x03 is interrupt) ==127
USB_EP4_TX_SIZE,0x00, //maximum packet size supported ==128,129
#if USB_USE_FULL_SPEED
1, //polling interval, in ms. (cant be smaller than 10)
#else
10, //polling interval, in ms. (cant be smaller than 10) ==130
#endif
//endpoint descriptor 4 OUT
USB_DESC_ENDPOINT_LEN, //length of descriptor ==131
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==132
0x04, //endpoint number and direction (0x04 = EP4 OUT) ==133
0x03, //transfer type supported (0x03 is interrupt) ==134
USB_EP4_RX_SIZE,0x00, //maximum packet size supported ==135,136
#if USB_USE_FULL_SPEED
1
#else
10 //polling interval, in ms. (cant be smaller than 10) ==137
#endif
};
//////////////////////////////////////////////////////////////////
///
/// 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[] = {
0x05, // 0
0x01, // USAGE_PAGE (Generic Desktop) ,1
0x15, //2
0x00, // LOGICAL_MINIMUM (0) ,3
0x09, //4
0x04, // USAGE (Joystick) ,5
0xa1, //6
0x01, // COLLECTION (Application) 7
0x85, // REPORT ID ,8
0x01, //ID 1 ,9
0x05, //10
0x02, // USAGE_PAGE (Simulation Controls),11
0x09, //12
0xbb, // USAGE (Throttle) ,13
0x15, //,14
0x81, // LOGICAL_MINIMUM (-127) ,15
0x25, //16
0x7f, // LOGICAL_MAXIMUM (127), 17
0x75, // 18
0x08, // REPORT_SIZE (8),19
0x95, //20
0x01, // REPORT_COUNT (1),21
0x81, //22
0x02, // INPUT (Data,Var,Abs),23
0x05, //24
0x01, // USAGE_PAGE (Generic Desktop) ,25
0x09, //26
0x01, // USAGE (Pointer) , 27
0xa1, //28
0x00, // COLLECTION (Physical), 29
0x09, //30
0x30, // USAGE (X),31
0x09, //32
0x31, // USAGE (Y),33
0x95, //34
0x02, // REPORT_COUNT (2),35
0x81, //36
0x02, // INPUT (Data,Var,Abs),37
0xc0, // END_COLLECTION,38
0x09, //39
0x39, // USAGE (Hat switch),40
0x15, //41
0x00, // LOGICAL_MINIMUM (0),42
0x25, //43
0x07, // LOGICAL_MAXIMUM (7),44
0x35, //45
0x00, // PHYSICAL_MINIMUM (0),46
0x46, //47
0x3B, //48
0x01, // PHYSICAL_MAXIMUM (315),49
0x65, //50
0x14, // UNIT (Eng Rot:Angular Pos),51
0x75, //52
0x08, // REPORT_SIZE (8),53
0x95, //54
0x01, // REPORT_COUNT (1),55
0x81, //56
0x02, // INPUT (Data,Var,Abs),57
0x05, //58
0x09, // USAGE_PAGE (Button),59
0x19, //60
0x01, // USAGE_MINIMUM (Button 1),61
0x29, //62
0x10, // USAGE_MAXIMUM (Button 16),63
0x15, //64
0x00, // LOGICAL_MINIMUM (0),65
0x25, //66
0x01, // LOGICAL_MAXIMUM (1),67
0x75, //68
0x01, // REPORT_SIZE (1),69
0x95, //70
0x10, // REPORT_COUNT (16),71
0x55, //72
0x00, // UNIT_EXPONENT (0),73
0x65, //74
0x00, // UNIT (None),75
0x81, //76
0x02, // INPUT (Data,Var,Abs),77
0xc0, // END_COLLECTION,78
0x05, //79 <------ BEGINNING OF THE SECOND INTERFACE
0x01, // USAGE_PAGE (Generic Desktop),80
0x15, //81
0x00, // LOGICAL_MINIMUM (0),82
0x09, //83
0x04, // USAGE (Joystick),84
0xa1, //85
0x01, // COLLECTION (Application),86
0x85, // REPORT ID,87
0x02, //ID 2,88
0x05, //89
0x02, // USAGE_PAGE (Simulation Controls),90
0x09, //91
0xbb, // USAGE (Throttle),92
0x15, //93
0x81, // LOGICAL_MINIMUM (-127),94
0x25, //95
0x7f, // LOGICAL_MAXIMUM (127),96
0x75, //97
0x08, // REPORT_SIZE (8),98
0x95, //99
0x01, // REPORT_COUNT (1),100
0x81, //101
0x02, // INPUT (Data,Var,Abs),102
0x05, //103
0x01, // USAGE_PAGE (Generic Desktop),104
0x09, //105
0x01, // USAGE (Pointer),106
0xa1, //107
0x00, // COLLECTION (Physical),108
0x09, //109
0x30, // USAGE (X),110
0x09, //111
0x31, // USAGE (Y),112
0x95, //113
0x02, // REPORT_COUNT (2),114
0x81, //115
0x02, // INPUT (Data,Var,Abs),116
0xc0, // END_COLLECTION,117
0x09, //118
0x39, // USAGE (Hat switch),119
0x15, //120
0x00, // LOGICAL_MINIMUM (0),121
0x25, //122
0x07, // LOGICAL_MAXIMUM (7),123
0x35, //124
0x00, // PHYSICAL_MINIMUM (0),125
0x46, //126
0x3B, //127
0x01, // PHYSICAL_MAXIMUM (315),128
0x65, //129
0x14, // UNIT (Eng Rot:Angular Pos),130
0x75, //131
0x08, // REPORT_SIZE (8),132
0x95, //133
0x01, // REPORT_COUNT (1),134
0x81, //135
0x02, // INPUT (Data,Var,Abs),136
0x05, //137
0x09, // USAGE_PAGE (Button),138
0x19, //139
0x01, // USAGE_MINIMUM (Button 1),140
0x29, //141
0x10, // USAGE_MAXIMUM (Button 16),142
0x15, //143
0x00, // LOGICAL_MINIMUM (0),144
0x25, //145
0x01, // LOGICAL_MAXIMUM (1),146
0x75, //147
0x01, // REPORT_SIZE (1),148
0x95, //149
0x10, // REPORT_COUNT (16),150
0x55, //151
0x00, // UNIT_EXPONENT (0),152
0x65, //153
0x00, // UNIT (None),154
0x81, //155
0x02, // INPUT (Data,Var,Abs),156
0xc0, // END_COLLECTION,157
0x05, //158 <------ BEGINNING OF THE THIRD INTERFACE
0x01, // USAGE_PAGE (Generic Desktop),159
0x15, //160
0x00, // LOGICAL_MINIMUM (0),161
0x09, //162
0x04, // USAGE (Joystick),163
0xa1, //164
0x01, // COLLECTION (Application),165
0x85, // REPORT ID,166
0x03, //ID 3,167
0x05, //168
0x02, // USAGE_PAGE (Simulation Controls),169
0x09, //170
0xbb, // USAGE (Throttle),171
0x15, //172
0x81, // LOGICAL_MINIMUM (-127),173
0x25, //174
0x7f, // LOGICAL_MAXIMUM (127),175
0x75, //176
0x08, // REPORT_SIZE (8),177
0x95, //178
0x01, // REPORT_COUNT (1),179
0x81, //180
0x02, // INPUT (Data,Var,Abs),181
0x05, //182
0x01, // USAGE_PAGE (Generic Desktop),183
0x09, //184
0x01, // USAGE (Pointer),185
0xa1, //186
0x00, // COLLECTION (Physical),187
0x09, //188
0x30, // USAGE (X),189
0x09, //190
0x31, // USAGE (Y),191
0x95, //192
0x02, // REPORT_COUNT (2),193
0x81, //194
0x02, // INPUT (Data,Var,Abs),195
0xc0, // END_COLLECTION,196
0x09, //197
0x39, // USAGE (Hat switch),198
0x15, //199
0x00, // LOGICAL_MINIMUM (0),200
0x25, //201
0x07, // LOGICAL_MAXIMUM (7),202
0x35, //203
0x00, // PHYSICAL_MINIMUM (0),204
0x46, //205
0x3B, //206
0x01, // PHYSICAL_MAXIMUM (315),207
0x65, //208
0x14, // UNIT (Eng Rot:Angular Pos),209
0x75, //210
0x08, // REPORT_SIZE (8),211
0x95, //212
0x01, // REPORT_COUNT (1),213
0x81, //214
0x02, // INPUT (Data,Var,Abs),215
0x05, //216
0x09, // USAGE_PAGE (Button),217
0x19, //218
0x01, // USAGE_MINIMUM (Button 1),219
0x29, //220
0x10, // USAGE_MAXIMUM (Button 16),221
0x15, //222
0x00, // LOGICAL_MINIMUM (0),223
0x25, //224
0x01, // LOGICAL_MAXIMUM (1),225
0x75, //226
0x01, // REPORT_SIZE (1),227
0x95, //228
0x10, // REPORT_COUNT (16),229
0x55, //230
0x00, // UNIT_EXPONENT (0),231
0x65, //232
0x00, // UNIT (None),233
0x81, //234
0x02, // INPUT (Data,Var,Abs),235
0xc0, // END_COLLECTION,236
0x05, //237 <------ BEGINNING OF THE FOURTH INTERFACE
0x01, // USAGE_PAGE (Generic Desktop),238
0x15, //239
0x00, // LOGICAL_MINIMUM (0),240
0x09, //241
0x04, // USAGE (Joystick),242
0xa1, //243
0x01, // COLLECTION (Application),244
0x85, // REPORT ID,245
0x04, //ID 4,246
0x05, //247
0x02, // USAGE_PAGE (Simulation Controls),248
0x09, //249
0xbb, // USAGE (Throttle),250
0x15, //251
0x81, // LOGICAL_MINIMUM (-127),252
0x25, //253
0x7f, // LOGICAL_MAXIMUM (127),254
0x75, //255
0x08, // REPORT_SIZE (8),256
0x95, //257
0x01, // REPORT_COUNT (1),258
0x81, //259
0x02, // INPUT (Data,Var,Abs),260
0x05, //261
0x01, // USAGE_PAGE (Generic Desktop),262
0x09, //263
0x01, // USAGE (Pointer),264
0xa1, //265
0x00, // COLLECTION (Physical),266
0x09, //267
0x30, // USAGE (X),268
0x09, //269
0x31, // USAGE (Y),270
0x95, //271
0x02, // REPORT_COUNT (2),272
0x81, //273
0x02, // INPUT (Data,Var,Abs),274
0xc0, // END_COLLECTION,275
0x09, //276
0x39, // USAGE (Hat switch),277
0x15, //278
0x00, // LOGICAL_MINIMUM (0),279
0x25, //280
0x07, // LOGICAL_MAXIMUM (7),281
0x35, //282
0x00, // PHYSICAL_MINIMUM (0),283
0x46, //284
0x3B, //285
0x01, // PHYSICAL_MAXIMUM (315),286
0x65, //287
0x14, // UNIT (Eng Rot:Angular Pos),288
0x75, //289
0x08, // REPORT_SIZE (8),290
0x95, //291
0x01, // REPORT_COUNT (1),292
0x81, //293
0x02, // INPUT (Data,Var,Abs),294
0x05, //295
0x09, // USAGE_PAGE (Button),296
0x19, //297
0x01, // USAGE_MINIMUM (Button 1),298
0x29, //299
0x10, // USAGE_MAXIMUM (Button 16),300
0x15, //301
0x00, // LOGICAL_MINIMUM (0),302
0x25, //303
0x01, // LOGICAL_MAXIMUM (1),304
0x75, //305
0x01, // REPORT_SIZE (1),306
0x95, //307
0x10, // REPORT_COUNT (16),308
0x55, //309
0x00, // UNIT_EXPONENT (0),310
0x65, //311
0x00, // UNIT (None),312
0x81, //313
0x02, // INPUT (Data,Var,Abs),314
0xc0 // END_COLLECTION,315
};
#if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN)
#error USB_TOTAL_CONFIG_LEN not defined correctly
#endif
//////////////////////////////////////////////////////////////////
///
/// 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,16,48,68,88};
char const USB_STRING_DESC[]={
//string 0
4, //length of string index ==1
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) ==2
0x09,0x04, //Microsoft Defined for US-English ==3,4
//string 1
12, //length of string index ==5
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) ==6
'J',0, //7,8
'A',0, //9,10
'G',0, //11,12
'E',0, //13,14
'R',0, //15,16
//string 2
32, //length of string index //17
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) //18
'A',0, //19,20
'R',0, //21,22
'C',0, //23,24
'A',0, //25,26
'D',0, //27,28
'E',0, //29,30
' ',0, //31,32
'J',0, //33,34
'O',0, //35,36
'Y',0, //37,38
'S',0, //39,40
'T',0, //41,42
'I',0, //43,44
'C',0, //45,46
'K',0, //47,48
//string 3
20, //length of string index //49
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) //50
'A',0, //51,52
'R',0, //53,54
'C',0, //55,56
'A',0, //57,58
'D',0, //59,60
'E',0, //61,62
' ',0, //63,64
'#',0, //65,66
'2',0, //67,68
//string 4
20, //length of string index //69
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) //70
'A',0, //71,72
'R',0, //73,74
'C',0, //75,76
'A',0, //77,78
'D',0, //79,80
'E',0, //81,82
' ',0, //83,84
'#',0, //85,86
'3',0, //87,88
//string 5
20, //length of string index //89
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) //90
'A',0, //91,92
'R',0, //93,94
'C',0, //95,96
'A',0, //97,98
'D',0, //99,100
'E',0, //101,102
' ',0, //103,104
'#',0, //105,106
'4',0 //107,108
};
#ENDIF
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Tue Jun 20, 2017 2:00 am |
|
|
A couple of comments, though I've not played with this....
1) Try reducing the buffer sizes. There may be a 256 byte limit somewhere, so 32 byte buffers may be needed once you have >3 devices.
2) Look at the HID2 example. They only generate one interface, but then two endpoints. Might be worth trying to base on this. |
|
|
ghostjager
Joined: 19 Jun 2017 Posts: 2
|
|
Posted: Tue Jun 20, 2017 12:06 pm |
|
|
Ttelmah wrote: | A couple of comments, though I've not played with this....
1) Try reducing the buffer sizes. There may be a 256 byte limit somewhere, so 32 byte buffers may be needed once you have >3 devices. |
This did not solved the problem, so I changed it back to 64 bytes.
Ttelmah wrote: | 2) Look at the HID2 example. They only generate one interface, but then two endpoints. Might be worth trying to base on this. |
This totally worked! Thanks man, you rock!
------------------------
May I abuse of your knowledge just a little bit more? There is only one small thing that was bothering me previously and it still is:
On the USB_STRING_DESC, I've set the interface names I'd like to have Windows recognizing for each interface. But no matter what I write there, all of the interfaces will share the same string, even though I wrote different indexes of string descriptors for each interface as you can see in the above joystick.h file (when I had 1 interface descriptor for each interface, but now I am sharing the third interface descriptor with report IDs 3 and 4, so I think if this has a solution, I'll still have at least these 2 "interfaces" with the same name).
I would love if I could have it listed there as:
ARCADE #1
ARCADE #2
ARCADE #3
ARCADE #4 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Tue Jun 20, 2017 2:12 pm |
|
|
I think you would have to use the serial number.
Looking at the Windows stack definitions, it seems it'll always assign the same name to all the devices, but will allow the serial number to be different.
So a limitation of the Windows driver, but one that the serial number should allow you deal with.... |
|
|
sancarajo
Joined: 15 Jul 2017 Posts: 1
|
|
Posted: Sat Jul 15, 2017 2:37 pm |
|
|
Hello Ghostjager, I'm working on an arcade joystick too. Please, could you post the working (modified) code for 4 joysticks ? Thanks in advance. |
|
|
vtrx
Joined: 11 Oct 2017 Posts: 142
|
|
Posted: Wed Oct 11, 2017 6:28 am |
|
|
Is not this part of the code wrong?
Quote: | //endpoint descriptor 4 IN
USB_DESC_ENDPOINT_LEN, //length of descriptor ==124
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==125
0x84, //endpoint number and direction (0x84 = EP4 IN) ==126
0x04, //transfer type supported (0x03 is interrupt) |
Would not it be 03? |
|
|
|
|
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
|