PS/2 Keyboard Working with ATTINY and I2C
PS/2 Keyboard Working with ATTINY and I2C
Great news everyone:
The motley Discord X16 dev crew got the PS/2 keyboard working with the ATTINY861 and delivering keystrokes to the host / KERNAL over I2C at 8MHz!
This was the biggest obstacle in David's top issue list. I'd list all the folks involved, but I'm sure I'd miss a few so I'll let them chime in here. It was a fun international dev-and-debug-by-mob session over the last couple of days that got kicked into gear after enabling a clock stretching module so that the X16 can read from the YM2151 at 8MHz (special thanks to @Kevin Williams for installing the clock module and spending the time with us to solve the impedance mismatch between the official hardware and mine).
It's about to get real!
PS/2 Keyboard Working with ATTINY and I2C
I was a spectator.
These guys did a great job debugging. It's clear that having a couple of extra pairs of knowledgeable eyes on the current problems really helped here. They could message back and forth, share pictures of circuits and timings, throw questions into the air, and muse on possible issues. And make progress together.
THAT is how it's done. A lot can get done in a quiet dark room with nobody to distract you, but frankly, debugging is highly parallelizable. Or perhaps more generally, it seems that targeted, goal-driven planning is also best done this way, too.
It was a lot of fun to watch.
PS/2 Keyboard Working with ATTINY and I2C
There's still some testing to be done and discussion being had about what sort of functionalities to enable over this channel, but having the thing work at all is the big hurdle that's been in the way for a long long time.
I'm stoked, and being up with the west-coasters 'till the wee hours has been draining for me, but so worth it! I've only been a minor participant as an extra set of eyes where the PS/2 is concerned, but I'd like to name @Jeffrey and @Stefan as major collaborators on this.
PS/2 Keyboard Working with ATTINY and I2C
Hey guys,
I have a X16 compatible computer I've been working on as a hobby. I've been mostly working on my own VDP and kernal while awaiting the release of the X16. However since the release of the Vera code I went ahead and built my own 'vera' and can now boot the X16 kernal on my own hardware. If possible, I'd like to participate in testing the new keyboard code.
PS/2 Keyboard Working with ATTINY and I2C
Yes, that sounds useful. You'll need to join the X16 Discord thing; they're typing in realtime over there.
PS/2 Keyboard Working with ATTINY and I2C
On 7/8/2022 at 2:13 PM, rje said:
Yes, that sounds useful. You'll need to join the X16 Discord thing; they're typing in realtime over there.
I believe this is the current invite link: https://discord.gg/nS2PqEC
PS/2 Keyboard Working with ATTINY and I2C
Finally got around to recording a demo of the end-to-end I2C keyboard functionality, complete with weird key glitch ?. I've modified the firmware to light up the activity LED whenever the SMC's keyboard buffer is non-empty (hard to see in the video, unfortunately, but that's why the video is looking at my hands for the first half, so that you can see the activity light coming on with each key tap).
PS/2 Keyboard Working with ATTINY and I2C
Thank you for posting the video, its allways a thrill to see the progress...
Is there now a performance increase from offloading the keyboard buffer? If so would it be noticeable? Thank you
PS/2 Keyboard Working with ATTINY and I2C
On 7/11/2022 at 4:01 PM, Trax81 said:
Thank you for posting the video, its allways a thrill to see the progress...
Is there now a performance increase from offloading the keyboard buffer? If so would it be noticeable? Thank you
There is a performance increase. Is it noticeable? That depends.
Previously the kernel would release the clock on the PS/2 port and then poll to see if the keyboard's microcontroller started transmitting a key. The only way to determine that there was no key was to let the polling code time out. Every VSYNC, some time was spent polling for a key. If a key was ready, the kernel would then spend longer in VSYNC waiting for a complete scan code to arrive (11 bits per scan code byte, 1.5 bytes on average per key stroke, roughly 1-1.5 milliseconds extra spent in VSYNC when a key is ready). Because the kernel's poll timer was a simple busy loop, the higher the X16 was clocked, the less wall-clock time it spent polling and therefore the less time that the keyboard's microcontroller had to respond. There is no guaranteed minimum time that the microcontroller has to respond following release of the clock, and the vast majority of keyboards did not start sending keys before the poll timed out. This resulted in zero keys from the keyboard being received. Kevin Williams is the only person I know of who had a keyboard that actually worked at 8MHz - missing only about 25% of characters typed if you didn't type to fast. I solved the problem by repurposing an Arduino as an ultra-low latency keyboard buffer (if you're curious, I think I have a video showing a key smashing test at 8MHz using the keyboard buffer). Regardless, a dedicated Arduino keyboard buffer was not a scalable solution.
This new method doesn't need to poll, but still comes with some cost. It uses the serial I2C protocol that has to meet strict timing requirements. The kernel sends a request to the SMC to ask if a byte of a scan code is available and the SMC will respond during that I2C transaction. To be fair, I did have to add some code to slow down the kernel's I2C clocking because the SMC wasn't able to respond in the handful of microseconds it had between clock edges to respond. We need to tune that exact timing because I solved it by adding more time to every I2C clock phase, but I suspect all that is needed is more time between bytes. The individual bits are received by a hardware serial block that should be able to handle at least 1MHz. In this video the actual I2C speed is effectively about 150KHz-200KHz - ~10 times faster than PS/2 - with no polling timeout. If people are REALLY curious, I believe I have logic analyzer captures showing the I2C traffic between the host and SMC (it took a good bit of debug to figure out that things weren't working because the SMC just didn't have enough time to respond).
So.. is the performance increase noticeable? If you consider going from "could not doing anything requiring a keyboard" to "keyboard works as intended", then it's a huge performance increase. If we instead ask "can it get more done in a single frame than it could before", then yes it can, but it may only work out to 0.5 to maybe 2.0 milliseconds per second saved. It's definitely more than nothing; it may be below the threshold of perception. I'd have to put the scope on the hardware and get the per-frame timing of each to answer better.