CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC18F4550 as a 4 player arcade joystick (only 3 working)

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ghostjager



Joined: 19 Jun 2017
Posts: 2

View user's profile Send private message

PIC18F4550 as a 4 player arcade joystick (only 3 working)
PostPosted: Mon Jun 19, 2017 10:20 pm     Reply with quote

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: 19552

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 2:00 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 12:06 pm     Reply with quote

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: 19552

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 2:12 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jul 15, 2017 2:37 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 11, 2017 6:28 am     Reply with quote

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?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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