rampa069 / ZX-ESPectrum

A ZX spectrum 48K/128K emulator running on ESP32 with bitluni ESP32 VGA Board (also in TTG VGA32)
153 stars 46 forks source link

Problem with PS/2 keyboard #10

Closed dcrespo3d closed 4 years ago

dcrespo3d commented 4 years ago

Hello, after some time I have been able to get a PS/2 Keyboard. I have carefully connected it to the ESP32, double-checking all connections, and still can't get it to work. When I press keys, nothing happens.

All I get from the keyboard is value 170 (0xAA) (through logging in PS2Kbd.cpp). I am also printing start, parity and stop bits so I'm reasonably sure the value is good.

The info at https://wiki.osdev.org/PS/2_Keyboard states that 0xAA means "Self-test passed" and is sent by keyboard after power up.

But my keyboard stays sending the same byte forever.

I have tested the keyboard against an old laptop and works perfectly.

Reading this other info http://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Keyboard%20Protocol.htm at the end of the file, there is an initialization sequence.

Should we perform any initialization on the keyboard?

I have checked the PS/2 code on which yours is based https://github.com/michalhol/ps2kbdlib/tree/master/PS2Kbd/src And it seems to SEND data to the keyboard, which code at this repo doesnt (other than setting CLK and DATA lines to 1 at kb_begin).

Does your keyboard work freshly from power-up?

dcrespo3d commented 4 years ago

And thanks for this great project, again!

dcrespo3d commented 4 years ago

Hello, I have done much more research on this subject and I'm closing the issue, but I think some of the things I have learned may be useful to others, so I'm writing them here.

First of all, the ESP32's logic I/O levels are 3.3V instead of 5V needed for DATA and CLK for the PS/2 Keyboard, so I have added a bidirectional MOSFET-based voltage level converter to my breadboard. (In practice, two are needed, one for DATA signal and other for CLK signal). I have used this circuit:

https://www.hobbytronics.co.uk/mosfet-voltage-level-converter

It's not too complicated, for each converter just two 10K resistors and one 2N7000 MOSFET transistor.

Here is my small breadboard with an ESP32 and the logic level converters in place:

photo_2020-08-09_11-53-35

Second: the problem was with the concrete keyboard model I am using. I have tried with another PS/2 keyboard and worked seamlessly with the code from this repo.

But I wanted this emulator to work with this concrete model of keyboard:

https://www.amazon.es/Perixx-PERIBOARD-409-Teclado-Inglés-QWERTY/dp/B00JV08TIA

My project is to fit an ESP32 INSIDE the keyboard, add connectors for power, sound and VGA, and voila! A full-fledged Spectrum emulator within the keyboard, much like a real spectrum, ready to power via USB and connect via VGA to a monitor.

But first, I need to make that nasty keyboard to work...

I have tested this Arduino library for PS/2 keyboard by Paul Carpenter:

https://github.com/techpaul/PS2KeyAdvanced

This library has 3 examples: simple, advanced and LCD.

Well the difference between the simple and advanced examples is that the advanced example sends an ECHO command to the keyboard. This seem to initialize the keyboard, and it keeps that way until power down.

Then I tried to flash the advanced example, try it (reading keyboard events from Serial) and then, without powering down, flash the ZX-ESPectrum project, and now it worked seamlessly. All keys working!

So I have fixed it in my own fork of this repo, but I'm not doing a pull request as this fixes just this particular model of keyboard which I think is not behaving correctly.

What I do in my fix:

After that, the keyboard keeps initialized until power down, so after that I perform the usual initialization of PS2Kbd.cpp at kb_begin.

jorgefuertes commented 4 years ago

My old IBM PS/2 keyboard works perfectly connected straight to the ESP pins, no pull-up resistors required. Unfortunately I haven't any other PS/2 keyboard to test.

jorgefuertes commented 4 years ago

May it just happens with USB downgradeable keyboards? I mean, that keyboards with a circuitry that detects if they are connected to an USB bus or to a PS/2 port, and only then they works with PS/2 port.

May the chip who does that logic need TTL levels or something? Juts wondering.

dcrespo3d commented 4 years ago

Nominally, the PS/2 port does use TTL levels (5V) for the DATA and CLK signals. The ESP32 logic levels are nominally CMOS (3.3v). When the communication is unidirectional (KEYB -> ESP32), the ESP seems to happily accept TTL levels in its input pins. I succeeded using this scheme with an Acer mechanical PS/2 keyboard from the 1990s, which worked with the CLK and DATA lines connected directly to the ESP32 without voltage conversion, although this is discouraged by Espressif itself in their forums:

https://esp32.com/viewtopic.php?f=2&t=877

But my problem wasn't connecting one keyboard or another: the keyboard IS the computer, 80's style! (Spoiler: I have already made it work, I've crammed the ESP32, voltage-level-converter, USB and VGA inside the keyboard and it works!)

photo_2020-08-10_09-38-37

So I had to make that one keyboard work, and that keyboard needs some type of initialization to begin sending keystrokes, and CMOS 3.3V levels seem not to be enough when communicating (ESP32 -> KEYB), so it doesn't get initialized. I insist: seems like most keyboard don't need to be inited, but this one does. So, for my project, level converter is mandatory, although it's a hassle...

jorgefuertes commented 4 years ago

Understood. Nice work, congrats!