t90
Joined: 07 Aug 2008 Posts: 11 Location: saigon,vietnam
|
USB gamepad in PIC 18f4550 can't start |
Posted: Thu Nov 27, 2008 9:38 am |
|
|
Hello! I am try to make the gamepad USB via PIC 18f4550. To implement the project I read all example for hid device in Devices folder, and I found in the web www.usb.org the example about gamepad descriptor. So that I try to implement base on the descriptor. When I plug in my gamepad in USB port on PC, the PC detect my device but throw the error said that "the device could not start (error 10)". Please help me! Sorry about my English.
Here is my code:
-this is the header file:
Code: |
#IFNDEF __USB_DESCRIPTORS__
#DEFINE __USB_DESCRIPTORS__
#include <usb.h>
const char USB_CLASS_SPECIFIC_DESC[] = {
0x05, 0x01,//USAGE_PAGE (Generic Desktop) ==1,2
0x09, 0x05,//USAGE (Gamepad)==3,4
0xA1, 0x01,//COLLECTION (Application)==5,6
0x09, 0x01,//USAGE (Pointer)==7,8
0xA1, 0x00,//COLLECTION (Physical)==9,10
0x09, 0x30,//USAGE (X)==11,12
0x09, 0x31,//USAGE (Y)==13,14
0x15, 0x00,//LOGICAL_MINIMUM (0)==15,16
0x25, 0x01,//LOGICAL_MAXIMUM (1)==17,18
0x75, 0x01,//REPORT_SIZE (1)==19,20
0x95, 0x02,//REPORT_COUNT (2)==21,22
0x81, 0x02,//INPUT (Data,Var,Abs)==23,24
0xC0, //END_COLLECTION=25
0x05, 0x09,//USAGE_PAGE (Button)==26,27
0x19, 0x01,//USAGE_MINIMUM (Button 1)==28,29
0x29, 0x06,//USAGE_MAXIMUM (Button 6)==30,31
0x15, 0x00,//LOGICAL_MINIMUM (0)==32,33
0x25, 0x01,//LOGICAL_MAXIMUM (1)==34,35
0x75, 0x01,//REPORT_SIZE (1)==36,37
0x95, 0x06,//REPORT_COUNT (6)==38,39
0x81, 0x02,//INPUT (Data,Var,Abs)==40,41
0x95, 0x02,//REPORT_COUNT (2)==42,43
0x81, 0x03,//INPUT (Constant,Var,Abs)==44,45
0xC5, //END_COLLECTION==46
};
//extra report
const int16 USB_CLASS_SPECIFIC_DESC_LOOKUP[USB_NUM_CONFIGURATIONS][1] =
{
//config 1
//interface 0
0
};
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 41//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
0xA0, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 unused and bit7=1 ==8
0x50, //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
0x01,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
0x40,0x00, //maximum packet size supported ==32,33
1 //polling interval, in ms. (cant be smaller than 10 for slow speed devices) ==34
//endpoint descriptor
USB_DESC_ENDPOINT_LEN, //length of descriptor ==35
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==36
0x01, //endpoint number and direction (0x81 = EP1 IN) ==37
0x40, //transfer type supported (0x03 is interrupt) ==38
USB_EP1_RX_SIZE,0x00, //maximum packet size supported ==39,40
1 //polling interval, in ms. (cant be smaller than 10 for slow speed devices) ==41
};
//****** 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
//////////////////////////////////////////////////////////////////
///
/// start device descriptors
///
//////////////////////////////////////////////////////////////////
const char USB_DEVICE_DESC[] = {
//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,0x04, //vendor id (0x04D8 is Microchip, or is it 0x0461 ??)
0x22,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
};
#if (sizeof(USB_DEVICE_DESC) != USB_DESC_DEVICE_LEN)
#error USB_DESC_DEVICE_LEN not defined correctly
#endif
//////////////////////////////////////////////////////////////////
///
/// start device descriptors
///
//////////////////////////////////////////////////////////////////
//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.
const char USB_STRING_DESC_OFFSET[]={0,4,12};
//number of strings you have, including string 0.
#define USB_STRING_DESC_COUNT sizeof(USB_STRING_DESC_OFFSET)
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
18, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
'G',0,
'A',0,
'M',0,
'E',0,
' ',0,
'P',0,
'A',0,
'D',0,
}; |
-and my excute code:
Code: | #include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#define __USB_PIC_PERIF__ 1
#DEFINE USB_HID_DEVICE TRUE //Tells the CCS PIC USB firmware
//to include HID handling code.
//turn on EP1 for IN interrupt transfers. (IN = PIC -> PC)
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT
#define USB_EP1_TX_SIZE 64 //max packet size of this endpoint
#define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for IN bulk/interrupt transfers
#define USB_EP1_RX_SIZE 64
#include <pic18_usb.h>
#include "usb_gamepad.h"
#include <usb.c>
#define LED2 PIN_B4
#define LED3 PIN_B5
#DEFINE BUTTON PIN_A4
#define LED_ON output_low
#define LED_OFF output_high
void usb_debug_task(void) {
static int8 last_connected;
static int8 last_enumerated;
int8 new_connected;
int8 new_enumerated;
new_connected=usb_attached();
new_enumerated=usb_enumerated();
if (new_connected)
LED_ON(LED2);
else
LED_OFF(LED2);
if (new_enumerated)
LED_ON(LED3);
else
LED_OFF(LED3);
last_connected=new_connected;
last_enumerated=new_enumerated;
}
void main(void) {
#define MOUSE_SEQUENCE_STEPS 16
const char mouse_seq[MOUSE_SEQUENCE_STEPS]=
{0, 1, 3, 4, 4, 4, 3, 1, 0, -1, -3, -4, -4, -4, -3, -1};
int8 out_data[2];
int8 x_seq=0; int8 y_seq=MOUSE_SEQUENCE_STEPS/4;
int8 count=0;
LED_OFF(LED2);
LED_OFF(LED3);
usb_init_cs();
usb_debug_task();
while (TRUE) {
usb_task();
usb_debug_task();
if (usb_enumerated()) {
out_data[0]=mouse_seq[x_seq];
out_data[1]=mouse_seq[y_seq];
//out_data[2]=0;
//out_data[3]=0; //wheel state goes here
//out_data[4]=0xFF;
if (usb_put_packet(1,out_data,2,USB_DTS_TOGGLE))
count++;
if (count > 10) {
if (++x_seq>=MOUSE_SEQUENCE_STEPS) {x_seq=0;}
if (++y_seq>=MOUSE_SEQUENCE_STEPS) {y_seq=0;}
count=0;
}
}
}
}
|
|
|