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

Feature: ibmpc_usb lock state indicators on converter itself #755

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

an-achronism
Copy link
Contributor

Refactored LED indicator routine to incorporate updating LEDs on the converter itself (LEDs wired directly to controller pins) primarily for the sake of keyboards that speak unidirectional protocols and/or have no LED indicators on them. Still safeguards sending IBM-formatted LED control byte to "XT" protocol keyboards or anything that has not yet been identified, just does it in a different place to facilitate controlling the LEDs on the converter.

If there are any issues with the way I've structured the converter LED part, I have a separate branch on which I just refactored the existing routine to make it slightly more efficient (specifically, it now only converts the USB HID format LED control byte to IBM format if it's already determined that it will be sending it to the keyboard, whereas before it did the translation anyway and could then decide afterwards that it was not going to be used).

Note: Mousekeys disabled by default because even when using avr-gcc 5.4 or 5.5, I cannot get TMK to compile either on Ubuntu 20.04 LTS or on macOS with Mousekeys disabled (not just because of my changes, but also from master branch).

Keyboard lock state indicator LEDs are updated by sending a control
byte to the keyboard, which has one bit per individual LED state (the
rest of the byte being 0s). The order of the bits is different between
the USB HID and IBM PC/AT protocols, so they have to be reorganised
before TMK sends them to the keyboard.

The existing implementation of this works perfectly fine, but reorders
the LED state control byte to IBM format before sending it to a single
function that sends both the LED control enquiry byte (0xED) and the
actual LED state control byte itself, one after the other. However, not
every keyboard will respond to the enquiry byte with an acknowledgement
(0xFA), e.g. IBM terminal keyboards which will respond instead with an
0xFE meaning "RESEND", in which case the LED state control byte will
not be sent, meaning that it was just reorganised unnecessarily.

This refactored implementation splits the sending of the enquiry byte
into a separate function, so that the enquiry byte is sent first, and
the control byte is only reorganised if the keyboard has already
responded with the "ACK" acknowledgement byte.
Even with this change, avr-gcc 8 and 9 are still unable to compile, but
it allows for a successful compilation in avr-gcc 5.4 and 5.5.

5.4 is still hanging on for dear life inside the VirtualBox VM provided
in the TMK wiki:
https://github.com/tmk/tmk_keyboard/wiki/Build-on-VirtualBox

5.5 is still currently available through Homebrew keg here:
https://github.com/osx-cross/homebrew-avr

I have not yet tested avr-gcc versions 6 or 7, because neither is
straightforwardly available to me (i.e. through on a package manager on
macOS, Windows, or Linux distro that can be set up quickly on a VM).
Further restructured lock state LED routine to update both the keyboard
and any indicators wired to the converter itself. Tested on Unicomp New
Model M and various different IBM keyboards (a 5150 one, a 122-key, and
a 1990 Enhanced Keyboard). Current behaviour is that the converter LEDs
always light regardless of whether the keyboard has them, which is
primarily because of edge cases where a keyboard might respond
indicating that it can be sent LED state control bytes even though it
doesn't actually have LEDs with which to render the information.
@an-achronism an-achronism changed the title Feature: ibmpc_usb converter lock state indicators Feature: ibmpc_usb lock state indicators on converter itself Mar 5, 2023
Renamed in one file and not the other, which was an artefact of naming
difference in another firmware. Fixed and retested now. Sorry!
My intention with splitting up ibmpc.host_set_led() into two functions
was to ensure that the bit order of the USB HID LED update byte was not
reconfigured to IBM order unless it was actually going to be used.
However, it has been suggested that splitting the check for whether the
keyboard can receive the LED byte and the subsequent sending of the LED
byte into separate functions in some way implies that they are less
contextually connected and inter-reliant, which could hypothetically
lead to a misunderstanding and potentially the addition of code that
does unwise things with these newly separate functions (e.g. you can't
send the LED byte without sending the check byte immediately prior, you
can't send multiple LED bytes after only ascertaining once that the
keyboard is capable of receiving them, and so forth).

To reduce the likelihood of this interpretation, I've removed the case-
specific functions for sending the two bytes from ibmpc and called
ibmpc.host_send() directly from ibmpc_usb.cpp to make it clearer that
the LED byte should only be sent immediately after the check byte.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant