This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC2368 HID Keyboard

Hi,

I've been try to modify USB_HID lpc23xx code to keyboard.
and I aleady read this forum.
www.cygnal.org/.../001381.html

and I already modify usbdesc.c for keyboard.
Now PC can see my lpc2368 board as HID_KEYBOARD.
But I can't send data to PC, so can you told how to midify code for send keyboard data from my board to PC.

Thanks,

Nuttawit

Parents
  • Thanks to referring my post for SiLabs forum
    It's somewhat weird to answer to it on Keil forum :-)

    Is this the base example?

    "LPC2368 / LPC2378 USB HID (Human Interface Device) Example" on KEIL
    http://www.keil.com/download/docs/335.asp

    I explain about a simple implementation, for first try.
    In this snippet, the device sends key input reports every time the endpoint interrupt occurs. The rate of report transmission is determined by the bInterval field (ms) of the endpoint descriptor of the interrupt IN. That is, the key scan rate also matches to this rate.

    a) In the Set_Configuration callback, put the first dummy report to the interrupt IN endpoint.
    It triggers the interrupt sequence.

    usbuser.c
    
    #include <string.h>
    #define KEYREPORT_SIZE    8
    BYTE keyReport[ KEYREPORT_SIZE ];
    
    /*
     *  USB Set Configuration Event Callback
     *   Called automatically on USB Set Configuration Request
     */
    
    #if USB_CONFIGURE_EVENT
    void USB_Configure_Event (void) {
    
      if (USB_Configuration) {                  /* Check if USB is configured */
        memset( keyReport, 0, sizeof(keyReport) );        // clear out the input report
        USB_WriteEP(0x81, keyReport, sizeof(keyReport));  // send it to trigger interrupt sequence
      }
    }
    #endif
    


    b) In the endpoint ISR, scan the keys and put the keycode to the report.
    And put the report to the IN endpoint.
    Write your own KeyScan() routine :-)

    usbuser.c
    
    /*
     *  USB Endpoint 1 Event Callback
     *   Called automatically on USB Endpoint 1 Event
     *    Parameter:       event
     */
    
    void USB_EndPoint1 (DWORD event) {
    
      switch (event) {
        case USB_EVT_IN:
          KeyScan();
          USB_WriteEP(0x81, keyReport, sizeof(keyReport));
          break;
      }
    }
    

    In the KeyScan(), you don't need to consider make/break of keys - it is handled by the host side. Just put the keycode(s) to the keycode array on the report, for the key(s) currently pushed down. The keycode array can hold up to 6 keys - 6 key rollover. When more than 6 keys are pushed simultaneously, fill the keycode array with ErrorRollOver (0x01) When no key is pushed, clear the array with 0.

    Report format
    
    keyReport
     byte
      0   Modifier byte
      1   reserved - 0
      2   keycode array [0]
      3   keycode array [1]
      4   keycode array [2]
      5   keycode array [3]
      6   keycode array [4]
      7   keycode array [5]
    
    The bitmap of Modifier byte
     bit
      0   LEFT CTRL
      1   LEFT SHIFT
      2   LEFT ALT
      3   LEFT GUI
      4   RIGHT CTRL
      5   RIGHT SHIFT
      6   RIGHT ALT
      7   RIGHT GUI
    

    The keycodes are defined in this spec

    HID Usage Table 1.12
    www.usb.org/.../Hut1_12.pdf
    10 Keyboard/Keypad Page (0x07) (Hut1_12.pdf p54)

    When you succeed this try, the next step is,
    - send the key report just when key make/break occurs (Windows default)
    - support output report for LED indicators - CAPS, Num lock etc.

    Tsuneo

Reply
  • Thanks to referring my post for SiLabs forum
    It's somewhat weird to answer to it on Keil forum :-)

    Is this the base example?

    "LPC2368 / LPC2378 USB HID (Human Interface Device) Example" on KEIL
    http://www.keil.com/download/docs/335.asp

    I explain about a simple implementation, for first try.
    In this snippet, the device sends key input reports every time the endpoint interrupt occurs. The rate of report transmission is determined by the bInterval field (ms) of the endpoint descriptor of the interrupt IN. That is, the key scan rate also matches to this rate.

    a) In the Set_Configuration callback, put the first dummy report to the interrupt IN endpoint.
    It triggers the interrupt sequence.

    usbuser.c
    
    #include <string.h>
    #define KEYREPORT_SIZE    8
    BYTE keyReport[ KEYREPORT_SIZE ];
    
    /*
     *  USB Set Configuration Event Callback
     *   Called automatically on USB Set Configuration Request
     */
    
    #if USB_CONFIGURE_EVENT
    void USB_Configure_Event (void) {
    
      if (USB_Configuration) {                  /* Check if USB is configured */
        memset( keyReport, 0, sizeof(keyReport) );        // clear out the input report
        USB_WriteEP(0x81, keyReport, sizeof(keyReport));  // send it to trigger interrupt sequence
      }
    }
    #endif
    


    b) In the endpoint ISR, scan the keys and put the keycode to the report.
    And put the report to the IN endpoint.
    Write your own KeyScan() routine :-)

    usbuser.c
    
    /*
     *  USB Endpoint 1 Event Callback
     *   Called automatically on USB Endpoint 1 Event
     *    Parameter:       event
     */
    
    void USB_EndPoint1 (DWORD event) {
    
      switch (event) {
        case USB_EVT_IN:
          KeyScan();
          USB_WriteEP(0x81, keyReport, sizeof(keyReport));
          break;
      }
    }
    

    In the KeyScan(), you don't need to consider make/break of keys - it is handled by the host side. Just put the keycode(s) to the keycode array on the report, for the key(s) currently pushed down. The keycode array can hold up to 6 keys - 6 key rollover. When more than 6 keys are pushed simultaneously, fill the keycode array with ErrorRollOver (0x01) When no key is pushed, clear the array with 0.

    Report format
    
    keyReport
     byte
      0   Modifier byte
      1   reserved - 0
      2   keycode array [0]
      3   keycode array [1]
      4   keycode array [2]
      5   keycode array [3]
      6   keycode array [4]
      7   keycode array [5]
    
    The bitmap of Modifier byte
     bit
      0   LEFT CTRL
      1   LEFT SHIFT
      2   LEFT ALT
      3   LEFT GUI
      4   RIGHT CTRL
      5   RIGHT SHIFT
      6   RIGHT ALT
      7   RIGHT GUI
    

    The keycodes are defined in this spec

    HID Usage Table 1.12
    www.usb.org/.../Hut1_12.pdf
    10 Keyboard/Keypad Page (0x07) (Hut1_12.pdf p54)

    When you succeed this try, the next step is,
    - send the key report just when key make/break occurs (Windows default)
    - support output report for LED indicators - CAPS, Num lock etc.

    Tsuneo

Children
  • Hi Tsuneo,

    By your instruction I already modify my source code.
    Please see modify function below.

    usbuser.c

    void USB_Configure_Event (void) {
      int i;
      if (USB_Configuration)
      {                  /* Check if USB is configured */
            for (i=0; i<8; i++)
                    KeyReport[i] = 0;
        USB_WriteEP(0x81, KeyReport, sizeof(KeyReport));
      }
    }
    
    void USB_EndPoint1 (DWORD event) {
      int i;
      if (KeyPress)
            saystr ("USB_ENDPoint1\n\r");
      switch (event) {
        case USB_EVT_IN :
              KeyScan ();
          USB_WriteEP(0x81, KeyReport, sizeof(KeyReport));
          if (KeyPress) // for debug on console
              {
                for (i=0; i<8; i++)
                    {
                      sayhex (KeyReport[i]);
                      saystr (" ");
                    }
                    saystr ("\n\r");
                    KeyPress = FALSE;
              }
              break;
      }
    }
    

    Output on hyperterminal is :

    USB_ENDPoint1
    00 00 04 00 00 00 00 00

    but notthing put on notepad. So my test solution is correct or not?

    and KeyScan function is :

    void KeyScan (void)
    {
      switch (Key)
      {
             case 'a' :
               KeyReport[2] = 4;
               break;
             case '1' :
               KeyReport[2] = 30;
               break;
      }
    
    }
    


    Key is gobal variable when I push button.

    and I wonder about GetInReport (), I set KeyPress = TRUE when I push button.

    void GetInReport (void)
    {
      InReport = 0x00;      /* Default All Input */
    
      if (KeyPress == TRUE)
      {
        InReport = 0x01;
      }
      else
      {
        InReport = 0x00;
      }
    }
    

    Thanks you,

    Nuttawit

  • Hi Tsuaneo,

    Now I just fixed this problem already. Cause by my setting HID_ReportDescriptor mistake.

    I debug by SourceUSB program , and setting HID_ReportDescriptor by HID descriptor tool , both program I get from your suggestion on keil forum :-).

    Thankyou very much for you help me in this forum and another forum that useful to fixed USB development problem.

    Happy new years,

    Nuttawit