Hamberthm / esp32-bt2ps2

Use a Bluetooth or BLE keyboard and mouse with your machine with a PS/2 port
MIT License
26 stars 6 forks source link

not working correctly with C.H.I.P. computer #10

Closed ktownsend-personal closed 1 week ago

ktownsend-personal commented 2 months ago

Very cool project! Unfortunately I am getting weird results when I try to use it with the C.H.I.P. computer. When I type, only sometimes do the characters appear on the screen, and not even the same characters work. It seems to depend on how fast I type and what the previous letter was that I typed. Even when I type fast the first character doesn't appear.

I assembled my ESP32 with a level shifter because I'm not comfortable giving it 5V signals directly. Any thoughts on what I can examine? I tried to enable debugging based on your instruction in the README.md, but I have no idea what SOMETHING should be and it won't compile.

I am hoping to use this to solve my need for a PS/2 keyboard for this CHIP computer, as I don't have that kind of keyboard. I don't have any other devices capable of using PS/2 to test with either, so I don't know if it's just this specific combination of devices or if it's something odd with my implementation of this, like the level shifter.

ktownsend-personal commented 2 months ago

I experimented some more and it seems like it's just eating the first character of a series typed very fast. If you type slow, all characters are eaten. If you type a word really fast just the first letter is eaten. The timeframe a sequence of characters has to be typed successfully is extremely fast, then it eats the next character. If you type the same character as the first character, even if very rapidly, it never appears.

I was able to type a word successfully if I type each character I want very fast after some other character to account for the first character not appearing. To get the enter key to work I have to do the same thing...type some other character and then the enter key very fast.

This seems like a timing issue of some sort, but no idea which end of the connection is responsible.

I also noticed the caps-lock light does not illuminate on my keyboard even though the characters are capitalized appropriately.

Hamberthm commented 1 month ago

Hi there! Thanks for trying out my project!

Yes, it seems like a timing issue of some sort. At least it seems your system is accepting the module correctly as you can at least get some control codes to reach the host, so the setup at post is working.

First of all, we need to check if the software is doing some weird timing. For this, try to turn on debug messages so you can see the serial console and check for feedback as soon as you press a key. You'll be looking for two things:

1- That the code is receiving the key correctly (it should echo the exact key you pressed). 2- That the echo message appears as soon as you press the key with no delay.

This will discard any code problems. I experienced some timing issues and it was due to the FreeRTOS ticking rate (make sure you're using the provided config file that includes this parameter!).

In main.cpp there are many logging/debug function calls that provide the info you need. More specifically, at line 379 you have what you are looking for:

https://github.com/Hamberthm/esp32-bt2ps2/blob/e4298b657bce084e72884f15ce24aac141fd48a8/main/main.cpp#L379

This call will echo the USB HID code received from the keyboard in the serial monitor, before passing it to the keyboard.keyHid_send() function to be translated to the PS2 protocol Control Code.

For v0.4 I turned the verbosity level down to avoid spamming the serial console, as it is a pretty stable build. To be able to see this debug message, you need to elevate the ESP-IDF logging verbosity to "debug" level or higher. This is done via the ESP-IDF Project Configuration page. For more info Google "ESP-IDF project configuration on Visual Studio Code" (I think it was done by typing "config" on the search bar on top of VS Code, enter the Project Configuration page, then search for the verbosity setting) or look here.

This is the easiest first step to try. Once we are sure the code is working OK with no lag, then we can start checking other things.

Reach back if you're having a hard time doing this, and I may set up a debug build to help you.

P.S.: Caps lock/num lock/scroll lock LED light up function is not supported yet and will be in the future. Caps should work regardless.

Kind regards

Humberto

ktownsend-personal commented 1 month ago

Here is what I get in the monitor console:

Pressing the A key once:

D (270079) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dbef8 and context 0x3ffd7aac on loop 0x3ffd7810
0x400dbef8: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

D (270080) BTKeyboard: 00 04 00 00 00 00 00
D (270083) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (270177) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dbef8 and context 0x3ffd7aac on loop 0x3ffd7810
0x400dbef8: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

D (270178) BTKeyboard: 00 00 00 00 00 00 00
D (270181) KEYS PASSED TO MAIN: : 00 00 00 00 00

Pressing A, then S in very rapid succession:

D (343626) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dbef8 and context 0x3ffd7aac on loop 0x3ffd7810
0x400dbef8: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

D (343627) BTKeyboard: 00 04 00 00 00 00 00
D (343630) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (343675) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dbef8 and context 0x3ffd7aac on loop 0x3ffd7810
0x400dbef8: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

D (343675) BTKeyboard: 00 04 16 00 00 00 00
D (343678) KEYS PASSED TO MAIN: : 16 00 00 00 00
D (343683) BTKeyboard: Down key: 16
D (343725) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dbef8 and context 0x3ffd7aac on loop 0x3ffd7810
0x400dbef8: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

D (343725) BTKeyboard: 00 16 00 00 00 00 00
D (343729) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (343733) BTKeyboard: Up key: 16
D (343775) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dbef8 and context 0x3ffd7aac on loop 0x3ffd7810
0x400dbef8: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

D (343775) BTKeyboard: 00 00 00 00 00 00 00
D (343779) KEYS PASSED TO MAIN: : 00 00 00 00 00
Hamberthm commented 1 month ago

I think I see where your problem is.

It seems your keyboard is reporting six key bytes and the code is only registering 5. Then you get output only when you press two or more keys at the same time (the first one gets ignored). That's what really happening with "quick writing".

That's not my code right there but I can certainly fix it. That function has given me problems before.

Please stand by and I will look at it today or tomorrow!

P.S.: Can you give me your keyboard make and model?

ktownsend-personal commented 1 month ago

Thanks! Looking forward to trying out your fix. I am using a Logitech MX Keys Wireless Keyboard, model YR0073. It's been an excellent keyboard for several years.

Hamberthm commented 1 month ago

Looking at it, it seems the push_key function is being given a byte length of 5 as a parameter.

Could you please ramp up the debug verbosity level to "VERBOSE" and pass me the same log? I need to check what's happening to the length paramater.

ktownsend-personal commented 1 month ago

Verbose log of same tests:

Pressing A once:

D (94164) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (94164) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (94171) BTKeyboard: 00 04 00 00 00 00 00 
D (94176) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (94314) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (94315) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (94322) BTKeyboard: 00 00 00 00 00 00 00
D (94326) KEYS PASSED TO MAIN: : 00 00 00 00 00

Pressing A, then S in rapid succession:

D (121090) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (121090) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (121098) BTKeyboard: 00 04 00 00 00 00 00
D (121102) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (121165) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (121165) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (121173) BTKeyboard: 00 04 16 00 00 00 00
D (121177) KEYS PASSED TO MAIN: : 16 00 00 00 00
D (121182) BTKeyboard: Down key: 16
D (121217) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (121217) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (121225) BTKeyboard: 00 16 00 00 00 00 00
D (121229) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (121234) BTKeyboard: Up key: 16
D (121267) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (121267) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (121275) BTKeyboard: 00 00 00 00 00 00 00
D (121279) KEYS PASSED TO MAIN: : 00 00 00 00 00
ktownsend-personal commented 1 month ago

Unrelated to this issue, I found something today that confirms ESP32 is officially 5V tolerant on the inputs as long as the ESP32 is powered with 3.3V. I may experiment with removing the level shifter to simplify the circuit. Is the clock pin driven by ESP32 or by the host? Is the data pin bidirectional or driven by ESP32 or by the host? I figured out both clock and data are bidirectional. Interesting protocol. As long as the host accepts 3.3V as logic high then it should work fine without level shifting.

Hamberthm commented 1 month ago

Yes, I'm sure you'll have no problems at all deleting the logic level converter. You'll then have a pretty neat standalone, and small, device you can attach to your system.

I'm currently working on your bug and it seems to be that your keyboard does a special 7-byte key report.

May I ask for another log? This time pressing a modifier key like CTRL, ALT or SHIFT. Then at the same time a letter.

Like CTRL, and then CTRL+A

This is to be sure we are getting the correct report for the modifier key. In my Logitech K380 the reports are as follows:

V (2571533) BTKeyboard: f4:73:35:86:e2:5a INPUT: KEYBOARD, MAP: 0, ID: 1, Len: 8, Data: D (2571541) BTKeyboard: 01 00 00 00 00 00 00 00 D (2571546) KEYS PASSED TO MAIN: : 00 00 00 00 00 00 D (2571551) BTKeyboard: Down key: LCTRL

This is a standard 8-byte report with the first byte containing the modifier (LCTRL), the second being undefined (always 0) and the 6 remaining cotaining the pressed keys.

Your keyboard seems to be using a different 7-byte report. I need to be sure the first byte is still being used for the modifier key.

ktownsend-personal commented 1 month ago

It looks like first byte is the modifier and second byte is the regular key. I noticed if I press a third key while holding a modifier and a regular key the third byte is the third key. Based on what you explained, it seems like my keyboard is omitting the undefined byte you are used to getting in the 8-byte sequence.

Log with modifier key:

Control key pressed and released:

D (13119770) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (13119770) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (13119778) BTKeyboard: 01 00 00 00 00 00 00
D (13119783) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (13119787) BTKeyboard: Down key: LCTRL
D (13119895) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (13119895) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (13119903) BTKeyboard: 00 00 00 00 00 00 00
D (13119907) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (13119912) BTKeyboard: Up key: LCTRL

Control pressed and held, A pressed, A released, Control released:

D (13139471) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (13139471) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (13139479) BTKeyboard: 01 00 00 00 00 00 00
D (13139483) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (13139488) BTKeyboard: Down key: LCTRL
D (13139796) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (13139796) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (13139804) BTKeyboard: 01 04 00 00 00 00 00 
D (13139808) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (13139994) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (13139994) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (13140002) BTKeyboard: 01 00 00 00 00 00 00
D (13140006) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (13141219) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dc578 and context 0x3ffd78c0 on loop 0x3ffd78a4
0x400dc578: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

V (13141219) BTKeyboard: f5:0e:80:7e:ba:de INPUT: KEYBOARD, MAP:  0, ID:   1, Len: 7, Data:
D (13141227) BTKeyboard: 00 00 00 00 00 00 00 
D (13141231) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (13141236) BTKeyboard: Up key: LCTRL
Hamberthm commented 1 month ago

Hi there, yesterday I worked on the issue for many hours. The problem seems to be the so called "Protocol Mode" as defined by the USB HID specification. It can either be "REPORT" or "BOOT". Report mode doesn't use a null byte in the key reports and BOOT mode is a fixed 8 byte with the second byte always zero. They did that for old BIOS compatibility or something.

I'm working in how to reliably identify the current mode the keyboard is using so to not break compatibility. It may take me a little longer.

In the meanwhile, I don't want to make you wait. You can try the following temporal fix on your build so you can test your machine. Please change the following lines in bt_keyboard.cpp:

https://github.com/Hamberthm/esp32-bt2ps2/blob/e4298b657bce084e72884f15ce24aac141fd48a8/main/bt_keyboard.cpp#L1098

Change to: uint8_t max = (size > MAX_KEY_COUNT + 1) ? MAX_KEY_COUNT : size - 1;

and

https://github.com/Hamberthm/esp32-bt2ps2/blob/e4298b657bce084e72884f15ce24aac141fd48a8/main/bt_keyboard.cpp#L1102

Change to: inf.keys[i] = keys[i + 1];


If I'm right, that should offset the byte count and include the missing one so you can test your machine and in the meanwhile, I can think on a more universal fix. If it still fails, come back with a log as usual.

Cheers! Humberto

ktownsend-personal commented 1 month ago

Thanks! I really appreciate your work on this. I just confirmed the temporary changes fix my situation and I am able to type normally now. Looking forward to seeing what you do for the protocol mode. I haven't dug into keyboard protocols before, so this is interesting.

Hamberthm commented 1 month ago

Hi there!

I've been working on a new release. I implemented a workaround for the BOOT/REPORT mode issue.

Turns out Espressif does provide a function to identify the current protocol mode, but it's only supported on BLE and not on BT Classic. Also, there's no apparent way to know the protocol mode by examining the report parameters because that info doesn't get passed to the callback function on the user side.

Even more, when on BT Classic the stack auto-generates a fake entry on the Report Map for a supposed "BOOT" mode report with the exact same ID as the REPORT mode one, it just duplicates it and changes the mode.

Anyway, that's way too technical and into the stack's code so don't worry about it. The new push_key() function is as follows:

void BTKeyboard::push_key(uint8_t *keys, uint8_t size)
{
  uint8_t offset = 2; // default to BOOT mode report, second byte is always 0

  if (keys[1]) // some keyboards use REPORT mode and the second byte of the report is the first one
  {
    offset = 1;
  }

  KeyInfo inf;
  inf.modifier = (KeyModifier)keys[0];

  uint8_t max = (size > MAX_KEY_COUNT + offset) ? MAX_KEY_COUNT : size - offset;
  // inf.keys[0] = inf.keys[1] = inf.keys[2] = 0; // No need to do this?
  for (int i = 0; i < max; i++)
  {
    inf.keys[i] = keys[i + offset];
  }
  if (max < MAX_KEY_COUNT) // End flag in case our keyboard reports less keys than our max count
    inf.keys[max] = 0;
  ESP_LOG_BUFFER_HEX_LEVEL("KEYS PASSED TO MAIN: ", inf.keys, max, ESP_LOG_DEBUG);
  xQueueSend(event_queue, &inf, 0);
}

As you can see, I replaced the offset with a variable, so it dynamically checks if a key is reported on the second byte after the modifier, like in your case, and adjusts the offset accordingly.

That's not the ideal fix, because the second byte being reserved on BOOT mode doesn't forbid the manufacturers from putting a non-zero constant value on there and thus reporting a fake key, but I'm willing to bet that would be an extremely rare case. Most or nearly all the keyboards following BOOT mode will give a zero value there, I'm sure.

So, if you want to test it, you can copy the new function in your source, otherwise if you want to test the new release (with support for multimedia keys ;) ) here you have the new v0.5 candidate source code and a compiled binary for fast flashing and testing (Use FLASH.BAT). Pins are set to 22 and 23 like the code on the repository!

Binary with flasher: https://1drv.ms/u/s!AlKre4_rNmpJiO06mvjtyg04xExK7w?e=XfPOVz Source: https://1drv.ms/u/s!AlKre4_rNmpJiPIjbqgqmQaozdPbtw?e=tK98xB

Keep in mind this will be a major release and there's changes on many files, not only this function.

Will leave this open for a while in case you come back with feedback :)

Thanks a lot!

Humberto

ktownsend-personal commented 4 weeks ago

Great!! I will give it a try soon and let you know how it goes. I appreciate the details :)

ktownsend-personal commented 2 weeks ago

I finally got a chance to try out your new code. I had to build from source because I am using different pins. Normal typing looks good, but I think the control key isn't working right. I am using this adapter on a homebrew computer kit and I don't remember for certain if control-C used to work but it seems like it did when I needed to break out of a BASIC program. The shift and caps-lock keys are working fine. I reviewed the debug output and the control and alt keys are signaling correctly from bluetooth. Maybe there is something odd with handling the key modifiers out to PS/2 in the latest changes?

Hamberthm commented 2 weeks ago

Hi @ktownsend-personal !

I think in reality your 'C' key isn't working! That's a big bug I just discovered fixed today! It drove me really mad. Explanation is really long, but if you want it fixed right away please change the key section in main.cpp to:

                // KEY SECTION (always tested)
                // release the keys that have been just released
                for (int i = 0; i < BTKeyboard::MAX_KEY_COUNT; i++)
                {
                    if (!infoBuf.keys[i])
                    {                                                     // Detect END FLAG
                        break;
                    }
                    for (int j = 0; (info.keys[j]) && (j < BTKeyboard::MAX_KEY_COUNT); j++)
                    {
                        if (infoBuf.keys[i] == info.keys[j])
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        ESP_LOGD(TAG, "Up key: %x", infoBuf.keys[i]);
                        keyboard.keyHid_send(infoBuf.keys[i], false);
                        gpio_set_level(GPIO_NUM_2, 1);
                    }
                    else
                    {
                        found = false;
                    }
                }

                // press the keys that have been just pressed
                for (int i = 0; i < BTKeyboard::MAX_KEY_COUNT; i++)
                {
                    if (!info.keys[i])
                    {                                                   // Detect END FLAG
                        break;
                    }
                    for (int j = 0; (infoBuf.keys[j]) && (j < BTKeyboard::MAX_KEY_COUNT); j++)
                    {
                        if (info.keys[i] == infoBuf.keys[j])
                        {
                            found = true;
                            break;
                        }
                    }
                    if (!found)
                    {
                        ESP_LOGD(TAG, "Down key: %x", info.keys[i]);
                        keyboard.keyHid_send(info.keys[i], true);
                        gpio_set_level(GPIO_NUM_2, 0);
                    }
                    else
                    {
                        found = false;
                    }
                }

                infoBuf = info;                 // Now all the keys are handled, we save the state
                typematicLeft = typematicDelay; // Typematic timer reset
            }

The only changes are the conditions for the for loops:

(info.keys[j]) && (j < BTKeyboard::MAX_KEY_COUNT)

and

(infoBuf.keys[j]) && (j < BTKeyboard::MAX_KEY_COUNT)

(CAUTION: Note they are different for each loop)

Basically, the array never gets fully initialized in the bt_keyboard.cpp module, it only gets populated with the pressed keys. As there may be garbage bytes already in memory, and my code was checking the full array until MAX_KEY_COUNT, it encountered those garbage bytes and interpreted them like already-pressed keys.

Now it checks only while there's a key code and not 0 (info.keys[j]), because the bt_keyboard module inserts a 0 end indicator when there's no more keys. This wasn't bein checked before.

Expect a big release before the weekend with mouse support and this bug fixed!

Cheers!

ktownsend-personal commented 2 weeks ago

Interesting. I will give it a try. When I was trying it earlier the normal C character was appearing on the screen of the kit computer, just not modified by the control key.

ktownsend-personal commented 2 weeks ago

No change. I just get the normal C character displayed instead of control-C.

Hamberthm commented 2 weeks ago

Sorry for the delay, had to sleep a little 🤪

Well, that's really strange! I just tested it on my Toshiba Satellite 205CDS and LCTRL is working fine with CTRL-C/CTRL-V and so on.

Also, the modifier is a single byte sent always in front of the report. For LCTRL, the first bit is set so it should read 0x1 on the modifier byte with that key pressed alone.

It could be an initialization problem just like above but it already gets initialized. Anyway it is a single byte and it always get overwritten by the buffer save (infoBuf = info;) at the end of the key section. So if it were an initialization problem it should fail the first press but start working afterwards.

Anyway, just to be sure you can try changing the initialization setting at the beggining of the loop at line:

info.modifier = infoBuf.modifier = (BTKeyboard::KeyModifier)0;

And change the 0 to something like 2 or 3. But I'm not sure that's the problem.

Anyway, if you have time a Verbose log chunk like you posted above would be useful. Also, can you confirm previous builds were working for you?

Thanks!

Hamberthm commented 2 weeks ago

Nevermind, just realized you won't see the modifier byte because it never gets logged.

You have to add this line at the end of the push_key() function in bt_keyboard.cpp, just after the log output for "KEYS PASSED TO MAIN":

ESP_LOGD("bt_keyboard", "MODIFIER: 0x%x", inf.modifier);

Then you'll see what modifier it gets passed to MAIN function via the queue.

Anyway: If you see both "BTKeyboard: Down key: LCTRL" and "BTKeyboard: Up key: LCTRL" on the logs, it means it's getting processed OK and the problem is the PS/2 section! (If you see only one, like "up" for example, then we have something to fix). This was working OK in your logs above.

ktownsend-personal commented 2 weeks ago

I added the logging but not the initialization. Figured worth seeing what we get without fiddling first. It looks like it sees the modifier at this point in the logic.

D (37782) BTKeyboard: 01 00 00 00 00 00 00
D (37785) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (37790) bt_keyboard: MODIFIER: 0x1
D (37794) BTKeyboard: Down key: LCTRL
D (39530) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dd0c8 and context 0x3ffd79c4 on loop 0x3ffd7944
0x400dd0c8: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

D (39530) BTKeyboard: 01 06 00 00 00 00 00
D (39534) KEYS PASSED TO MAIN: : 06 00 00 00 00 00
D (39539) bt_keyboard: MODIFIER: 0x1
D (39542) BTKeyboard: Down key: 6
D (39980) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dd0c8 and context 0x3ffd79c4 on loop 0x3ffd7944
0x400dd0c8: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

D (39980) BTKeyboard: 01 00 00 00 00 00 00
D (39984) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (39988) bt_keyboard: MODIFIER: 0x1
D (39992) BTKeyboard: Up key: 6
D (40655) event: running post ESP_HIDH_EVENTS:2 with handler 0x400dd0c8 and context 0x3ffd79c4 on loop 0x3ffd7944
0x400dd0c8: esp_ble_hidh_event_handler_wrapper at C:/Users/edge9/esp/v5.2.2/esp-idf/components/esp_hid/src/ble_hidh.c:621

D (40655) BTKeyboard: 00 00 00 00 00 00 00
D (40659) KEYS PASSED TO MAIN: : 00 00 00 00 00
D (40663) bt_keyboard: MODIFIER: 0x0
D (40667) BTKeyboard: Up key: LCTRL
Hamberthm commented 1 week ago

Good, as per the posted log it seems that LCTRL is being processed correctly and passed to the PS/2 module (Down and Up key logs appear).

So, maybe we have a (very strange) problem with PS2dev module and PS/2 commands.

May I suggest:

I'm always here to help.

Humberto

ktownsend-personal commented 1 week ago

cool, I will try out v0.6 later tonight or tomorrow. I wish I had another PS/2 host I could try but unfortunately I don't. That's really the whole reason I'm using this...because I don't have anything PS/2 except this CHIP computer kit and hence no PS/2 keyboard laying around LOL

Hamberthm commented 1 week ago

I was just browsing the documentation for the computer you're using and came across this on the manual:

One thing to note: To stop a program press the "pause/break" key on the keyboard.

https://github.com/Retrotink/CHIP/tree/main/User%20Manual#one-thing-to-note-to-stop-a-program-press-the-pausebreak-key-on-the-keyboard-

You mentioned above you were trying to use CTRL-C instead to break out of BASIC programs!

Maybe that's it?

ktownsend-personal commented 1 week ago

Oh! I forgot all about that! It must not handle control codes, which seems weird but certainly possible. Sorry for having you chase this non-bug!

Hamberthm commented 1 week ago

Haha! Great! That's a relief!

No worries, you did more work than me on this one. Also big, big thanks to you! Your certainly helped me on the boot/report issue and collaborated to make the project even more universally compatible.

That system you're using seems like fun! I'm a collaborator at a local retro computer museum in my city, so I know you're into some good old "home computer" fun 😊

Once you tested it further, remember to turn down the logging to "Info" level, as debugging messages affect performance a lot.

Let me close this one so I can enjoy 0-issues for once haha!

Please reopen if issues with your system continue, and in case of any other.

Cheers!

Humberto

ktownsend-personal commented 1 week ago

I didn't mind helping out at all... this project fits my needs perfectly and lets me avoid having a second keyboard floating around my office. Win-win!

I installed v0.6-beta and it's working great. I disabled boot pairing to get faster startup and my keyboard is operational in 10 seconds from power on now. It was quite a lot slower before. My ESP32 module doesn't have a boot button, so I'll have to remember to ground GPIO0 if I ever need to pair again.

It took me some time to figure out updating esp-idf to 5.3 since I have not used it for any of my personal projects (I use platform.io; check out my RetroPhone project). After I finally figured out how to update the version the build wouldn't work and wanted me to run idf.py fullclean, which had me stumped for a bit because I couldn't find any path where idf.py was recognized, but eventually found the fullclean command in the extension UI when I stopped banging my head on the console long enough to remember there is a UI. Toolchain woes LOL

I did a compare and saw how much you changed...quite a lot! I like the mouse option and multiple paring option. Can't really use it for my particular case, but good features. I went ahead and mapped the mouse pins to something sensible for my board in case I decide to add the extra mouse PS/2 cable in the future. I might try finding a PS/2 cable with all 6 wires and put all the signals on one cable, then use a mouse/keyboard splitter adapter for hardware that needs it.

Thanks for providing this project and all the time you put into it so people like me can benefit!

Hamberthm commented 1 week ago

Thanks a lot for the feedback! Glad it worked!! 😁

Pretty interesting that phone project! Going to check it out for sure!