Page 1 of 1

First key is not sent (hid keyboard)

Posted: Fri Mar 14, 2008 1:53 pm
by ThiefMaster
Hi,

i wrote this code (http://tm.privatepaste.com/801BrgfCB1) based on HIDKeys, but right after connecting it to USB, it only sends "ello\n" when pressing my button on PC0.
When i press it again it sends "Hello\n" as intended.
Do you have an idea what could be the reason for it?

Is there another way to send the same key two times except sending "key,0,key"?

PS: If you have any other suggestions how I can improve the code, please post them.

Posted: Sun Mar 16, 2008 11:58 pm
by christian
Try defining USB_INITIAL_DATATOKEN to USBPID_DATA1 in usbconfig.h. I have to verify this yet, but some people say that this is the correct start condition.

And no, there's no other way to send a key twice, as far as I know. I do the same in EasyLogger.

Posted: Mon Mar 17, 2008 12:17 am
by ThiefMaster
Hmm, USB_INITIAL_DATATOKEN is not used anywhere in the driver. :o

Btw, when sending data from my program, is it better to send it only when receiving USBRQ_HID_GET_REPORT or via usbSetInterrupt?

Posted: Mon Mar 17, 2008 3:13 am
by Grendel
Uhm, you may want to update your AVR_USB to a version >= 20070807..

* Release 2007-08-07

- More config options: USB_RX_USER_HOOK(), USB_INITIAL_DATATOKEN, USB_COUNT_SOF

Posted: Mon Mar 17, 2008 10:38 am
by christian
For a keyboard, you can ignore USBRQ_HID_GET_REPORT.

Posted: Thu Apr 17, 2008 11:36 am
by texmex
christian wrote:Try defining USB_INITIAL_DATATOKEN to USBPID_DATA1 in usbconfig.h. I have to verify this yet, but some people say that this is the correct start condition.

And no, there's no other way to send a key twice, as far as I know. I do the same in EasyLogger.


Hello!!

I'm trying the AVRUSB code with a similar HID application and i'm experiencing the same problem.

The first Keypress is not swallowed every time. But if i set USB_INITIAL_DATATOKEN to USBPID_DATA1 it fails every time plus sometimes the second key event too.

So the problem seems not to be caused by USB_INITIAL_DATATOKEN.


Kind regards,
Klaus

Posted: Fri Apr 18, 2008 1:35 pm
by christian
Interesting. I have tried both with EasyLogger. If I set USB_INITIAL_DATATOKEN to USBPID_DATA1, then it works as expected. If I set it to USBPID_DATA0, the first keystroke is missing.

Have you checked your firmware whether it generates the keystrokes correctly?

Posted: Fri Apr 18, 2008 3:00 pm
by texmex
christian wrote:Interesting. I have tried both with EasyLogger. If I set USB_INITIAL_DATATOKEN to USBPID_DATA1, then it works as expected. If I set it to USBPID_DATA0, the first keystroke is missing.

Have you checked your firmware whether it generates the keystrokes correctly?


Unfortunately i don't know how it should be correct.

After

Code: Select all

   hardwareInit();
   usbInit();
   sei();


And before the main event loop i've done this now as a workaround:

Code: Select all

{...}
   buildReport( 0 );
   usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
{...}
   reportBuffer[0]= MOD_SHIFT_LEFT;
   reportBuffer[1]= 0;
   usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
{...}
   buildReport( 0 );
   usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
{...}


I've discovered also that i have to issue a

Code: Select all

  buildReport( 0 );
   usbSetInterrupt(reportBuffer, sizeof(reportBuffer));

between each (simulated) keystroke. Otherwise some keystrokes are swallowed every now and then too.
I don't know whether this is the expected behaviour.

Maybe everything is a timing problem? Since it happens only occasionally?

Thank you for your patience with my half knowledge :-).


Kind regards,
Klaus

Posted: Fri Apr 18, 2008 3:24 pm
by christian
Do you check whether the interrupt buffer is free with usbInterruptIsReady() before you use usbSetInterrupt()? If not, this is probably the cause of the problem. See EasyLogger for details.

Posted: Fri Apr 18, 2008 5:05 pm
by texmex
christian wrote:Do you check whether the interrupt buffer is free with usbInterruptIsReady() before you use usbSetInterrupt()? If not, this is probably the cause of the problem. See EasyLogger for details.


Yes of course. This is my complete testing main loop:

Code: Select all

   for(;;)
     {  /* main event loop */
        wdt_reset();
        usbPoll();
        if(pgm_read_byte(&teststring[stringpointer]) != 0 && usbInterruptIsReady())
          {
             buildReport( pgm_read_byte(&teststring[stringpointer++]) );
             usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
             while ( ! usbInterruptIsReady() )
               {
                  wdt_reset();
                  usbPoll();
               }
             buildReport( 0 );
             usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
          }
     }

Posted: Fri Apr 18, 2008 8:53 pm
by christian
Although the main loop looks a bit weird, it should work.

Maybe the host side driver does not accept keystrokes shortly after the device was connected (just a wild guess). Did you try to add a delay before sending the first keystroke, e.g. iterate the main loop for one second before you send the first interrupt report?

Posted: Thu May 01, 2008 12:58 am
by texmex
christian wrote:Although the main loop looks a bit weird, it should work.

Maybe the host side driver does not accept keystrokes shortly after the device was connected (just a wild guess). Did you try to add a delay before sending the first keystroke, e.g. iterate the main loop for one second before you send the first interrupt report?


Yes, i've tried this but it doesn't work. I have to send a dummy keystroke (shift for example) at first.

It's no problem but a bit strange :-).


Kind regards,
Klaus