Haciendo joystick usb

Hola a todos

Estoy intentando realizar un joytick con dos controles análogos y 11 botones con un pic 18f2550.

Me e guiado por un proyecto similar que realiza un joystick con solo un control análogo pero hasta el momento e topado con los descriptores, ya que no tengo un conocimiento acabado en como definir un elemento a traves de estos

En lo posible apelo a su conocimiento en CCS C, para que me den un empujón de como es la estructura que debiera tener un Descriptor para un joystick con estas caracteristicas.

Aqui va el programa


Programa
Código:
// Programa de control para probar un GAMEPAD compuesto por 1 control analógico y 8 botones digitales.
// Utilizaremos un PIC18F2550 con conexión USB.
// Programador: Moyano Jonathan
// Librerías de descriptores: Programada por LIAMNESSON y modificada para uso personal.
// 30/03/09
//*****************************************************************************************************

#include <18F2550.h> // Definición de registros internos del PIC18F2550.
#device ADC=8 // CAD a 8 bits, justificación a a la derecha.
#fuses NOMCLR,XTPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
// NOMCLR: No vamos ha usar el PIN MCLR, el reset se hará por soft.
// XTPLL: Vamos a usar un cristal de 4.00Mhz.
// NOWDT: No vamos a usar el perro guardian.
// NOPROTECT: Memoria no protejida contra lecturas.
// NODEBUG: No utilizamos código para debugear.
// NOLVP: No utilizamos el modo de programación con bajo voltaje.
// USBDIV: signfica que el clock del usb se tomará del PLL/2 = 96Mhz/2 = 48Mhz.
// PLL1: significa que el PLL prescaler no dividirá la frecuencia del cristal. para XT = 4Mhz.
// CPUDIV1: El PLL postscaler decide la división en 2 de la frecuencia de salida del PLL de 96MHZ, si queremos 48MHZ, lo dejamos como está.
// VREGEN: habilita el regulador de 3.3 volts que usa el módulo USB.
// NOPBADEN: Deshabilitamos el módulo conversor ADC del puerto B.

#use delay(clock=48000000)


#DEFINE USB_HID_DEVICE TRUE // Vamos a utilizar el protocolo HID.

// Solamente definimos el buffer de salida ya que solamente enviaremos datos a la PC.

#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT 
#define USB_EP1_TX_SIZE 8 // Definición del tamaño del buffer de salida.

/*********************************************************************************************************/

// Definición de las librerías utilizadas.
#include <pic18_usb.h>    // Drivers's USB del PIC18F2550.
#include <GAMEPAD.h> // Descriptores USB para el GAMEPAD.
#include <usb.c> // Funciones del USB.

/*********************************************************************************************************/

// Comienza programa principal.

void main(void) {

int envia[3]; // Definimos los 3 bytes a enviar al EP1.
#define     eje_x       envia[0]     // Byte del eje X del mando analógico.                          
#define     eje_y       envia[1]     // Byte del eje Y del mando analógico.
#define     botones     envia[2]     // Byte de los 8 botones del PAD.


int botonera; // Variable que toma el valor de los botones presionados.
                                                               
output_b(0x00); // Limpiamos el puerto B.
// Configuraciones varias:
   disable_interrupts(global);
   disable_interrupts(int_timer1);
   disable_interrupts(int_rda);
   disable_interrupts(int_ext);
   disable_interrupts(int_ext1);
   disable_interrupts(int_ext2);
   setup_spi(FALSE);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   port_b_pullups(FALSE); 
   setup_adc_ports(AN0_TO_AN1 || VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_64);


// Iniciamos el USB.
      usb_init();                           // Inicializamos el USB.
      usb_wait_for_enumeration();           // Esperamos hasta que el dispositivo sea configurado por la PC.
      while(true) { 
      usb_task();                                                         // Habilita el periferico usb y las interrupciones.

        if (usb_enumerated()) // Si el puerto es enumerado y configurado por el host..
                  {

                          set_adc_channel(0); // Selecciono el canal de conversión para el eje X.
                          delay_us(10); // Espero 10uS, a que termine la conversión.
                          eje_x = read_adc(); // Guardamos el valor de la variable.

                          set_adc_channel(1); // Selecciono el canal de conversión para el eje Y.
                          delay_us(10); // Espero 10uS, a que termine la conversión.
                          eje_y = read_adc(); // Guardamos el valor de la variable.


                          botonera = input_b(); // Tomamos el valor de los botones.
                          botones = botonera;   // Guardamos el valor de la variable.
                          usb_put_packet(1,envia,5,USB_DTS_TOGGLE);   // Enviamos los datos por USB.
}

                      }
                            }

Libreria

Código:
// Descriptores para GAMEPAD USB.

#IFNDEF __USB_DESCRIPTORS__
#DEFINE __USB_DESCRIPTORS__

#include <usb.h>


   const char USB_CLASS_SPECIFIC_DESC[] = {

        0x05, 0x01, // usage page (generic desktop Choose the usage page "mouse" is on
      0x09, 0x05, // usage Device is a gamepad
      0xA1, 0x01, // collection (application) This collection encompasses the report format
      0x09, 0x01, // usage (pointer) Choose the key code usage page
      0xA1, 0x00, // collection (physical) Physical collection
      0x09, 0x30, // usage (X) X direction of pointer
      0x09, 0x31, // usage (Y) Y direction of pointer
      0x15, 0x00, // logical minimum (0)
      0x26, 0xFF, 0x00, // logical maximum (255)
      0x35, 0x00, // PHYSICAL minimum (0)
      0x46, 0xFF, 0x00, // PHYSICAL maximum (255)
      0x75, 0x08, // report size (8)
      0x95, 0x02, // report count (2) Two reports, eight bit each
      0x81, 0x02, // input (data, variable, absolute)
      0xC0,       // end collection

      0x05, 0x09, // usage page (buttons) Choose the “button” usage page
      0x19, 0x01, // usage minimum (1) There are three buttons
      0x29, 0x08, // usage maximum (8)
      0x15, 0x00, // logical minimum (0) Each button is represented by one bit
      0x25, 0x01, // logical maximum (1)
      0x95, 0x08, // report count (8) Three reports, one bit each
      0x75, 0x01, // report size (1)
      0x81, 0x02, // input (data, variable, absolute)
      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
      sizeof(USB_CLASS_SPECIFIC_DESC)
   };



//////////////////////////////////////////////////////////////////
///
///   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
         0x01, //subclass code //boot     ==16
         0x02, //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
         USB_ENDPOINT_TYPE_INTERRUPT, //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 for slow speed devices)     ==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][USB_NUM_HID_INTERFACES][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


//////////////////////////////////////////////////////////////////
///
///   Descriptores del dispositivo
///
//////////////////////////////////////////////////////////////////

   const char USB_DEVICE_DESC[USB_DESC_DEVICE_LEN] ={
         USB_DESC_DEVICE_LEN, // Longitud del reporte.
         0x01, // Constante del dispositivo = 1
         0x10,0x01, // Versión del USB 1.10.
         0x00, // Código de clase.
         0x00, // Código de subclase.
         0x00, // Código de protocolo.
         USB_MAX_EP0_PACKET_LENGTH, // Tamaño máximo del paquete de datos del endpoint 0 = 8 para HID.
         0x81,0x17, // Vendor  id =  decimal(6017), hexadecimal(1781) // Identificadores de easyHID.
         0xD0,0x07, // Product id =  decimal(2000), hexadecimal(7D0)
         0x00,0x01, // Número del dispositivo.
         0x01, 
         0x02, 
         0x00, 
         USB_NUM_CONFIGURATIONS  // Número de posibles configuraciones.
   };

   #if (sizeof(USB_DEVICE_DESC) != USB_DESC_DEVICE_LEN)
      #error USB_DESC_DEVICE_LEN not defined correctly
   #endif

//////////////////////////////////////////////////////////////////
/// Descriptores del fabricante
//////////////////////////////////////////////////////////////////


char USB_STRING_DESC_OFFSET[]={0,4,12};

char const USB_STRING_DESC[]={
   // Primer descriptor.
         4, // Longitud del descriptor.
         USB_DESC_STRING_TYPE, 
         0x09,0x04,   // Lenguaje id = Inglés (Definido por microsoft).
   // Segundo descriptor.
         8, // Longitud del descriptor.
         USB_DESC_STRING_TYPE, // Descriptor del compilador utilizado. (STRING) (Puede ser el nombre de la compañía)
         'C',0,
         'C',0,
         'S',0,
   // Tercer descriptor.
         32, // Longitud del descriptor.
         USB_DESC_STRING_TYPE, // Descriptor del fabricante: MoyaPIC_easyHID. (STRING)
         'N',0,
         'a',0,
         'X',0,
         'o',0,
         'P',0,
         'I',0,
         'C',0,
         '_',0,
         'G',0,
         'A',0,
         'M',0,
         'E',0,
         'P',0,
         'A',0,
         'D',0
};

#ENDIF
 
Hola, en el POST donde esta publicado el código en el cual te estas basando, hay un archivo PDF que contiene la información de los descriptores. Espero que te sirva.
Saludos
 
Atrás
Arriba