qmk_firmware/keyboards/framework/framework.c

321 lines
7.6 KiB
C
Raw Permalink Normal View History

// Copyright 2022 Framework Computer
// SPDX-License-Identifier: GPL-2.0-or-later
#include "quantum.h"
#include "framework.h"
#include "os_detection.h"
void keyboard_post_init_kb(void) {
keyboard_post_init_user();
// Enable debug output
debug_enable = true;
debug_matrix = true;
debug_keyboard = true;
}
/**
* Hook into early keyboard initialization
*/
void keyboard_pre_init_kb(void) {
keyboard_pre_init_user();
// Mark boot as done.
// Before this, when holding down both alt keys QSPI_SS is pulled low to put
// the RP2040 in bootloader mode during reset.
setPinOutput(BOOT_DONE_GPIO);
writePinLow(BOOT_DONE_GPIO);
//// TODO: Do we ever need to disable it to save power?
setPinOutput(MUX_ENABLE_GPIO);
writePinHigh(MUX_ENABLE_GPIO);
setPinOutput(IS31FL3743A_ENABLE_GPIO);
#if defined(RGB_MATRIX_ENABLE)
writePinHigh(IS31FL3743A_ENABLE_GPIO);
#else
writePinLow(IS31FL3743A_ENABLE_GPIO);
#endif
setPinInput(SLEEP_GPIO);
}
/**
* Called by QMK when the keyboard suspends
*/
void suspend_power_down_kb(void) {
suspend_power_down_user();
#ifdef RGB_MATRIX_ENABLE
# ifndef NO_SUSPEND_POWER_DOWN
writePinLow(IS31FL3743A_ENABLE_GPIO);
# endif
#endif
}
/**
* Called by QMK when the keyboard wakes up from suspend
*/
void suspend_wakeup_init_kb(void) {
suspend_wakeup_init_user();
#ifdef RGB_MATRIX_ENABLE
# ifndef NO_SUSPEND_POWER_DOWN
writePinHigh(IS31FL3743A_ENABLE_GPIO);
# endif
2023-01-06 21:31:44 -08:00
#endif
}
// If in BIOS mode, no matter what the keys have been remapped to, always send them as the F keys
bool bios_mode = true;
void set_bios_mode(bool val) {
bios_mode = val;
#ifdef BIOS_HOTKEY_DEBUG
if (bios_mode) {
// Red
#if defined(RGB_MATRIX_ENABLE)
rgb_matrix_sethsv_noeeprom(0, 0xFF, 0xFF);
rgb_matrix_mode_noeeprom(1);
#endif
writePin(GP24, 1);
} else {
// White
#if defined(RGB_MATRIX_ENABLE)
rgb_matrix_sethsv_noeeprom(0, 0, 0xFF);
rgb_matrix_mode_noeeprom(1);
#endif
writePin(GP24, 0);
}
#endif
}
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 == 3) {
if (record->event.pressed) {
register_code(KC_F1);
} else {
unregister_code(KC_F1);
}
return false;
}
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 == 4 && record->event.key.row == 6) {
if (record->event.pressed) {
register_code(KC_F3);
} else {
unregister_code(KC_F3);
}
return false;
}
if (record->event.key.col == 4 && record->event.key.row == 3) {
if (record->event.pressed) {
register_code(KC_F4);
} else {
unregister_code(KC_F4);
}
return false;
}
if (record->event.key.col == 10 && record->event.key.row == 4) {
if (record->event.pressed) {
register_code(KC_F5);
} else {
unregister_code(KC_F5);
}
return false;
}
if (record->event.key.col == 10 && record->event.key.row == 3) {
if (record->event.pressed) {
register_code(KC_F6);
} else {
unregister_code(KC_F6);
}
return false;
}
if (record->event.key.col == 10 && record->event.key.row == 2) {
if (record->event.pressed) {
register_code(KC_F7);
} else {
unregister_code(KC_F7);
}
return false;
}
if (record->event.key.col == 15 && record->event.key.row == 1) {
if (record->event.pressed) {
register_code(KC_F8);
} else {
unregister_code(KC_F8);
}
return false;
}
if (record->event.key.col == 11 && record->event.key.row == 3) {
if (record->event.pressed) {
register_code(KC_F9);
} else {
unregister_code(KC_F9);
}
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 == 8 && record->event.key.row == 6) {
if (record->event.pressed) {
register_code(KC_F11);
} else {
unregister_code(KC_F11);
}
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);
os_variant_t os = detected_host_os();
set_bios_mode(true);
#if defined(OS_DETECTION_RGB_DEBUG) && defined(RGB_MATRIX_ENABLE)
rgb_matrix_mode_noeeprom(1);
switch (os) {
case OS_UNSURE:
rgb_matrix_sethsv(0, 0, 255); // White
break;
case OS_LINUX:
// Works on laptop and android
rgb_matrix_sethsv(213, 255, 255); // purple
break;
case OS_WINDOWS:
rgb_matrix_sethsv(170, 255, 255); // blue
break;
case OS_MACOS:
rgb_matrix_sethsv(85, 255, 255); // green
break;
case OS_UEFI:
case OS_IOS:
// works on M1 mac
rgb_matrix_sethsv(43, 255, 255); // yellow
break;
default:
rgb_matrix_sethsv(125, 255, 255); // cyan
break;
}
#endif
switch (os) {
case OS_UNSURE:
break;
case OS_LINUX:
set_bios_mode(false);
break;
case OS_WINDOWS:
set_bios_mode(false);
break;
case OS_MACOS:
break;
case OS_UEFI:
case OS_IOS:
set_bios_mode(true);
// works on M1 mac
break;
}
//#endif
// Enable NKRO only in OS. Can cause issues with some pre-boot environments
// Framework UEFI is ok, but I think grub can't handle it properly
if (!bios_mode) {
keymap_config.nkro = 1;
}
if (!handle_bios_hotkeys(keycode, record)) {
return false;
}
#ifdef RGB_MATRIX_ENABLE
uint8_t h;
uint8_t s;
uint8_t v;
uint8_t new_v;
#endif
switch (keycode) {
// Implement step brightness for RGB backlight
#ifdef RGB_MATRIX_ENABLE
case RGB_MODE_FORWARD:
case RGB_MODE_REVERSE:
// Turn on if it was off
if (!rgb_matrix_is_enabled()) {
rgb_matrix_enable();
}
return true;
case BL_STEP:
if (record->event.pressed) {
h = rgb_matrix_get_hue();
s = rgb_matrix_get_sat();
v = rgb_matrix_get_val();
switch (v) {
default: // Default when user set to a different level
case 0:
new_v = 85;
break;
case 85:
new_v = 170;
break;
case 170:
new_v = 255;
break;
case 255:
new_v = 0;
break;
}
rgb_matrix_sethsv(h, s, new_v);
}
return true;
#endif
case KC_SCRN:
// Simulate press WIN+P
// Works (at least) on Windows and GNOME
if (record->event.pressed) {
register_code(KC_LGUI);
register_code(KC_P);
} else {
unregister_code(KC_P);
unregister_code(KC_LGUI);
}
return false; // Skip all further processing of this key
default:
return true; // Process all other keycodes normally
}
return true;
}
#ifdef BIOS_HOTKEY_DEBUG
// Ignore capslock updates in order to manually control it
bool led_update_kb(led_t led_state) {
return false;
}
#endif