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

USB GamePad with PIC18F4550
Goto page 1, 2, 3, 4, 5  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

USB GamePad with PIC18F4550
PostPosted: Sun Mar 20, 2022 12:08 am     Reply with quote

Guys, first of all I deeply apologize if there is any other topic just like this one I'm making, I'm a bit desperate with this and pulling my hair almost...
Second, I want to apologize if my writing is not the best (english is not my first language), but I will try to be as clear as possible.


Let me explain what I'm trying to do:

I want to build an Arcade controller just like this one

HERE

If you look closely, that arcade controller also includes an "analog joystick" besides the regular digital one (4 or 8 micro switches).


The usb interface used to make the one of the picture is out of stock and besides it doesn't support the amount of buttons I would like to have.

My idea is to have a total of 13 buttons, a hat switch (which has 8 micro switches to include diagonals) and a two axis analog input for the analog stick.

I created the following descriptor using the tool from the official USB website and it parses my descriptor without issues.
Code:

const char USB_CLASS_SPECIFIC_DESC[] =
   {
    0x05, 0x01,                    //         USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    //         USAGE (Game Pad)
    0xa1, 0x01,                    //         COLLECTION (Application)
    0x15, 0x00,                    //           LOGICAL_MINIMUM (0)
    0x09, 0x01,                    //           USAGE (Pointer)
    0xa1, 0x00,                    //           COLLECTION (Physical)
    0x19, 0x30,                    //             USAGE_MINIMUM (X)
    0x29, 0x31,                    //             USAGE_MAXIMUM (Y)
    0x26, 0xff, 0x03,              //             LOGICAL_MAXIMUM (1023)
    0x75, 0x10,                    //             REPORT_SIZE (16)
    0x95, 0x02,                    //             REPORT_COUNT (2)
    0x81, 0x02,                    //             INPUT (Data,Var,Abs)
    0xc0,                          //           END_COLLECTION
    0x09, 0x39,                    //           USAGE (Hat switch)
    0x25, 0x07,                    //           LOGICAL_MAXIMUM (7)
    0x35, 0x00,                    //           PHYSICAL_MINIMUM (0)
    0x46, 0x3b, 0x01,              //           PHYSICAL_MAXIMUM (315)
    0x65, 0x14,                    //           UNIT (Eng Rot:Angular Pos)
    0x75, 0x08,                    //           REPORT_SIZE (8)
    0x95, 0x01,                    //           REPORT_COUNT (1)
    0x81, 0x02,                    //           INPUT (Data,Var,Abs)
    0x05, 0x09,                    //           USAGE_PAGE (Button)
    0x19, 0x01,                    //           USAGE_MINIMUM (Button 1)
    0x29, 0x0c,                    //           USAGE_MAXIMUM (Button 12)
    0x25, 0x01,                    //           LOGICAL_MAXIMUM (1)
    0x45, 0x00,                    //           PHYSICAL_MAXIMUM (0)
    0x65, 0x00,                    //           UNIT (None)
    0x75, 0x01,                    //           REPORT_SIZE (1)
    0x95, 0x0c,                    //           REPORT_COUNT (12)
    0x81, 0x02,                    //           INPUT (Data,Var,Abs)
    0xc0                           //         END_COLLECTION
   };

I took the original usb_desc_hid.h file provided by CCS and changed that part to use my descriptor.

In the main code I'm doing this:
Code:

#include <18F4550.h>
#device ADC = 10
#define USB_HID_DEVICE TRUE
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT
#define USB_EP1_TX_SIZE 8
#define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT
#define USB_EP1_RX_SIZE 8

#include <pic18_usb.h>
#include <C:\hid_descriptor_tool\arcade.h>
#include <usb.c>

#include <string.h>
#fuses NOWDT, NOPROTECT, NOLVP, VREGEN, NOMCLR, INTRC_IO
#use delay(clock=48MHz ,crystal=20MHz, USB_FULL)
#use rs232(uart1, baud = 9600)
#use fast_io(B)


int main (void)
 {
   
    char message[] = "PIC18F4550 microcontroller";
    char j, textsize;
    int i, estado;
    int16 x, y;
    //setup_oscillator(OSC_8MHZ);
    set_tris_b(0xC0); //seteo puerto B para lectura/escritura del multiplexor
    setup_adc(ADC_CLOCK_DIV_32);
    setup_adc_ports(AN0_TO_AN1);
   
    // Write your code here
   while (1) {     
      //putc(13);
     
      SET_ADC_CHANNEL(0);
      delay_us(20);
      x = read_adc();     
      SET_ADC_CHANNEL(1);
      delay_us(20);
      y = read_adc();     
      putc(13);     
      printf("Posicion del joystick: %lu %lu", x, y);
      putc(13);
      putc(10);
      //putc(10);
      for (i=0; i<8; i++) {
      printf("Voy a mandar el valor %d al puerto B\n", i);
      putc(13);
      putc(10);
           output_b(i);                     
           if (input(PIN_B7)) {
               printf("Boton %d: ACTIVADO", i);
           } else {
               printf("Boton %d: DESACTIVADO", i);
           }
      putc(13);
      putc(10);
      delay_ms(10);
      }
      putc(13);
      putc(10);
      delay_ms(10);
   }
     
   return 0;
 } 

This is in no way complete as I'm just starting. So far I have a multiplexer to be able to use only 4 pins to read 8 buttons so I don't have to use so many pins. Also I decided to use the series connection to debug.

The thing is that when I start the simulation in Proteus (with the virtual usb driver installed) Windows 10 tries to install my device but it brings errors...

Quote:

Este dispositivo no puede iniciar. (Código 10)

Se encontró una colección final adicional o no se encontró ninguna.


Let me translate that for you

Quote:

This device could not be initialized (Code 10)

An additional final collection was found or no collection was found at all.

I'm totally lost with this. I guess I would have to do something more than just replace the original class descriptor on that header file for it to work but I don't have a clue of what should I do.

I can provide all my files if needed, I will much appreciate any help you can provide me.

Thank you all.-
Ttelmah



Joined: 11 Mar 2010
Posts: 19495

View user's profile Send private message

PostPosted: Sun Mar 20, 2022 1:59 pm     Reply with quote

Start by looking at how the CCS example class descriptors are laid out.
You look to have taken a Microchip class descriptor and not added the other
stuff needed. The examples show a proper complete descriptor, It is
this you need to modify to include that class descriptor.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Sun Mar 20, 2022 2:17 pm     Reply with quote

First of all, thanks for your answer Ttelmah.

I was checking what you said and honestly I don't get it... I took the header file provided by CCS and the only things I did was removing all the RX stuff because my device doesn't need to get info from the computer, just send, and only replaced the class descriptor provided by my own.

If I leave the provided class descriptor provided (which is way smaller than mine) and quite different as they used a different kind of usage, it kinda works, but as soon as I put my own class descriptor (which is properly parsed without any errors by the official tool provided from usb.org) it comes with error code 10.


I didn't paste the entire code of the usb_desc_hid.h because I've seen other posts where mods had to edit that because we are not supposed to post the whole CCS driver stuff...


If you could give me an example of how should my class descriptor be I will greatly appreciate as this stuff is really obscure to me. I think that all the documentation and tools around this stuff are really poor and over-complicated. I don't why they couldn't make a little app where you define what you want your device to do (meaning, does it have buttons?, how many?, does it have a hat switch?, does it have analog axis?) and export the proper header file ready to use, even if it was not on the exact format for CCS, but for MikroC, I guess it would not be that hard to migrate.
Ttelmah



Joined: 11 Mar 2010
Posts: 19495

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 1:17 am     Reply with quote

OK. You posted as if this was the whole descriptor.
Get yourself a book on USB, or use one of the online versions.
The key is that USB descriptors are not a single entity. Each part cross
connects to other things.
You have to tell the other parts that you have changed the length of this
part, otherwise they won't work. Look at
USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE

How big is the CCS class specific descriptor?. How large is yours?.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 8:50 am     Reply with quote

Once again, Ttelmah, thanks for your help.

Finally I was able to make it work without error code 10!! Very Happy

Yet, for some odd reason, when I go to Devices and Printers, my devices is in there and has the icon of a gamepad, but when I try to get to the calibration page to see the buttons, axis and hat switch, it does not detect any configurable device Confused


Screenshot

I will keep checking now that I was able to make it work without explicit errors (Code 10), but if you happen to have an idea of why it may be happening that it doesn't show the device in order to calibrate it I would appreciate any help you may provide me.

Thanks for your time and invaluable help.
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 21, 2022 8:54 am     Reply with quote

I have done some work with USB HID and its descriptors across diverse devices. The USB descriptor you show is the device specific part only. There has to be interface and configuration definitions too. Unless those are seen, one does not really see the whole picture. that could be the source of your error message.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 9:56 am     Reply with quote

Thanks Jerson, I will copy&paste the whole header, I hope it is ok as I've seen other posts where mods actually deleted because apparently it is not allowed to post the whole code provided by CCS...


Code:

///////////////////////////////////////////////////////////////////////////
///                          usb_desc_hid.h                            ////
////                                                                   ////
//// An example set of device / configuration descriptors for use with ////
//// CCS's HID Demo example (see ex_usb_hid.c)                         ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////                                                                   ////

#include "usb_desc_hid.h"
#include<pic18_usb.h>
#include<usb.c>

char data[16];
void main(){
  lcd_init();                                    // Initialize LCD module
  lcd_putc('\f');                                // LCD clear
  lcd_gotoxy(1, 1);
  lcd_putc("USB HID Example");
  usb_init();                                 // Initialize USB hardware
  delay_ms(1000);
  while(TRUE){
    usb_task();
    /*if(usb_enumerated()){                // If the device has been enumerated by the PC
      if(usb_kbhit(1)){                  // If endpoint1 has data in it's receive buffer
        lcd_gotoxy(1, 2);
        lcd_putc("                ");            // Clear 2nd line
        // Read up to 16 bytes from endpoint1 buffer and save it to variable data
        //usb_get_packet(1, data, 16);
        lcd_gotoxy(1, 2);
        printf(lcd_putc, data);                  // Display the received bytes on LCD
        delay_ms(1000);                          // Wait 1 second
        // Return the received bytes back
        //usb_put_packet(1, data, 16, USB_DTS_TOGGLE);
      }
    }*/
  }
}

Disregard the lcd part, I decided to use a working example and do my modifications over it as a start point.

++++++++++++++++++++++++
Code deleted: Do not post CCS driver code per the forum rules.

- Forum Moderator
++++++++++++++++++++++++
Jerson



Joined: 31 Jul 2009
Posts: 125
Location: Bombay, India

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 21, 2022 10:29 am     Reply with quote

I suspect this line could be the reason


Code:
#DEFINE USB_TOTAL_CONFIG_LEN      34  //config+interface+class+endpoint (1 endpoint)
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 11:21 am     Reply with quote

Well, it may have sense but yet, there is a precompiler sentence that checks that and tells me if that value is wrong...

Code:
 
#if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN)
    #error USB_TOTAL_CONFIG_LEN not defined correctly
#endif


So I would assume that if that value was wrong it shouldn't even compile.

But I just tested with a tool called Thesycon USB Descriptor Dumper and clearly for my usb it is missing a lot of info but I'm just not sure why it is missing though.


Quote:

Information for device USB\Vendor_181C_Product_004F:

------------------------------
Connection Information:
------------------------------
Device current bus speed: LowSpeed
Device address: 0x0000
Current configuration value: 0x01
Number of open pipes: 0


------------------------------
Device Descriptor:
------------------------------
0x12 bLength
0x01 bDescriptorType
0x0110 bcdUSB
0x00 bDeviceClass
0x00 bDeviceSubClass
0x00 bDeviceProtocol
0x08 bMaxPacketSize0 (8 bytes)
0x181C idVendor
0x004F idProduct
0x0100 bcdDevice
0x01 iManufacturer
0x02 iProduct
0x00 iSerialNumber
0x01 bNumConfigurations

Configuration descriptor and all subsequent descriptors are not available. Error code: 0x00000057

Microsoft OS Descriptor is not available. Error code: 0x00000057


--------------------------------
String Descriptor Table
--------------------------------
Index LANGID String
0x00 0x0000
0x01 0x0000 Request failed with 0x00000057
0x02 0x0000 Request failed with 0x00000057

------------------------------

Connection path for device:
Virtual Usb Hub
Root Hub
USB\Vendor_181C_Product_004F Port: 1

Running on: Windows 10 or greater (Build Version 19043)

Brought to you by TDD v2.17.0, Feb 23 2021, 14:04:02


As you can see, it is only seing the device descriptor... I will try to change that value you mentioned as it does make sense, even though that precompiler sentence...
Ttelmah



Joined: 11 Mar 2010
Posts: 19495

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 11:24 am     Reply with quote

The point is you can't just stuff a new bit into a descriptor, the whole
thing has to work together. Hence you need to read how these work,
and how each part is used.
There are several references explaining this. Some reading is needed.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 11:39 am     Reply with quote

Ttelmah, I did read several documentations including the official one and also a pdf of the fourth edition of Jan Axelson, the thing is that all this stuff is really unnecessarily obscure because there is no clear documentation, at least, for it's usage with CCS.

I think I understand the basics of how the heck USB descriptors work but my problem is when I have to put that in practice in CCS, like, how is CCS actually forming the whole damn thing. For example, I checked every forum where people had the same problem I initially had and nobody, NOBODY cared to say "hey, if you changed the default descriptor, you should make sure you update it's length on the appropriate variable or it will not work".

It's like the experts of USB and embedded systems don't want the rest of us mortals to know how to work with this.

I haven't found even a single complete example of a Gamepad done with a PIC and coded with CCS...
Ttelmah



Joined: 11 Mar 2010
Posts: 19495

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 12:24 pm     Reply with quote

Always start by searching the forum.
This poster:
[url]
https://www.ccsinfo.com/forum/viewtopic.php?t=47415
[/url]

got his working after one change.

The actual structures are the same whatever processor is used. The CCS
examples show how the stuff has to be laid out.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 12:36 pm     Reply with quote

I did read that post long ago and if you check my code you will see I commented everything regarding the in-going connection as the gamepad doesn't need to receive any info from the PC and I also adjusted the descriptor size based on the fact that I have only one endpoint.

Also, if you see that post, the guy is saying he is getting error code 10, I had that before but I fixed it by setting the proper length for the class descriptor as you suggested so I don't see how is that post related to my current problem (the calibration page not showing and actually the device not sending the complete config to the PC).

That is what makes me even more confused, I have everything just like that guy, except by my descriptor because I have more buttons and a hat switch, and my version does not work properly.
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 1:26 pm     Reply with quote

re: It's like the experts of USB and embedded systems don't want the rest of us mortals to know how to work with this.

I feel your pain...

USB means Useless Serial Bus..... Smile

Good old RS-232 was simple to implement , reliable and interrupt driven. Everyone understood HOW it worked..well, until someone decide to use DE-9 connector and swap xmt and rcv pins......

I got around the BS of USB by using $2 TTL<>USB modules, reduced the coffee pots to only 2 a day from 4...... Shocked

Jay
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Mon Mar 21, 2022 1:48 pm     Reply with quote

I appreciate that but I really need help with this, I understand your point but unfortunately your post doesn't help in no way with my problem.

If you happen to have an idea of what the heck I am doing wrong it would be greatly appreciated.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3, 4, 5  Next
Page 1 of 5

 
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