First key is not sent (hid keyboard)

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
ThiefMaster
Posts: 5
Joined: Thu Mar 13, 2008 5:17 pm
Contact:

First key is not sent (hid keyboard)

Post by ThiefMaster » Fri Mar 14, 2008 1:53 pm

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.

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Sun Mar 16, 2008 11:58 pm

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.

ThiefMaster
Posts: 5
Joined: Thu Mar 13, 2008 5:17 pm
Contact:

Post by ThiefMaster » Mon Mar 17, 2008 12:17 am

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?

Grendel
Rank 4
Rank 4
Posts: 167
Joined: Sat Dec 16, 2006 9:53 pm
Location: Oregon, USA
Contact:

Post by Grendel » Mon Mar 17, 2008 3:13 am

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

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Mon Mar 17, 2008 10:38 am

For a keyboard, you can ignore USBRQ_HID_GET_REPORT.

texmex

Post by texmex » Thu Apr 17, 2008 11:36 am

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

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Fri Apr 18, 2008 1:35 pm

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?

texmex

Post by texmex » Fri Apr 18, 2008 3:00 pm

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

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Fri Apr 18, 2008 3:24 pm

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.

texmex

Post by texmex » Fri Apr 18, 2008 5:05 pm

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));
          }
     }

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Post by christian » Fri Apr 18, 2008 8:53 pm

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?

texmex

Post by texmex » Thu May 01, 2008 12:58 am

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

Post Reply