??? 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 |
Topic | Author | Date |
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 |