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 support@ccsinfo.com

USB GamePad with PIC18F4550
Goto page Previous  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

PostPosted: Wed Mar 23, 2022 10:16 am     Reply with quote

newguy wrote:
Suggestion: once you get it working throw it in the code library section of this forum. You yourself said it was frustrating that were no clear examples of working code....


I sure will and I will make some side notes of issues I encountered on the way so if anyone stumbles with them, he has an idea how to work around. But I prefer to wait until I have the actual hardware to be sure everything works as expected before making a post there.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 12:09 am     Reply with quote

Guys, today I got my Pickit 3 and two 18F4550, I tried to program my code into the PICs and now things are even worse than before, whenever I plug my PIC to the computer it says it doesn't recognize the device. It gives me an error code 43.

I tried the descriptor dumper and these are the results

Quote:

Information for device USB\Vendor_0000_Product_0000:

------------------------------
Connection Information:
------------------------------
Device current bus speed: FullSpeed
Device supports USB 1.1 specification
Device supports USB 2.0 specification
Device address: 0x0000
Current configuration value: 0x00
Number of open pipes: 0

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


--------------------------------
String Descriptor Table
--------------------------------
Index LANGID String

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

Connection path for device:
Controladora de host USB genérico compatible con xHCI
Root Hub
Concentrador USB genérico
Concentrador USB genérico
USB\Vendor_0000_Product_0000 Port: 4

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

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


Now it does recognize it is indeed a full speed device but nothing else... I haven't changed the code at all...
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 1:44 am     Reply with quote

Shows how wrong the emulation was.
This is because the VID/PID you have for the device is not now accepted
by Windows. Use UsbView (part of the WDK). This will show what
Windows is seeing.
I'd suspect you will find that Windows is only seeing the first eight bytes
of the descriptor.
If so, ideally you need to recode the firmware so that it checks the length
required by a GET DESCRIPTOR call. If it says 8, then just the first
eight bytes need to be sent. If it says 64, then you need to return
the whole descriptor.
The way that this call is handled by Windows, was changed a while ago.
Alternatively disable selective suspend on the Windows system.

[url]
https://thegeekpage.com/fix-error-usb-device-descriptor-failure-in-windows-10-solved/
[/url]
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 2:03 am     Reply with quote

Actually is kinda weird, I don't know if I just killed my brand new 18F4550 but, whenever I plug it properly the computer just doesn't even realize something has been plugged on the USB, but if I put the PIC upside down (with the little marking on bottom instead of on top) then the computer does understand that some kind of device has been plugged but just doesn't recognize it.

In any case, the thing that is confusing me the most is that a guy from the technical support said he programmed my exact code on an actual pic and it worked just fine and even gave me the descriptor dump which somehow proves it worked, but it won't work on my end... he used a slightly different model of PIC but yet from the 18 family.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 2:26 am     Reply with quote

Plugging it in backwards could easily kill it.... Sad
However, worth checking that his board is set up the same as yours.
Classic 'wrong' things are getting D+ and D- reversed on the USB, or
an incorrect clock setup. USB is critical on the clock.
If he is using a different PIC, he will have had to put in his own fuses
and clock settings for this. The 4550 is quite 'strict' about it's clock
compared to modern chips.
temtronic



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

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 5:16 am     Reply with quote

nice, I can consider myself a 'classic' dinosaur, as I did the D+,D- reversal Sad
Next day ordered 10 of those USB<>TTL modules Smile
I recall needing a proper cap on a certain pin a using a 4MHz xtal for the clock to get the correct clocks.
I'm thinking this was 8-10 years ago ? when the 4550 was the 'new kid on the block'.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 1:16 pm     Reply with quote

Well, the thing is that what I did, I think is even worse than reverse D+ and D-, basically I short circuited VCC and GND on the pic, you know, the 4550 has two pins for VCC and two pins for GND on each side, well, I counted wrongly the pins on one side and the whole thing got hot as heck... the "weird" thing is that the pic still let's me read and write to it with the PICkit 3, but I guess it may have sustained some internal damage nevertheless...

I guess I will have to buy more of them...

Also, I'm intending to use a 12Mhz crystal, on my config I have


Code:


#fuses  HSPLL PLL2 CPUDIV1 USBDIV VREGEN NOMCLR
#use delay(clock = 48Mhz, crystal = 12Mhz, usb_full)



do you see it alright?? or did I make a silly mistake and I configured it wrong??
temtronic



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

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 1:32 pm     Reply with quote

I always printed out the 'clock diagram' to see the 'flow' and then decide what was necessary.
Don't think the CPUDIV1 is necessary as CPU clock will be coming from the PLL/USB chain....

I found out the hard way some config aren't allowed.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 1:55 pm     Reply with quote

For some odd reason, some code that was before the usual infinite loop made it not being able to reach that point, not even the usb_init()... now it does, Windows does detect the PIC but doesn't recognize the device...

I'm not sure if it somehow survived what I did to it but I still have to figure out the propper setting for the clock (as for what I heard, USB is pretty specific with timing) or if it has to do with some kind of internal damage.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 4:03 pm     Reply with quote

manusoftar wrote:
For some odd reason, some code that was before the usual infinite loop made it not being able to reach that point, not even the usb_init()... now it does, Windows does detect the PIC but doesn't recognize the device...

I'm not sure if it somehow survived what I did to it but I still have to figure out the proper setting for the clock (as for what I heard, USB is pretty specific with timing) or if it has to do with some kind of internal damage.


Ok, about that code that wouldn't let my PIC to continue part of it was

Code:

lcd_init();


And since I don't have any LCD physically connected to my PIC, it just stopped the execution at that point...
temtronic



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

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 5:07 pm     Reply with quote

Without seeing the actual code, that function may have been looking for a response from the LCD module.

lcdinit() probably initializes an LCD module to some sort of 'configuration' that then allows the PIC to control and communicate with the LCD module.
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Sat Mar 26, 2022 5:13 pm     Reply with quote

The last thing I had to change in order to get it finaly working was a cap I was using to connect VUSB to GND, I was using a 22pF, I changed that for a 0.1uF and the pc finally recognized my device Very Happy

Now I need to add all the data sending code for all the buttons, axis and hat switch...
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Mar 27, 2022 2:17 am     Reply with quote

Sounds like steady progress. Very Happy
Have fun on the next bits.
temtronic



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

View user's profile Send private message

PostPosted: Sun Mar 27, 2022 6:16 am     Reply with quote

Nice to hear someone's going forward !!
You may want to split the next code into two sections.

1 the actual 'data collection'( button/pot info)
2 transferring that into the 'send by USB function buffers'

This way you can fill 'dummy', known data into the 'bytes to send by USB buffers' and confirm the PC gets the correct data, in the correct order.
It might save a few hours of head scratching debugging where you learn you've swapped X axis data for Y axis data, not that I've done that in the past..... Sad
manusoftar



Joined: 19 Mar 2022
Posts: 46

View user's profile Send private message

PostPosted: Sun Mar 27, 2022 7:20 pm     Reply with quote

Hi guys, first of all I want to say that I tried replacing the 0.1uF ceramic cap for an electrolytic and it worked like a charm.

Also, I checked my circuit design in Proteus and I didn't have the proper cap on the VUSB either, I placed it, run the simulation and it does actually work and simulates the device properly, so it wasn't a matter of poor simulation but of poor circuit design on my behalf.


Now I'm facing a different and confusing problem. The device connects to the PC and it recognizes the device properly. I also connected one multiplexer and one lm317 to obtain 3.3v for the multiplexer, so far so good.

I made some changes on the code to work with the multiplexer, my idea is to use 3 multiplexers for the buttons and hat switch and two analog pins to read the analog stick input. That way I don't run out of pins. Remember that I have a hat switch and 17 buttons.

The thing is that whenever I try to do usb_put_packet() it keeps reconnecting to the PC, like, I can hear the sound of a usb device being plugged and unplugged continuously.

I am doing this:
Code:

// PIC18F4550 USB HID Example CCS C code
#include <18F4550.h>

//LCD module connections
#define LCD_RS_PIN PIN_D0
#define LCD_RW_PIN PIN_D1
#define LCD_ENABLE_PIN PIN_D2
#define LCD_DATA4 PIN_D3
#define LCD_DATA5 PIN_D4
#define LCD_DATA6 PIN_D5
#define LCD_DATA7 PIN_D6
//End LCD module connections

#define USB_CONFIG_HID_TX_SIZE 6                // Transmit packet size (bytes)
//#define USB_CONFIG_HID_RX_SIZE 16                // Receive packet size (bytes)
#define USB_CONFIG_PID 0x0079                         //Chnage Product Id
#define USB_CONFIG_VID 0x181C                      //Chnage Vendor Id
#define USB_STRINGS_OVERWRITTEN
#define USB_CONFIG_HID_TX_POLL 1 //fullspeed


#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,VREGEN,NOPBADEN
#use delay(clock = 48Mhz)
//#include <lcd.c>
//#use rs232(baud = 9600,xmit=PIN_C6,rcv=PIN_C7)
#define USB_STRING(x)  (sizeof(_unicode(x))+2), 3, _unicode(x)

#use fast_io(b)
//#DEFINE USB_DESC_CLASS_LEN 66
//#DEFINE USB_DESC_DEVICE_LEN 66
rom char USB_STRING_DESC[]={
    //string 0 (must always provide this string)
    //4(length of string index),3(descriptor type is string),9&4(Microsoft Defined for US-English)
    4, 3, 9, 4, 
    //string 1 - vendor (this is optional, but we specified it's use in the device descriptor)
    USB_STRING("DIC"),
    //string 2 - product (this is optional, but we specified it's use in the device descriptor)
    USB_STRING("USB Gamepad"),
    //string 3 - serial number (this is optional, but we specified it's use in the device descriptor)
    USB_STRING("123456789")};
   
const char USB_CLASS_SPECIFIC_DESC[]={
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x15, 0x00,                    // LOGICAL_MINIMUM (0)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x05, 0x01,                    //   USAGE_PAGE (Generic Desktop)
    0x09, 0x01,                    //   USAGE (Pointer)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //     END_COLLECTION
    0x09, 0x39,                    //   USAGE (Hat switch)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    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, 0x11,                    //   USAGE_MAXIMUM (Button 17)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x11,                    //   REPORT_COUNT (17)
    0x55, 0x00,                    //   UNIT_EXPONENT (0)
    0x65, 0x00,                    //   UNIT (None)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x07,                    //   REPORT_COUNT (7)
    0x81, 0x01,                    //   INPUT (Cnst,Ary,Abs)
    0xc0                           // END_COLLECTION 
};


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

unsigned char data[6]; //Acá va todo el reporte del gamepad (6 bytes)
unsigned char hatsw;

void main(){
 
  set_tris_b(0xC0);  //Pong los dos últimos pines B6 y B7 como lectura y los otros 6 como escritura para interactuar con 2 multiplexores.
  usb_init();                                    //HABILITA LA INTERRUPCIÓN DE USB
  usb_task();                                    //HABILITA LA CONEXION USB
  /*lcd_init();                                    // Initialize LCD module
  lcd_putc('\f');                                // LCD clear
  lcd_gotoxy(1, 1);
  lcd_putc("USB HID Example"); */
 
  /*printf("Iniciando...\n");
  putc(13);
  putc(10);*/
 
 
  usb_wait_for_enumeration();                    //ESPERA EN ESTA LINEA HASTA COMPLETAR LA ENUMERACIÓN CON EXITO             
  /*printf("Dispositivo USB enumerado\n");
  putc(13);
  putc(10);*/

  while(TRUE){
   //hatsw = 4;
   hatsw = -1; //reseteo los bits
   for (int i=0; i<8; i++) {
        //Primero reviso el multiplexor 1
        output_b(i);
        if (input(PIN_B6)==1) {
            hatsw = i;
            break;
        }
   }
   
   /*data[2] = hatsw; */
   data[0] = 0;
   data[1] = 0;
   data[2] = hatsw;
   data[3] = 0;
   data[4] = 0;
   data[5] = 0;
   delay_ms(15);
   if (usb_enumerated()) {
      while(!usb_put_packet(1, data, 6, USB_DTS_TOGGLE));
   }
    //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);
      }
    }*/
  }
}


As you can see my packet size is 6 bytes, the endpoint is the number 1 (the only endpoint I have defined because my device doesn't need to receive info from the pc), and the variable "data" is an unsigned char.

If any of you know why could this strange behaviour happening it would be of great help.

Thanks.
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 Previous  1, 2, 3, 4, 5  Next
Page 3 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