Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyboard not recognized at boot / BIOS #34

Open
NicoHood opened this issue May 2, 2015 · 57 comments
Open

Keyboard not recognized at boot / BIOS #34

NicoHood opened this issue May 2, 2015 · 57 comments

Comments

@NicoHood
Copy link
Owner

NicoHood commented May 2, 2015

The keyboard has to be a special boot keyboard with a standard descriptor. I heard it is possible with Teensy. More information can be found in the official USB docs.

http://www.usb.org/developers/hidpage/HID1_11.pdf
Seite 89 im PDF, 79 auf dem Blatt. Geht hier um Boot compatible HID devices.
Mit USB kann man ein Keyboard auf verschiedene Arten beschreiben. Standardmäßig 6 Modifier (strg, alt), 1 reserved und 6 keys. Das nutzt auch der Arduino. 

Auf seite 85/75 steht auch etwas feines. Das USB Gerät muss einen Boot Modus unterstützen, bzw sich als solches ausweisen.
Desweiteren steht hier, dass es mit dem Teensy wohl gehen sollte:
http://stackoverflow.com/questions/12682429/generic-keyboard-emulation-using-arduino-leonardo 
@RingoM
Copy link

RingoM commented May 2, 2015

Hey Nico,

Have a look at Appendix E of the hid1_11 pdf you've linked to, there's an example:

The sample device is a low-speed 105-key keyboard with an integrated pointing
device. This device could be built using just one interface. However, two are used
in this example so the device can support the boot protocol. As a result there are
two Interface, Endpoint, HID and Report descriptors for this device.

@NicoHood
Copy link
Owner Author

NicoHood commented May 2, 2015

Sure, if I ever have time to do that. I didnt even had time to review your PR. I just add issues if things like that come to my mind. I also did not translate my german notes I wrote someone as email.

As always: If you have a fix, open a PR.

@RingoM
Copy link

RingoM commented May 2, 2015

Haha, stupid 24 hour days ;-)

@NicoHood
Copy link
Owner Author

NicoHood commented May 2, 2015

I have to admit that I am working on the IRLremote instead :D totally worth it. Fixes will come, sooner or later.

@bam80
Copy link

bam80 commented Sep 18, 2015

The feature would be very great!
Hope you will have time for this @NicoHood
Thanks for your work

@NicoHood
Copy link
Owner Author

Does the teensy work at boot? has anyone tested this? I dont know what is required for a boot keyboard. If the teensy works at boot we could try to search for the difference in the code and fix it.

The teensy keyboard is currently in the dev repo, but I dont think this works like this. I think the hid interface descriptor will be different then.

@bam80
Copy link

bam80 commented Sep 18, 2015

In the Teensy USB Keyboard example it's clearly said:
"This code also supports the keyboard "boot protocol" ":
https://www.pjrc.com/teensy/usb_keyboard.html

I don't have Teensy to check it though

@NicoHood
Copy link
Owner Author

http://community.silabs.com/t5/8-bit-MCU/USB-HID-class-Difference-between-report-protocol-and-boot/td-p/78797

I do not think that this will work with our current setup. But it should be possible to implement this. It requires a single HID Interface with just a keyboard and with no report ID. This differs from the current implementation. It would require a new endpoint to be used and some API changes. Those changes are similar to what would be needed for raw HID + The interface descriptor mentioned in the link above.

http://www.avrfreaks.net/forum/avr-all-firmware-usb-and-pc-bootbios
https://github.com/PaulStoffregen/cores/blob/master/teensy3/usb_desc.c#L572-L574
www.usb.org/developers/hidpage/HID1_11.pdf
Page 59 and 62

@NicoHood
Copy link
Owner Author

Got it working under my Bios. Feel free to test it. You need to install the latest dev version of HID Project and the patched IDE with .alinkage. See the wiki on installing instructions.

Then you need to outcomment this line in HID-Project.h to enable the boot keyboard API. Working for improved keyboard and Teensy Keyboard as well.

Booting took a bit longer than normal for me.

The keyboard will not work under the OS currently, only via BIOS. With further work this can also be accomplished.

Fix commit:
0e29749

@NicoHood
Copy link
Owner Author

@bam80 @RingoM Now enabled by default! There were a few bugs that now should be removed. Booting is fast now and it automatically switched between boot protocol and normal protocol.

You can deactivate this function now, if it causes problems. This was only tested under linux with a newer bios(UEFI). It could be possible that it does not work with older BIOS, because I did not implement every required function. Thats enough at least for my bios. If it doesnt work for you, let me know and I will patch it. Unless it works, I wont add more "useless" code.

The mouse wont be supported here. You can only have Mouse OR Keyboard. Or you need a 2nd interface which I will not implement since no bios needs a mouse at all if you are serious.
Mouse is also supported, but deactivated by default. My Bios doesnt support a mouse, I need help here.

3ed2577

@bam80
Copy link

bam80 commented Sep 19, 2015

Thank you @NicoHood, it's awesome!
I've got my Arduino UNO recently and just need to get used to it. Then I'll try your patches definitely and report if they work.
Thank you again and keep up such a good work!

@ghostcomms
Copy link

@NicoHood please how do I add the boot USB protocol to the arduino ide from dev 2.4 I cannot find any.zip files and I'm kind of new to this thank you for your time and effort on this matter

@NicoHood
Copy link
Owner Author

It is enabled by default. Just install the library as described in the wiki and use the keyboard API.

(maybe in further versions it will be disabled again, I need to have a look at this once again. RawHID caused this some problems).

@ghostcomms
Copy link

@NicoHood thank you for the reply I'm not sure where to find the library as I can't see a folder in 2.4 code do I download and install 2.2 then add files I have read the wiki and do not u derstand what to do sorry to pester you

@NicoHood
Copy link
Owner Author

https://github.com/NicoHood/HID/tree/dev_2_4
on the right side click download .zip file.

And then read the wiki on how to install this zip file. the wiki will link to the arduino page. basically you open the ide, search for libraries and select install via zip file. Or you put the file manually in your arduino/libraries folder.

https://github.com/NicoHood/HID/wiki/Installation

@ghostcomms
Copy link

Thank you for your help I've now Dow loaded the .zip and will install when
I am home will the boot protocol work with keboardpress. Keyboardrelease
and lastly what library do I have to #include to have the boot keyboard
function work I am very gratefull for the help also do you know if this
library works on Mac bootscreen? EFI for example?
On 25 Sep 2015 14:20, "Nico" [email protected] wrote:

https://github.com/NicoHood/HID/tree/dev_2_4
on the right side click download .zip file.

And then read the wiki on how to install this zip file. the wiki will link
to the arduino page. basically you open the ide, search for libraries and
select install via zip file. Or you put the file manually in your
arduino/libraries folder.


Reply to this email directly or view it on GitHub
#34 (comment).

@NicoHood
Copy link
Owner Author

Just include HID-Project.h and you can use the Keyboard API. Try the examples.

This is not a support forum, sorry. If you have further technical questions/bugs please write it here. Otherwise contact me via PGP mail: www.nicohood.de for instructions.

@ghostcomms
Copy link

Ok I will try this thank you very much for the help I will email you if I
need further help thanks again
On 25 Sep 2015 15:16, "Nico" [email protected] wrote:

Just include HID-Project.h and you can use the Keyboard API. Try the
examples.

This is not a support forum, sorry. If you have further technical
questions/bugs please write it here. Otherwise contact me via PGP mail:
www.nicohood.de for instructions.


Reply to this email directly or view it on GitHub
#34 (comment).

@NicoHood
Copy link
Owner Author

NicoHood commented Oct 9, 2015

Ignore this...
screenshot from 2015-10-09 19 01 35

@NicoHood
Copy link
Owner Author

Current dev version requires this PR:
arduino/Arduino#3948

A real bootkeyboard is now implemented. Multireport Keyboard is still supported, but not as boot compatible. I wanted to a) keep it simple, and b) to the official specs. Everything else would just work half of the time.

Please test the BootKeyboard sketch. For me the Arduino detects the boot mode (led lights) but not when starting back the OS. Not sure if this is a feature/ intended of linux or just a lock of the HID implementation. Because the idle mode and getreport and getprotocol is not supported yet which normally is essential to work as bios. However it works more or less. No further testing has been done. I also dont need this feature myself so I dont really care much more if noone is willing to test.

@NicoHood
Copy link
Owner Author

Mouse needs further testing. At the moment it leaves out the wheel data in bios mode. However it does not recognize when it comes back to report mode (for keyboard at least). This means after a reboot the mouse (wheel) might not work at all.

@bam80
Copy link

bam80 commented Oct 11, 2015

Hi Nico, you said:

it automatically switched between boot protocol and normal protocol

What did you mean here?
Is it mean that I can always use BootKeyboard class and it will switch internally between normal Keyboard and Bootkeyboard?

@NicoHood
Copy link
Owner Author

This was for the implementation before.

There is a variable called "protocol" in the BootKeyboard class. This indicated if the USB Keyboard is in bios mode or not. However it does currently not reset back to normal mode (currently). This is no problem now, because the report is always the same anyways. Before where i mashed up all other devices as well (consumer etc inside a multi report) this would have caused problems.

I think I need to reset the variable on reenumeration. Then people can detect when they are in bios mode or even if a pc reboots or so. However for the functionality NOW it doesnt matter anymore.

Clearer? Sorry if thats all mashed up. When the time is ready i try to make the wiki as clear as i can.

@bam80
Copy link

bam80 commented Oct 11, 2015

Thank you but it isn't too clearer actually.
If "protocol" variable does currently not reset back to normal mode, how could I know then what class to use: BootKeyboard or Keyboard? As I understand I must choose the right one to make keyboard work in current environment.
Could you update BootKeyboard sketch so that is work both in bios mode and OS mode, or it's impossible with current implementation?

@NicoHood
Copy link
Owner Author

Keyboard has no bios compatiblity.

BootKeyboard has. Bootkeyboard detects when the usb host changes to bios/boot mode. However there is no actual difference in sending the reports to the host, so that information is useless somehow. However the proper implementation would be to know the state (bios or not) because the idea behind this is to implement a whole different device after bios finished (such as an nkro keyboard).

The current sketch works in both modes, it always acts the same. It detects if the host switches to bios mode but not back (at last for linux, linux seems to not send a signal). The detection can be made visible via the led. But as said it doesnt switch back. But its just a variable, the keyboard will continue to work anyways.

Maybe you should look at the bootkeyboard source if its still unclear. Hm...

This changes the protocol variable (which is almost useless but should indicate the device to change to pure bios mode if it uses other stuff in non bios mode). However this only works from report -> bios mode and not back (yet).

protocol = setup.wValueL;

@bam80
Copy link

bam80 commented Oct 11, 2015

Ah, this is what I've asked before: if I could use BootKeyboard class all the way for now.
Just didn't catch it from your previous response, thank you.

@NicoHood
Copy link
Owner Author

Renewed the whole Keyboard API. I havent tested the delta between the new version but it should possibly be smaller. In any case its more clear now and should work better.

The main reason why I did this is that you cannot press all keys via write() before (like volume up/down). Instead of inputting a 2 byte value I just improved it the correct way.

AddKeycode etc is now just renamed, the option is still there.

Feedback appreciated. More Key definitions will follow. Consumer Keys and System key support will follow (yes for keyboard, in the same report). But only for linux, because windows sucks. Meaning you can integrate 3 device functions into a single device =) This is especially useful for u2 Uno devices combined with a raspi for example. But it also gives less API overhead for new devices and their descriptors.
1a676a2

@NicoHood
Copy link
Owner Author

NicoHood commented Nov 6, 2015

Closing this, as it is implemented now. If it doesnt work, let me know.

@NicoHood NicoHood reopened this Mar 16, 2016
@NicoHood
Copy link
Owner Author

Can you please try to: plug in the arduino when the bios is loading. Like a normal boot, not a reboot. And then also test a reboot. Cause if the usb state is changing a lot (reboots) the arduino could possibly get confused and fail.

But actually I have no idea whats going on. I'd have to debug this and get such a PC/bios myself. And to be honest I currently have not the time to debug it. You may want to contact me on tox and kindly ask if i have time to help you in chat.

@justinj0001
Copy link

Hi,
I've just double checked it, running purely on the example BootKeyboard sketch (Just changing KEY_ENTER to '1' so I could see if it was typing) and when plugged in during BIOS, or when powering on from scratch or rebooting the LED does not light indicating it's in boot mode. Shorting Pin2>GND flashes the TX once (As per my previous sketches), does not send any keystrokes and does not attempt to send again. When plugging into a running machine the LED does not light (As expected) and shorting Pin2>GND enters a string of 1's. Is there any way to force the sketch into boot mode? I'm willing to help diagnose the issue (I have another micro to use when this one is in deployment), but in this circumstance I just need a quick fix and keeping the Arduino in boot mode should be that quick fix.

@NicoHood
Copy link
Owner Author

I dont think that this will change much. You can set it here:
https://github.com/NicoHood/HID/blob/master/src/SingleReport/BootKeyboard.cpp#L102

The definition is in the pluggable hid core (of the ide) i think. To really debug this we need to a) read the usb specs about boot compatible devices again (not all required functions are implemented). And b) we need to add debug output to see what is going on. What does the host request etc (with serial1). This is complex.

@justinj0001
Copy link

Well it does force it into boot mode (LED on) when connected to a running computer. The same computer in BIOS does not seem to be enumerating it as the LED fails to light.

@NicoHood
Copy link
Owner Author

you can add a blink without delay inside the loop for another led/pin.
If it does not blink then the sketch crashed. Or it hangs in an interrupt.
It would be nice to know what happens if you then boot the OS.

Also the bios could have problems with the 500ma spec. You might want to change that (somewhere in the arduino usb core, usbdesc.h i think).

As I said, contact me in tox for faster support (tomorrow again)

@justinj0001
Copy link

Added a blink code in and in BIOS the blinking continues so the sketch isn't crashing. The TX light still flashes once only after shorting and that's all.
I've added you to Tox but with timezone difference it might be a bit hard.

@renjithg1
Copy link

@NicoHood : I am not sure still you are in track of this issue. Hopefully you are. I am using learnado with HID-Project 2.4.4. I don't have any issues with either BIOS or OS.
My problem while emulating keyboard for booting to BIOS from scratch or after a reboot. Something similar as follows.

void setup() {
BootKeyboard.begin();
}

void loop() {

BootKeyboard.write(KeyboardKeycode(KEY_F2));
delay(200);
}
Initially I thought it would be the power problem in the USB port during the early boot. So I tried connecting an external power for my Learnado. Still it is not sending the F2 key strokes during the initial system boot. Any possible clues I can look into? Thanks

@NicoHood
Copy link
Owner Author

So you are saying that you can use left/right inside the bios to switch pages, but are unable to enter setup? Have you verified the f2 key works properly when inside the os?

I'd try to press and release the key with some delay in between each press.

@renjithg1
Copy link

renjithg1 commented Oct 12, 2017

Thanks for looking into this.

So you are saying that you can use left/right inside the bios to switch pages, but are unable to enter setup?

Yes. That is correct. (f3, F4 every keys are working inside BIOS)

Have you verified the f2 key works properly when inside the OS?

Yes. F2 is working. I have verified with a KB tester application.

Today I did some more experiment after I paused in the pre-boot screen. (Attached the screen).
I have configured a button in my sketch which when pressed will send back a serial data to serial1. When I read the serial data while in the pre-boot screen, I always get "NON_BOOT_PROTOCOL". Where as I get HID_BOOT_PROTOCOL after I boot to BIOS by pressing F2 with a REAL keyboard.

preboot_screen

void loop() {
int buttonState = digitalRead(buttonPin);
if (buttonState == HIGH)
{
if (BootKeyboard.getProtocol() == HID_BOOT_PROTOCOL)
Serial1.write("HID_BOOT_PROTOCOL\n");
else
Serial1.write("NON_BOOT_PROTOCOL\n");
}

Thanks.

@NicoHood
Copy link
Owner Author

Does the keyboard work after you entered setup?
The bios possibly does not like your arduino.

@renjithg1
Copy link

renjithg1 commented Oct 12, 2017

Does the keyboard work after you entered setup?

I hope you mean setup(). - Yes F2 works in setup().

The bios possibly does not like your arduino.

My problem is ONLY with the pre-boot screen. I tried with a another arduino -learnado. Still no hope :(

@renjithg1
Copy link

I mean once it reaches BIOS it returns the protocol as HID_BOOT_PROTOCOL. But in the early/pre boot it is recognizing arduino as normal (HID_REPORT_PROTOCOL).

@NicoHood
Copy link
Owner Author

no i mean if you tried the arduino in the bios setup, after you pressed f2. Check if the arrow keys work etc. If not, I dont know whats the problem of your bios. I've tested the fujitsu laptop bios which is based on infineon. Which bios vendor is your bios from? American megatrends? phoenix? infineon? how old is your pc? are you booting with csm enabled or disabled?

I currently have no hardware to even retest on my own system, but it must be something in between bios and keyboard.

@justinj0001
Copy link

Sounds a lot like the issue I was having, I tried hours and hours to get it to work and couldn't. In the end I tried a teensy and it's built in keyboard function and it worked perfectly. I wish I had of tried it sooner!
From memory I had to downgrade the teensy keyboard library to the older version, I can't remember if that was for an additional function that was obsolete in the latest version or to do with the boot protocol mode being removed or changed in the latest version. So if you want to save yourself a heap of time, give a teensy a try.

@renjithg1
Copy link

Some old version - phoenix. I tried with few other machines too with infineon. Still i could see the issue.

I have another observation, hope it will narrow down to the possible root-cause.

a) If I boot my machine from a complete shutdown - F2 or any other keys are working in the PRE-BOOT screen.

b) But a reboot from OS/BIOS - The F2/any other keys are not working in PRE-BOOT screen.

So I believe the problem is with the reboot procedure. Appreciate if you can give me some clues or the area in the library I can have a try. Thanks

@renjithg1
Copy link

Another observation in LEDs

Booting from shutdown - Rx LED blinks twice
Booting from a reboot - Rx LED blinks only once

Thanks

@NicoHood
Copy link
Owner Author

Is it a cold or warm reboot? A cold reboot turns off usb power for a short time.
Its definitely and arduino bug, maybe the device does not reset properly. I currently have no idea how to fix it, I'd need to debug it. :/

@d33pk3rn3l
Copy link

Hallo NicoHood! I have pretty much the same problem, although it doesn't matter if I reboot cold/warm or from a complete shutdown (Stromlos). I have a couple of HP-Bios to set up (130 to be exact).

I tried it with your example code, since I just wanted to test possibilities... KEY_ENTER/_F10/_DOWN_ARROW are all not responding. TX blinks once when Pin 2 is shorted. Doesn't blink again when 2 is kept shorted. PinLED never turns on. Behavior in MacOS/Windows as programmed/expected. Any Ideas?

/*
  Copyright (c) 2014-2015 NicoHood
  See the readme for credit to other people.
  BootKeyboard example
  Shows that keyboard works even in bios.
  Led indicats if we are in bios.
  See HID Project documentation for more information.
  https://github.com/NicoHood/HID/wiki/Keyboard-API#boot-keyboard
*/

#include "HID-Project.h"

const int pinLed = LED_BUILTIN;
const int pinButton = 2;

void setup() {
  pinMode(pinLed, OUTPUT);
  pinMode(pinButton, INPUT_PULLUP);

  // Sends a clean report to the host. This is important on any Arduino type.
  BootKeyboard.begin();
}


void loop() {
  // Light led if keyboard uses the boot protocol (normally while in bios)
  // Keep in mind that on a 16u2 and Arduino Micro HIGH and LOW for TX/RX Leds are inverted.
  if (BootKeyboard.getProtocol() == HID_BOOT_PROTOCOL)
    digitalWrite(pinLed, HIGH);
  else
    digitalWrite(pinLed, LOW);

  // Trigger caps lock manually via button
  if (!digitalRead(pinButton)) {
    BootKeyboard.write(KEY_DOWN_ARROW);

    // Simple debounce
    delay(300);
  }
}

I never tried forcing it in HID_BOOT_PROTOCOL...

@NicoHood
Copy link
Owner Author

As an alternative you could try LUFA. I built an API around that, please checkout the example here:
https://github.com/NicoHood/avr/blob/master/lib/USB_KEYBOARD/examples/keyboard/keyboard.cpp

The code is provided "as is" I did not create any docs yet. Feel free to check it out, but you have to figure out how everything is done yourself.

@wilbolinux
Copy link

hi BenediktRPI ! Reading about your post to use an arduino to set the Bios. Which arduino do you use ? Best regards. Wilbo

@gdsports
Copy link
Contributor

My attempt at fixing bootkeyboard for SAMD boards.

https://github.com/gdsports/HID/tree/bootkeyboard/examples/Keyboard/BootKeyboard

@NicoHood
Copy link
Owner Author

To everyone who still has problems with keyboard in bios:
Checkout this comment #305 (comment) where someone is happy to fix the issue, if he can get his hands on a not working device. Maybe someone of you can help here?

@NicoHood
Copy link
Owner Author

You can also try this:
#225 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants