speed up HID keyboard reporting rate

cancel
Showing results for 
Search instead for 
Did you mean: 

speed up HID keyboard reporting rate

778 Views
sw_vw
Contributor II

Hi,

I'm using the freescale USB stack - hid keyboard  in one of our project(using MKL25). during the test , the reporting rate is some slow,  can only achieve about 100 keys /second. when we try to report faster, some keys will lost. so is there a way to speed up the reporting rate, say, to make it report about 300 ~500 keys/second. is it possible? according to USB2.0 spec, the reporting rate should be 1000Hz, but during our test, the FSL usb stack can only be about 60Hz. how to improve it?

thanks a lot

SW

Labels (1)
Tags (1)
0 Kudos
6 Replies

241 Views
DerekLau
Contributor IV

In "usb_descriptor.c" file

uint_8 USB_DESC_CONST g_config_descriptor[CONFIG_DESC_SIZE] =
{
   CONFIG_ONLY_DESC_SIZE,  /*  Configuration Descriptor Size - always 9 bytes*/
   .......

   /*Endpoint descriptor */
   ENDP_ONLY_DESC_SIZE,
   USB_ENDPOINT_DESCRIPTOR,
   HID_ENDPOINT|(USB_SEND << 7),
   USB_INTERRUPT_PIPE,
   HID_ENDPOINT_PACKET_SIZE, 0x00,
   0x0A
};

The above 0x0A is the endpoint report rate. Change it from 0x0A (ms) to 0x01 (ms).

241 Views
sw_vw
Contributor II

Thank you, DereLau,

yes. after following your instruction, the reporting rate now is faster.

anyway, currently we put a simple delay some longer than 1ms after function USB_Class_HID_Send_Data(....), otherwise some keys will lost. is there a way to get status that the last packet was completed send out so we can start the next sending as soon as possible, and we can make sure the data already send out? and, where is the the best location to reset that status?

to put the question some simple, may i know that in which sub routine, we can:

1) where to reset the completed sending flag

2) where to set the completed sending flag

so we can  have the best data through out?

best regards,

sw

.

0 Kudos

241 Views
dspNeil
Contributor III

SW,

The USB stack has features that you can utilize to do exactly as you're intending. First, you should understand that the stack itself queues data packets to be sent. You can queue at most MAX_QUEUE_ELEMS of packets. By default, this macro is set to 4 in usb_hid.h. As DerekLau suggested, you can repeatedly call USB_Class_HID_Send_Data() until it does not return USB_OK. At that point, you know the last packet you tried did not send, so you could retry it.

But do realize that just because that function returns USB_OK, that does not mean that the packet has been sent. It simply means that it has been accepted by the stack to be queued for sending, and it will be sent when it is its turn in the FIFO. So keep in mind that the stack still has a pointer to your data packet, and it is NOT OK for you to reuse that data buffer until the stack has sent the data.

It is very important that you keep track of the memory that you have passed to the stack, and make sure that you do not reuse the buffer until your application receives the event callback USB_APP_SEND_COMPLETE. Once you have received that callback event, you can then reuse the buffer. This event will be sent to the callback function that you registered when you called USB_Class_HID_Init(). In the stack examples, this callback function is often called USB_App_Callback.

My guess would be that you are reusing the same buffer over and over to queue data to the stack, thus you are overwriting data before it is sent, giving the impression that keys are "lost".

Also, it is a very bad idea to queue data to the stack in the app callback (because it is essentially an interrupt routine). It would be best to set a flag in this callback to tell your main routine that a buffer is free, and you can send more data. Alternatively, you could create a simple FIFO that tracks what buffers have been sent to the stack, and what buffers the stack has sent.

241 Views
chuckh
Contributor III

How does this approach apply to receiving using _usb_device_recv_data()?  Will that also fire an event callback?

0 Kudos

241 Views
DerekLau
Contributor IV

To avoid data lost, you can check the result of USB_Class_HID_Send_Data.

Example of implementation:

  do

           {

            result = USB_Class_HID_Send_Data(CONTROLLER_ID,HID_ENDPOINT,rpt_buf,BUFF_SIZE);

           }

          while (result != USB_OK);

0 Kudos

241 Views
sw_vw
Contributor II

Dear DerekLau,

we once tried this before. during our test,

  do

           {

            result = USB_Class_HID_Send_Data(CONTROLLER_ID,HID_ENDPOINT,rpt_buf,BUFF_SIZE);

           }

          while (result != USB_OK);


the val result will always show USB_OK after USB_Class_HID_Send_Data (...)  when we test the keyboard hid example. so if we have longer series keys to be report, by this way, some keys will lost

0 Kudos