USB Keyboard with PIC18F4550

Discussion in 'Embedded Systems and Microcontrollers' started by Dalaran, Mar 3, 2012.

  1. Dalaran

    Thread Starter Active Member

    Dec 3, 2009
    168
    0
    I have been working on for some time a USB keyboard with the PIC18F4550. I am using MikroC PRO for PIC and have started working with their example of HID write that they have. Using this example I can open the HID terminal in mikroC and see the device detect and the data being written. I followed the steps here:
    http://helmpcb.com/electronics/usb-joystick

    If I use the joystick.hid from the HID descriptor tool and follow the other steps it gets detected in the HID terminal of mikroC. However, when I use the keybrd.hid from the HID descriptor and follow the same method it does not detect in the HID terminal. The PC makes the sound to indicate that something new has been detected, but nothing shows up on the HID terminal.

    Here is my descriptor code:
    Code ( (Unknown Language)):
    1. //******************************************************************************
    2. //
    3. // File Version 1.01
    4. //
    5. //******************************************************************************
    6.  
    7. #include "Definit.h"
    8. #include "VARs.h"
    9.  
    10. //******************************************************************************
    11. // The number of bytes in each report,
    12. // calculated from Report Size and Report Count in the report descriptor
    13. //******************************************************************************
    14. unsigned char const HID_INPUT_REPORT_BYTES      = 1;
    15. unsigned char const HID_OUTPUT_REPORT_BYTES     = 1;
    16.  
    17. unsigned char const HID_FEATURE_REPORT_BYTES    = 2;
    18. //******************************************************************************
    19. // Byte constants
    20. //******************************************************************************
    21. unsigned char const NUM_ENDPOINTS               = 2;
    22. unsigned char const ConfigDescr_wTotalLength    = USB_CONFIG_DESCRIPTOR_LEN + USB_INTERF_DESCRIPTOR_LEN + USB_HID_DESCRIPTOR_LEN + (NUM_ENDPOINTS * USB_ENDP_DESCRIPTOR_LEN);
    23. unsigned char const HID_ReportDesc_len          = 63;
    24.  
    25. unsigned char const Low_HID_ReportDesc_len      = HID_ReportDesc_len;
    26. unsigned char const High_HID_ReportDesc_len     = HID_ReportDesc_len >> 8;
    27.  
    28. unsigned char const Low_HID_PACKET_SIZE         = HID_PACKET_SIZE;
    29. unsigned char const High_HID_PACKET_SIZE        = HID_PACKET_SIZE >> 8;
    30.  
    31. // Descriptor Tables
    32.  
    33. unsigned char const DescTables[] = {
    34.  
    35. // Device Descriptor
    36.     USB_DEVICE_DESCRIPTOR_LEN, 0,           // bLength               - Length of Device descriptor (always 0x12)
    37.     USB_DEVICE_DESCRIPTOR_TYPE, 0,          // bDescriptorType       - 1 = DEVICE descriptor
    38.     0x00, 0,                                // bcdUSB                - USB revision 2.00 (low byte)
    39.     0x02, 0,                                //                                           (high byte)
    40.     0x00, 0,                                // bDeviceClass          - Zero means each interface operates independently (class code in the interface descriptor)
    41.     0x00, 0,                                // bDeviceSubClass
    42.     0x00, 0,                                // bDeviceProtocol
    43.     EP0_PACKET_SIZE, 0,                     // bMaxPacketSize0       - maximum size of a data packet for a control transfer over EP0
    44.     0x34, 0,                                // idVendor              - Vendor  ID (low byte)
    45.     0x12, 0,                                //                                    (high byte)
    46.     0x01, 0,                                // idProduct             - Product ID (low byte)
    47.     0x00, 0,                                //                                    (high byte)
    48.     0x01, 0,                                // bcdDevice             - ( low byte)
    49.     0x00, 0,                                //                         (high byte)
    50.     0x01, 0,                                // iManufacturer         - String1
    51.     0x02, 0,                                // iProduct              - String2
    52.     0x00, 0,                                // iSerialNumber         - ( None )
    53.     0x01, 0,                                // bNumConfigurations    - 1
    54.  
    55. // Configuration Descriptor
    56.     USB_CONFIG_DESCRIPTOR_LEN, 0,           // bLength               - Length of Configuration descriptor (always 0x09)
    57.     USB_CONFIG_DESCRIPTOR_TYPE, 0,          // bDescriptorType       - 2 = CONFIGURATION descriptor
    58.     ConfigDescr_wTotalLength, 0,            // wTotalLength          - Total length of this config. descriptor plus the interface and endpoint descriptors that are part of the configuration.
    59.     0x00, 0,                                //                         ( high byte)
    60.     0x01, 0,                                // bNumInterfaces        - Number of interfaces
    61.     0x01, 0,                                // bConfigurationValue   - Configuration Value
    62.     0x00, 0,                                // iConfiguration        - String Index for this configuration ( None )
    63.     0xA0, 0,                                // bmAttributes          - attributes - "Bus powered" and "Remote wakeup"
    64.     50, 0,                                  // MaxPower              - bus-powered draws 50*2 mA from the bus.
    65.  
    66. // Interface Descriptor
    67.     USB_INTERF_DESCRIPTOR_LEN, 0,           // bLength               - Length of Interface descriptor (always 0x09)
    68.     USB_INTERFACE_DESCRIPTOR_TYPE, 0,       // bDescriptorType       - 4 = INTERFACE descriptor
    69.     0x00, 0,                                // bInterfaceNumber      - Number of interface, 0 based array
    70.     0x00, 0,                                // bAlternateSetting     - Alternate setting
    71.     NUM_ENDPOINTS, 0,                       // bNumEndPoints         - Number of endpoints used in this interface
    72.     0x03, 0,                                // bInterfaceClass       - assigned by the USB
    73.     0x00, 0,                                // bInterfaceSubClass    - Not A boot device
    74.     0x00, 0,                                // bInterfaceProtocol    - none
    75.     0x00, 0,                                // iInterface            - Index to string descriptor that describes this interface ( None )
    76.  
    77. // HID Descriptor
    78.     USB_HID_DESCRIPTOR_LEN, 0,              // bLength               - Length of HID descriptor (always 0x09)
    79.     USB_HID_DESCRIPTOR_TYPE, 0,             // bDescriptorType       - 0x21 = HID descriptor
    80.     0x01, 0,                                // HID class release number (1.01)
    81.     0x01, 0,
    82.     0x00, 0,                                // Localized country code (none)
    83.     0x01, 0,                                // # of HID class descriptor to follow (1)
    84.     0x22, 0,                                // Report descriptor type (HID)
    85.     Low_HID_ReportDesc_len, 0,
    86.     High_HID_ReportDesc_len, 0,
    87.  
    88. // EP1_RX Descriptor
    89.     USB_ENDP_DESCRIPTOR_LEN, 0,             // bLength               - length of descriptor (always 0x07)
    90.     USB_ENDPOINT_DESCRIPTOR_TYPE, 0,        // bDescriptorType       - 5 = ENDPOINT descriptor
    91.     0x81, 0,                                // bEndpointAddress      - In, EP1
    92.     USB_ENDPOINT_TYPE_INTERRUPT, 0,         // bmAttributes          - Endpoint Type - Interrupt
    93.     Low_HID_PACKET_SIZE, 0,                 // wMaxPacketSize        - max packet size - low order byte
    94.     High_HID_PACKET_SIZE, 0,                //                       - max packet size - high order byte
    95.     1, 0,                                  // bInterval             - polling interval (1 ms)
    96.  
    97. // EP1_TX Descriptor
    98.     USB_ENDP_DESCRIPTOR_LEN, 0,             // bLength               - length of descriptor (always 0x07)
    99.     USB_ENDPOINT_DESCRIPTOR_TYPE, 0,        // bDescriptorType       - 5 = ENDPOINT descriptor
    100.     0x01, 0,                                // bEndpointAddress      - Out, EP1
    101.     USB_ENDPOINT_TYPE_INTERRUPT, 0,         // bmAttributes          - Endpoint Type - Interrupt
    102.     Low_HID_PACKET_SIZE, 0,                 // wMaxPacketSize        - max packet size - low order byte
    103.     High_HID_PACKET_SIZE, 0,                //                       - max packet size - high order byte
    104.     1, 0,                                  // bInterval             - polling interval (1 ms)
    105.  
    106.  
    107.  
    Any ideas what is happening differently between the joystick and keyboard? Any help to get this detect is appreciated. I know this is just the first step, but a major one to get going on my pic keyboard emulator.

    (code too long and continuing on next post)

    Thanks!
     
  2. Dalaran

    Thread Starter Active Member

    Dec 3, 2009
    168
    0
    continuation of code

    Code ( (Unknown Language)):
    1. //Keyboard descriptor
    2.     0x05, 0,
    3.     0x01, 0,                    // USAGE_PAGE (Generic Desktop)
    4.     0x09, 0,
    5.     0x06, 0,                    // USAGE (Keyboard)
    6.     0xa1, 0,
    7.     0x01, 0,                    // COLLECTION (Application)
    8.     0x05, 0,
    9.     0x07, 0,                    //   USAGE_PAGE (Keyboard)
    10.     0x19, 0,
    11.     0xe0, 0,                    //   USAGE_MINIMUM (Keyboard LeftControl)
    12.     0x29, 0,
    13.     0xe7, 0,                    //   USAGE_MAXIMUM (Keyboard Right GUI)
    14.     0x15, 0,
    15.     0x00, 0,                    //   LOGICAL_MINIMUM (0)
    16.     0x25, 0,
    17.     0x01, 0,                    //   LOGICAL_MAXIMUM (1)
    18.     0x75, 0,
    19.     0x01, 0,                    //   REPORT_SIZE (1)
    20.     0x95, 0,
    21.     0x08, 0,                    //   REPORT_COUNT (8)
    22.     0x81, 0,
    23.     0x02, 0,                    //   INPUT (Data,Var,Abs)
    24.     0x95, 0,
    25.     0x01, 0,                    //   REPORT_COUNT (1)
    26.     0x75, 0,
    27.     0x08, 0,                    //   REPORT_SIZE (8)
    28.     0x81, 0,
    29.     0x03, 0,                    //   INPUT (Cnst,Var,Abs)
    30.     0x95, 0,
    31.     0x05, 0,                    //   REPORT_COUNT (5)
    32.     0x75, 0,
    33.     0x01, 0,                    //   REPORT_SIZE (1)
    34.     0x05, 0,
    35.     0x08, 0,                    //   USAGE_PAGE (LEDs)
    36.     0x19, 0,
    37.     0x01, 0,                    //   USAGE_MINIMUM (Num Lock)
    38.     0x29, 0,
    39.     0x05, 0,                    //   USAGE_MAXIMUM (Kana)
    40.     0x91, 0,
    41.     0x02, 0,                    //   OUTPUT (Data,Var,Abs)
    42.     0x95, 0,
    43.     0x01, 0,                    //   REPORT_COUNT (1)
    44.     0x75, 0,
    45.     0x03, 0,                    //   REPORT_SIZE (3)
    46.     0x91, 0,
    47.     0x03, 0,                    //   OUTPUT (Cnst,Var,Abs)
    48.     0x95, 0,
    49.     0x06, 0,                    //   REPORT_COUNT (6)
    50.     0x75, 0,
    51.     0x08, 0,                    //   REPORT_SIZE (8)
    52.     0x15, 0,
    53.     0x00, 0,                    //   LOGICAL_MINIMUM (0)
    54.     0x25, 0,
    55.     0x65, 0,                    //   LOGICAL_MAXIMUM (101)
    56.     0x05, 0,
    57.     0x07, 0,                    //   USAGE_PAGE (Keyboard)
    58.     0x19, 0,
    59.     0x00, 0,                    //   USAGE_MINIMUM (Reserved (no event indicated))
    60.     0x29, 0,
    61.     0x65, 0,                    //   USAGE_MAXIMUM (Keyboard Application)
    62.     0x81, 0,
    63.     0x00, 0,                    //   INPUT (Data,Ary,Abs)
    64.     0xc0, 0,                           // END_COLLECTION
    65. };
    66. //******************************************************************************
    67. unsigned char const LangIDDescr[8] = {
    68.     0x04, 0,
    69.     USB_STRING_DESCRIPTOR_TYPE, 0,
    70.     0x09, 0,                                // LangID (0x0409) - Low
    71.     0x04, 0                                 //                 - High
    72. };
    73. //******************************************************************************
    74. unsigned char const ManufacturerDescr[68] = {
    75.     34, 0,
    76.     USB_STRING_DESCRIPTOR_TYPE, 0,
    77.     'B', 0, 0, 0,
    78.     'u', 0, 0, 0,
    79.     'c', 0, 0, 0,
    80.     'h', 0, 0, 0,
    81.     'y', 0, 0, 0,
    82.     's', 0, 0, 0,
    83.     ' ', 0, 0, 0,
    84.     'S', 0, 0, 0,
    85.     'o', 0, 0, 0,
    86.     'l', 0, 0, 0,
    87.     'u', 0, 0, 0,
    88.     't', 0, 0, 0,
    89.     'i', 0, 0, 0,
    90.     'o', 0, 0, 0,
    91.     'n', 0, 0, 0,
    92.     's', 0, 0, 0
    93. };
    94. //******************************************************************************
    95. unsigned char const ProductDescr[100] = {
    96.     50, 0,
    97.     USB_STRING_DESCRIPTOR_TYPE, 0,
    98.     'B', 0, 0, 0,
    99.     'u', 0, 0, 0,
    100.     'c', 0, 0, 0,
    101.     'h', 0, 0, 0,
    102.     'y', 0, 0, 0,
    103.     's', 0, 0, 0,
    104.     ' ', 0, 0, 0,
    105.     'A', 0, 0, 0,
    106.     'r', 0, 0, 0,
    107.     'c', 0, 0, 0,
    108.     'a', 0, 0, 0,
    109.     'd', 0, 0, 0,
    110.     'e', 0, 0, 0,
    111.     ' ', 0, 0, 0,
    112.     'C', 0, 0, 0,
    113.     'o', 0, 0, 0,
    114.     'n', 0, 0, 0,
    115.     't', 0, 0, 0,
    116.     'r', 0, 0, 0,
    117.     'o', 0, 0, 0,
    118.     'l', 0, 0, 0,
    119.     'l', 0, 0, 0,
    120.     'e', 0, 0, 0,
    121.     'r', 0, 0, 0
    122. };
    123.  
    124. unsigned char const StrUnknownDescr[4] = {
    125.     2, 0,
    126.     USB_STRING_DESCRIPTOR_TYPE, 0
    127. };
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    I could not follow what two methods you used, but generally...

    The Vendor ID and Product ID (VID and PID) need to match for any device to be recognized by a windows program. That is how windows identifies the actual hardware out there.
     
  4. Dalaran

    Thread Starter Active Member

    Dec 3, 2009
    168
    0
    I was able to get my keyboard working in windows by modifying the descriptor file as well as my USB write sequence to the PC. I can now push buttons and have my coded key show up in notepad or something similar.

    I was originally intending this to be used so that I can convert button strokes on an arcade machine to register in MAME. These key strokes still work in DOS and other Windows applications, but for some reason they do not register in MAME. My regular keyboard does, but my PIC created one does not.

    Anyone with ideas why I can not see this in MAME but can in all other apps I've tried?

    Thanks.
     
  5. rasyoung

    New Member

    Apr 27, 2011
    1
    0
    Sir,

    Do you have the exact code for this solution, I am struggling with same problem ( I need to able to HID USB keystroke with MicroC)?

    I would like to see it please.

    Thanks.
     
Loading...