-
Notifications
You must be signed in to change notification settings - Fork 7
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
Add to arduino library manager #2
Comments
Hi, thanks for your suggestion. It clearly would be a useful integration but I wonder if it is meaningful in the current state. And I do not know if my use of the TIMER1 is compatible with all the Arduino libraries as I edit the registers directly. I' didn't use the Arduino for some time so I do not know if all Arduino libraries from the Library Manager could be imported at once without conflicts but I can see it as an expected feature from the point of view of users of the IDE. I can see that you started a project similar (https://github.com/Harvie/ps2dev) based on other implementations. Maybe we could join the effort :) |
I am not author of that code. It was some kind of library that was echoing through the internet forums, but was lacking proper repository and documentation. So i created the repository for it, added arduino metadata and made request so it can be added to arduino library manager. Also i added some basic documentation and examples on how to use it. I guess this will enable people to collaborate on improving it. There are still some issues with timing, so there's need to call delay(50) after each byte is sent. Hopefully i'll track it down, so this is not needed. I've just quickly peeked at your code and it seems to me that your code is bit more complex. Also ps2dev can only work as mouse/keyboard, but can't read data from keyboard.. While your library can do both directions... However in arduino library manager there are already some libraries which can read data from keyboard. But there is none, which can act as keyboard, that's why i started working on this... |
You can install as many libraries as you wish... IDE will just download it and put it in your libraries folder... But of course there might be conflicts when you
Arduino has some timer/interrupt abstraction layer, so if you can use that instead of directly modifiing registers, you should be OK. They have separate implementation for each board, but API is the same, so you can use that. If you need something special that is not implemented in arduino, you can use
These two implementations seem to be different and i don't see how we can merge them to single library. But i think we might synchronize the API, so people will be able to use both libraries interchangeably. But to be honest i like the ps2dev syntax better :-) Since it follows the arduino serial syntax. Note that there are multiple arduino serial implementations which can also be used interchangeably: Eg.: native serial, soft serial, usb serial. You can use any of them without changing the code... Both ps2dev and ps2-keyboard are low level libs. But if we have common API, we can start implementing some high level features in way that it will be able to run on top of both libs. So people will be able to chose if they want interrupt based (when they need more free cycles) or synchronous communication (for when they need more free timers) Eg.: scancode table which will enable us to send arbitrary string to be typed on computer screen without having to worry about stuff like make/break or shift for uppercase letters. |
Didn't know about that library, but it's great to see these kind of libraries easily available. Thanks for fulling the gap of simulating a keyboard then.
I was not talking about these delays but more about the delays in the library itself ( My implementation may seem a bit more complex because my use case was to be able to do these two tasks concurrently:
These was for integrating an iPad generating some data for old cash system in a store. Some keyboards are very touchy about PS/2 timings, if you do not respect absolutely the 40us, you're out and sometime you even have to power cycle the keyboard to make it work again !
Unfortunately, this api does not let you configure the timer as precisely as I would have needed.
I like that idea, we could tell people that synchronous library is more compatible with other libraries and should be used by default while interrupt based may not work with other libraries using the timer 1 (I do not know if there is a list for that) but could free up some CPU resources. I think the only blocking point then is the compatibility with other boards. I may look at the references, but I don't have other boards to actually test it. I'll try to do that when I have some time and I'll map my API to yours :)
A higher-level API would be greatly appreciated. I had contact with a few person wanting to use ps2-keyboard and they struggle to know how to use it to send actual keys to the computer. So would be definitely a good contribution :) |
Is 40us given by protocol specs? I was thinking about clocking whole thing bit faster for higher keystroke rates...
Yes i know. But there's some timing bug in ps2dev, which causes that there has to be aditional delay after each byte write() added separately by API user. I saw other people doing delay(100), but i tried delay(50) and it seems to work as well... But now that i know that ps2 timing is in microseconds i want to figure shortest possible delay and add it directly into the write() method, so people don't need to call the delay separately.
I struggle too... I've never learned scancodes before, but it turns out there are several scancode tables... I've found that this is how you press and release [0] button:
I was implementing numeric-only keyboard and all i needed was this scancode table:
|
I couldn't find "official" specifications unfortunately but I use this file: https://www.avrfreaks.net/sites/default/files/PS2%20Keyboard.pdf According to this paper, the clock period has to be between 30us and 50us. Some PS/2 controller may have some assumption about that (like, ok there is a falling edge, I still have this number of cycles to read the value) and may stop working with your device if you go faster. But test it, it could work, the host should use the edges to determine when reading the data line and if it can, it will follow your rate. Maybe through an option that enable that behaviour, to let users that are more concerned about compatibility with old computers using your library.
The parity bit is absolutely necessary. If it is wrong, the computer will discard your byte and will send you an error response. If your implementation does not write it, then the additional delays should not help because you still need to toggle the clock line for the host to read that parity bit. And there is a stop bit that is necessary as well (always 1). Maybe you could go as low as a bit more than 50 us ( And you have to consider that the host may want to speak to your device too. Right now,
There is actually two different code sets. For press-release 0, one is indeed 0x45 0xF0 0x45 while the other is 0x0B 0x8B. These tables are provided in the given paper. |
Thanks for interresting insights!
I've checked again and actually there's a code for parity bit, so this should be ok. I thought that i've read somewhere that parity is not supported, but it was probably different library.
Currently this is the last line of write() method:
Which one is preffered? (in terms of having better support across devices) |
Eh. Checked again and the write ends like this: // stop bit
gohi(_ps2data);
delayMicroseconds(CLKHALF);
golo(_ps2clk);
delayMicroseconds(CLKFULL);
gohi(_ps2clk);
delayMicroseconds(CLKHALF); //20 us
delayMicroseconds(50); Which means, there actually is 70 us delay with CLK pulled high, but it's stiil not enough... I guess something fishy is going on... |
I've changed that last line to But i've realized that the keyboard is not working until i plug real ps2 keyboard to that ps2 port. Once i type few letters on real keyboard, unplug it and plug arduino in, it starts to work magicaly. Is there some init sequence that keyboard has to send before it can start sending scancodes? It's combined mouse/keyboard (purple/green) ps2 port, so maybe it is used to switch between keyboard/mouse modes... |
I think keyboards only sends 0xAA when powering up. This command tells that the keyboard controller self-test was okay. But generally, the computer generally sends a few commands to set the initial state of the LEDs (numlock, ...) and other settings. If you do not acknowledge them, it may think the keyboard is not working and stop listening to the port. I do not know how this could fit in your sync API but your library should ack computer commands even if it does not provide a way to receive commands. |
I just read the commits from the past couple of days and it seems you just have implemented that acknowledgment, great :) Can you get rid of the real ps2 keyboard then ? |
What do you mean? It works so i was able to replace the ps2 keyboard with arduino. But had to increase the delay between sent bytes even further... BTW i was thinking that i can just use attachInterrupt() to catch computer requesting to send data on CLK and then handle all communication synchronously just like i do now. It would be sensible tradeoff between doing everything using interrupts and doing everything using delays... Also easily portable and compatible. But still better than having to check CLK every 10ms like i do now... Given that computer sending data to keyboard happens only occasionaly and takes just few ms... |
Please get listed at arduino, so this library can be easily installed using arduino library manager using few clicks. It's quite simple. Just add "library.properties" file to your repo and let them know:
https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ#how-can-i-add-my-library-to-library-manager
The text was updated successfully, but these errors were encountered: