Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Thread Closed: Issue successfully resolved

???
01/12/08 03:44
Read: times


 
#149341 - Modification for Atmel HID KB example
Responding to: ???'s previous message
Jae-yong Kim said:
I am developing device with HID keyboard functionality but not exactly keyboard. I have used code in ATMEL website but speed was too slow for my application.

Are you talking about this Atmel example?
"AT89C51 HID Keyboard demonstration software"
http://www.atmel.com/dyn/resou...-1_0_2.zip

but speed was too slow for my application.

What do you mean "too slow"?
Is it the transfer speed over USB?
Or the code execution speed?

As of the USB transfer,
The transfer speed is determined by the bInterval field of the endpoint descriptor. EP_INTERVAL_1 is assigned to it.
config.h
#define EP_INTERVAL_1    0x20

usb_kbd_enum.c
code struct  
{ struct usb_st_configuration_descriptor  cfg;
  struct usb_st_interface_descriptor      ifc;
  struct usb_st_hid_descriptor            hid ;
  struct usb_st_endpoint_descriptor       ep1 ;
  Uchar                                   rep[SIZE_OF_REPORT] ;
}
  usb_configuration =
  {
    { 9, CONFIGURATION, CONF_LENGTH, NB_INTERFACE, CONF_NB,
      CONF_INDEX, CONF_ATTRIBUTES, MAX_POWER},
    { 9, INTERFACE, INTERFACE_NB, ALTERNATE, NB_ENDPOINT, INTERFACE_CLASS,
      INTERFACE_SUB_CLASS, INTERFACE_PROTOCOL, INTERFACE_INDEX },
    { 9, HID, 0x1101, 8, 1, REPORT, 0x3B00 },
    { 7, ENDPOINT, ENDPOINT_NB_1, EP_ATTRIBUTES_1, EP_SIZE_1, EP_INTERVAL_1 },

The example sets it to 32 ms.
When the device is configured to full-speed (attach pull-up to D+), you can reduce EP_INTERVAL_1 to 1 (ms).
When configured to a low-speed (D- pull-up), the minimum is 10 ms.

As of the code execution,
I don't think this code is so slow.
The main loop executes two tasks, usb_task() and usb_kbd_task().
Both of tasks check the essential flags in early stage, not to consume the execution time uselessly.


It seems to send a character per a routine cycle

It doesn't send a character per a routine cycle.
It sends a report when the IN endpoint becomes empty by readout from host.

and send unnecessary 0.

This implementation sends single key per report. Other five key slots is filled with 0.

The six key slots on the key report is the de-fact standard. I recommend you to keep it as is. Surely, the USB HID spec doesn't define that it must be six. But, as the example on the HID spec uses six, most of HID keyboard implementation takes six.

If you dare to reduce it, reduce the report count on the report descriptor.
usb_kbd_enum.c
  usb_configuration =
  {
    ...
      0x19,0x00,          /* Usage Minimum (0)                 */
      0x29,101,           /* Usage Maximum (101)               */
      0x15,0x00,          /* Logical Minimum (0)               */
      0x25,101,           /* Logical Maximum (101)             */
      0x75,0x08,          /* Report Size (8)                   */
//      0x95,0x06,          /* Report Count (6)                  */
      0x95,0x01,          /* Report Count (1)                  */
      0x81,0x00,          /* Input (Data, Array)               */


Also does the actual reports.
usb_task.c
void usb_kbd_task (void)
{
  // if USB ready to transmit new data :
  //        - if last time = 0, nothing
  //        - if key pressed -> transmit key
  //        - if !key pressed -> transmit 0
  if ((!key_hit) && (usb_configuration_nb != 0) && !(Usb_suspend()))
  {
    kbd_test_hit();
    if (key_hit == TRUE)
    {
      Led_1_on();
      transmit_no_key = TRUE;
      Usb_select_ep(EP_KBD_IN);
      Usb_write_byte(0);
      Usb_write_byte(shift_key);
      Usb_write_byte(usb_key);
/*
      Usb_write_byte(0);     // cut off five key slots
      Usb_write_byte(0);
      Usb_write_byte(0);
      Usb_write_byte(0);
      Usb_write_byte(0);
*/
      Usb_set_tx_ready();
      return;
    }

    if (transmit_no_key)
    {
      key_hit = TRUE;
      transmit_no_key = FALSE;
      Usb_select_ep(EP_KBD_IN);
      Usb_write_byte(0);
      Usb_write_byte(0);
      Usb_write_byte(0);
/*
      Usb_write_byte(0);
      Usb_write_byte(0);
      Usb_write_byte(0);
      Usb_write_byte(0);
      Usb_write_byte(0);
*/
      Usb_set_tx_ready();
    }
  }
}


I wrote a brief summary on USB keyboard implementation here.
"USB HID KEYBOARD (Search a Programmer)" on SiLabs forum
http://www.cygnal.org/ubb/Forum9/HTML/001381.html

Tsuneo

List of 4 messages in thread
TopicAuthorDate
HID keyboard with AT89C5131            01/01/70 00:00      
   Foundations needed?            01/01/70 00:00      
   Modification for Atmel HID KB example            01/01/70 00:00      
      Thank you very much Tsuneo            01/01/70 00:00      

Back to Subject List