fl16: Implement BIOS mode

When enabled, overrides whatever keyboard layout and always makes the
keys in the physical location of F2, F10 and F12 send the keycodes for
F2/F10/F12.
BIOS is supposed to enable this right after USB enumeration, so that the
BIOS hot keys always work, even if FN-lock is enabled or the user has
remapped their keyboard.
BIOS mode is exited either by the keyboard resetting or by sending the
disable message.

How to send:

1. Find USB devices with Framework VID 0x32AC
2. Filter by interface number == 0x01 and usage page == 0xFF60
3. Set HID report with the following body:

Enable:  0x00 0x0B 0x05 0x01 0xFE 0xFE ... pad the 32 byte buffer with 0xFE
Disable: 0x00 0x0B 0x05 0x00 0xFE 0xFE ... pad the 32 byte buffer with 0xFE
Where the first byte is the report ID 0x00

TODO:

- [ ] Test on ANSI keyboard
- [x] Test on ISO keyboard
- [ ] Test on JIS keyboard
- [ ] Add method to get current status

Signed-off-by: Daniel Schaefer <dhs@frame.work>
This commit is contained in:
Daniel Schaefer 2023-07-17 13:03:14 +08:00
parent 4e2e213040
commit 21fd6d199c
3 changed files with 50 additions and 0 deletions

View File

@ -15,6 +15,7 @@
enum factory_commands {
f_emu_keypress = 0x01, // Next byte is keycode
f_serialnum = 0x04, // Read device serial number
f_bios_mode = 0x05, // Read device serial number
f_bootloader = 0xFE,
};
@ -61,6 +62,12 @@ void handle_factory_command(uint8_t *data) {
uprintf("Serial number unavailable\n");
#endif
break;
case f_bios_mode:
if (command_data[0] == 0x01)
bios_mode = true;
else
bios_mode = false;
break;
default:
uprintf("Unknown factory command: %u\n", factory_command_id);
break;

View File

@ -59,9 +59,50 @@ void suspend_wakeup_init_kb(void) {
#endif
}
// If in BIOS mode, no matter what the keys have been remapped to, always send them as the F keys
bool bios_mode = false;
bool handle_bios_hotkeys(uint16_t keycode, keyrecord_t *record) {
// Not in bios mode, no special handling, handle as normal
if (!bios_mode)
return true;
if (record->event.key.col == 5 && record->event.key.row == 2) {
if (record->event.pressed) {
register_code(KC_F2);
} else {
unregister_code(KC_F2);
}
return false;
}
if (record->event.key.col == 8 && record->event.key.row == 4) {
if (record->event.pressed) {
register_code(KC_F10);
} else {
unregister_code(KC_F10);
}
return false;
}
if (record->event.key.col == 13 && record->event.key.row == 3) {
if (record->event.pressed) {
register_code(KC_F12);
} else {
unregister_code(KC_F12);
}
return false;
}
return true;
}
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
process_record_user(keycode, record);
if (!handle_bios_hotkeys(keycode, record)) {
return false;
}
#ifdef RGB_MATRIX_ENABLE
uint8_t h;
uint8_t s;

View File

@ -23,6 +23,8 @@ enum framework_keycodes {
FN_LOCK,
};
extern bool bios_mode;
#define SLEEP_GPIO GP0
#define MUX_ENABLE_GPIO GP4
#define BOOT_DONE_GPIO GP5