diff options
Diffstat (limited to 'keyboards/mechboards/common')
-rw-r--r-- | keyboards/mechboards/common/display_oled.c | 385 | ||||
-rw-r--r-- | keyboards/mechboards/common/post_rules.mk | 3 | ||||
-rw-r--r-- | keyboards/mechboards/common/rgb_effects.h | 54 |
3 files changed, 442 insertions, 0 deletions
diff --git a/keyboards/mechboards/common/display_oled.c b/keyboards/mechboards/common/display_oled.c new file mode 100644 index 0000000000..fed13c22fd --- /dev/null +++ b/keyboards/mechboards/common/display_oled.c @@ -0,0 +1,385 @@ +// Copyright 2025 Dasky (@daskygit) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "quantum.h" + +static uint16_t current_keycode = 0xFF; + +static const char *depad_str(const char *depad_str, char depad_char) { + while (*depad_str == depad_char) + ++depad_str; + return depad_str; +} + +static void render_spacer(uint8_t char_length) { + static const char PROGMEM spacer_char[] = {8, 8, 8, 8, 8, 8, 8}; + if (char_length > 5) { + char_length = 5; + } + for (uint8_t i = 0; i < char_length; i++) { + oled_write_raw_P(spacer_char, sizeof(spacer_char)); + oled_advance_char(); + } +} + +__attribute__((weak)) void render_logo(void) { + static const char PROGMEM mb_logo[] = { + 252, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 31, 31, 31, 31, 31, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 227, 227, 227, 3, 227, 227, 227, 3, 227, 227, 227, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 254, 252, 255, 255, 255, 255, 255, 7, 7, 7, 7, 7, 255, 7, 7, 7, 7, 7, 255, 7, 7, 7, 7, 7, 255, 7, 7, 7, 7, 7, 255, 7, 7, 7, 7, 7, 255, 255, 255, 4, 4, 4, 4, 4, 255, + 7, 7, 7, 7, 7, 255, 7, 7, 7, 7, 7, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 238, 238, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 65, 65, 65, 65, 65, 255, 255, 255, 255, 255, 255, 255, 65, 65, 65, 65, 65, 255, 255, 255, 255, 255, 255, 255, 65, 65, 65, 65, 65, 255, 255, 255, 65, 65, 65, 65, 65, 255, 127, 127, 127, 127, 127, 255, 65, 65, 65, 65, 65, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 63, 127, 255, 255, 255, 240, 240, 240, 240, 240, 255, 255, 255, 255, 255, 255, 255, 240, 240, 240, 240, 240, 255, 255, 255, 255, 255, 255, 255, 240, 240, 240, 240, 240, 255, 255, 255, 240, 240, 240, 240, 240, 255, 240, 240, 240, 240, 240, 255, 240, 240, 240, 240, 240, 255, 255, 255, 255, 255, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 199, 199, 199, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 224, 127, 63, + }; + oled_write_raw_P(mb_logo, sizeof(mb_logo)); +} + +void render_small_mb_logo(void) { + static const char PROGMEM small_mb_logo[] = { + 112, 112, 112, 0, 112, 112, 112, 0, 112, 112, 112, 0, 112, 112, 112, 0, 112, 112, 112, 0, 0, 119, 119, 119, 0, 112, 112, 112, 0, 112, 112, 112, 119, 119, 119, 0, 0, 0, 0, 0, 119, 119, 119, 0, 0, 0, 0, 0, 119, 119, 119, 0, 0, 119, 119, 119, 0, 112, 112, 112, 0, 119, 119, 119, + }; + oled_write_raw_P(small_mb_logo, sizeof(small_mb_logo)); +} + +static uint8_t last_hue; +static uint8_t last_sat; +static uint8_t last_val; +static uint8_t last_mode; + +void render_rgb_info(void) { + last_hue = rgb_matrix_get_hue(); + last_sat = rgb_matrix_get_sat(); + last_val = rgb_matrix_get_val(); + last_mode = rgb_matrix_get_mode(); + oled_set_cursor(0, 6); + oled_write("H:", false); + oled_write(depad_str(get_u16_str(last_hue, ' '), ' '), false); + oled_set_cursor(0, 7); + oled_write("S:", false); + oled_write_ln(depad_str(get_u16_str(last_sat, ' '), ' '), false); + oled_set_cursor(0, 8); + oled_write("V:", false); + oled_write_ln(depad_str(get_u16_str(last_val, ' '), ' '), false); + oled_set_cursor(0, 9); + oled_write("M:", false); + oled_write_ln(depad_str(get_u16_str(last_mode, ' '), ' '), false); +} + +oled_rotation_t oled_init_kb(oled_rotation_t rotation) { + if (is_keyboard_master()) { + return OLED_ROTATION_270; + } + return rotation; +} + +char basic_codes_to_name[57] = {' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'R', 'E', 'B', 'T', '_', '-', '=', '[', ']', '\\', '#', ';', '\'', '`', ',', '.', '/'}; + +const char *keycode_string(uint16_t keycode) { + char *keycode_str; + static char key; + switch (keycode) { + case 0 ... 56: + key = pgm_read_byte(&basic_codes_to_name[keycode]); + return &key; + case KC_CAPS: + keycode_str = "Caps\0"; + break; + case KC_SCRL: + keycode_str = "Scrl\0"; + break; + case KC_PAUS: + keycode_str = "Pause\0"; + break; + case KC_DEL: + keycode_str = "Del\0"; + break; + case KC_NUM: + keycode_str = "Num\0"; + break; + case KC_MUTE: + keycode_str = "Mute\0"; + break; + case KC_VOLU: + keycode_str = "VolUp\0"; + break; + case KC_VOLD: + keycode_str = "VolD\0"; + break; + case KC_MNXT: + keycode_str = "Next\0"; + break; + case KC_MPRV: + keycode_str = "Prev\0"; + break; + case KC_MSTP: + keycode_str = "Stop\0"; + break; + case KC_MPLY: + keycode_str = "Play\0"; + break; + case QK_MODS ... QK_MODS_MAX: + keycode_str = "MOD()\0"; + break; + case QK_MOD_TAP ... QK_MOD_TAP_MAX: + keycode_str = "MT()\0"; + break; + case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: + keycode_str = "LT()\0"; + break; + case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: + keycode_str = "LM()\0"; + break; + case QK_TO ... QK_TO_MAX: + keycode_str = "TO()\0"; + break; + case QK_MOMENTARY ... QK_MOMENTARY_MAX: + keycode_str = "MO()\0"; + break; + case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: + keycode_str = "DF()\0"; + break; + case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: + keycode_str = "TG()\0"; + break; + case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_MOD_MAX: + keycode_str = "1SHOT\0"; + break; + case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: + keycode_str = "TT()\0"; + break; + case QK_PERSISTENT_DEF_LAYER ... QK_PERSISTENT_DEF_LAYER_MAX: + keycode_str = "PDF()\0"; + break; + case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX: + keycode_str = "SWAP\0"; + break; + case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: + keycode_str = "TD()\0"; + break; + case QK_MAGIC ... QK_MAGIC_MAX: + keycode_str = "Magic\0"; + break; + case QK_MIDI ... QK_MIDI_MAX: + keycode_str = "Midi\0"; + break; + case QK_SEQUENCER ... QK_SEQUENCER_MAX: + keycode_str = "Seq\0"; + break; + case QK_JOYSTICK ... QK_JOYSTICK_MAX: + keycode_str = "Joy\0"; + break; + case QK_PROGRAMMABLE_BUTTON ... QK_PROGRAMMABLE_BUTTON_MAX: + keycode_str = "Prog\0"; + break; + case QK_AUDIO ... QK_AUDIO_MAX: + keycode_str = "Audio\0"; + break; + case QK_STENO ... QK_STENO_MAX: + keycode_str = "Steno\0"; + break; + case QK_MACRO ... QK_MACRO_MAX: + keycode_str = "Macro\0"; + break; + case QK_CONNECTION ... QK_CONNECTION_MAX: + keycode_str = "Conn\0"; + break; + case QK_LIGHTING ... QK_LIGHTING_MAX: + keycode_str = "Light\0"; + break; + case QK_QUANTUM ... QK_QUANTUM_MAX: + keycode_str = "Quant\0"; + break; + case QK_KB ... QK_KB_MAX: + keycode_str = "KB\0"; + break; + case QK_USER ... QK_USER_MAX: + keycode_str = "USER\0"; + break; + case QK_UNICODEMAP ... QK_UNICODEMAP_PAIR_MAX: + keycode_str = "Uni\0"; + break; + default: + keycode_str = "Undef\0"; + break; + } + + return keycode_str; +} + +const char *layer_string(uint32_t layer) { + char *layer_str; + switch (layer) { + case 0: + layer_str = "Zero\0"; + break; + case 1: + layer_str = "One\0"; + break; + case 2: + layer_str = "Two\0"; + break; + case 3: + layer_str = "Three\0"; + break; + case 4: + layer_str = "Four\0"; + break; + case 5: + layer_str = "Five\0"; + break; + case 6: + layer_str = "Six\0"; + break; + case 7: + layer_str = "Seven\0"; + break; + default: + return get_u16_str(layer, ' '); + } + + return layer_str; +} + +bool process_detected_host_os_kb(os_variant_t detected_os) { + if (!process_detected_host_os_user(detected_os)) { + return false; + } + + oled_set_cursor(0, 10); + switch (detected_os) { + case OS_MACOS: + oled_write_ln("MacOS", false); + case OS_IOS: + oled_write_ln("Apple", false); + break; + case OS_WINDOWS: + oled_write_ln("Win", false); + break; + case OS_LINUX: + oled_write_ln("Linux", false); + break; + case OS_UNSURE: + oled_write_ln("Unkno", false); + + break; + } + + return true; +} + +void keyboard_post_init_kb(void) { + if (!is_keyboard_master()) { + render_logo(); + } else { + oled_set_cursor(0, 0); + oled_write("Layer", false); + render_spacer(5); + oled_write_ln(layer_string(get_highest_layer(layer_state)), false); + + oled_set_cursor(0, 4); + oled_write_ln("Key", false); + render_spacer(3); + oled_advance_page(false); + oled_write_ln("None", false); + + oled_set_cursor(0, 8); + oled_write_ln("OS", false); + render_spacer(2); + oled_advance_page(false); + oled_write_ln("Wait", false); + + oled_set_cursor(0, 12); + oled_write_ln("Rate", false); + render_spacer(4); + } + keyboard_post_init_user(); +} + +layer_state_t layer_state_set_kb(layer_state_t state) { + state = layer_state_set_user(state); + oled_set_cursor(0, 2); + oled_write_ln(layer_string(get_highest_layer(state)), false); + return state; +} + +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + current_keycode = keycode; + return process_record_user(keycode, record); +}; + +uint16_t loop_rate = 0; +void housekeeping_task_kb(void) { + if (is_keyboard_master()) { + static uint32_t loop_count = 0; + static fast_timer_t loop_time = 0; + loop_count++; + if (timer_elapsed_fast(loop_time) > 1000) { + loop_time = timer_read_fast(); + loop_rate = loop_count > UINT16_MAX ? UINT16_MAX : loop_count; + loop_count = 0; + if (is_oled_on()) { + oled_set_cursor(0, 14); + oled_write(depad_str(get_u16_str(loop_rate, ' '), ' '), false); + } + } + } + if (is_oled_on() && last_input_activity_elapsed() > OLED_TIMEOUT) { + oled_off(); + } +} + +void oled_reinit_slave(void) { + oled_init(OLED_ROTATION_270); + oled_clear(); + oled_set_cursor(0, 0); + oled_write_ln("WPM", false); + render_spacer(3); + oled_advance_page(false); + oled_write_ln(depad_str(get_u16_str(get_current_wpm(), ' '), ' '), false); + + oled_set_cursor(0, 4); + oled_write_ln("RGB", false); + render_spacer(3); + render_rgb_info(); + + oled_set_cursor(0, 13); + render_small_mb_logo(); +} + +bool oled_task_kb(void) { + if (!oled_task_user()) { + return false; + } + + static uint16_t last_keycode = 0xFF; + static bool oled_slave_init_done = false; + + if (is_keyboard_master()) { + if (last_keycode != current_keycode) { + oled_set_cursor(0, 6); + if (current_keycode < ARRAY_SIZE(basic_codes_to_name)) { + oled_write_char(basic_codes_to_name[current_keycode], false); + oled_advance_page(true); + } else { + oled_write_ln(keycode_string(current_keycode), false); + } + last_keycode = current_keycode; + } + } else { + if (!oled_slave_init_done) { + if (timer_elapsed32(0) > 5000) { + oled_slave_init_done = true; + oled_reinit_slave(); + } + } else { + static uint16_t last_wpm = 0; + if (rgb_matrix_get_hue() != last_hue || rgb_matrix_get_sat() != last_sat || rgb_matrix_get_val() != last_val || rgb_matrix_get_mode() != last_mode) { + render_rgb_info(); + } + if (last_wpm != get_current_wpm()) { + last_wpm = get_current_wpm(); + oled_set_cursor(0, 2); + oled_write_ln(depad_str(get_u16_str(last_wpm, ' '), ' '), false); + } + } + } + + return false; +} diff --git a/keyboards/mechboards/common/post_rules.mk b/keyboards/mechboards/common/post_rules.mk new file mode 100644 index 0000000000..69bbbab9d0 --- /dev/null +++ b/keyboards/mechboards/common/post_rules.mk @@ -0,0 +1,3 @@ +ifeq ($(strip $(OLED_ENABLE)), yes) + SRC += keyboards/mechboards/common/display_oled.c +endif diff --git a/keyboards/mechboards/common/rgb_effects.h b/keyboards/mechboards/common/rgb_effects.h new file mode 100644 index 0000000000..8763d2a007 --- /dev/null +++ b/keyboards/mechboards/common/rgb_effects.h @@ -0,0 +1,54 @@ +// Copyright 2025 Dasky (@daskygit) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#ifdef CONVERTER_ENABLED +# define ENABLE_RGB_MATRIX_ALPHA_MODS +# define ENABLE_RGB_MATRIX_BREATHING +# define ENABLE_RGB_MATRIX_COLORBAND_PINWHEEL_SAT +# define ENABLE_RGB_MATRIX_COLORBAND_PINWHEEL_VAL +# define ENABLE_RGB_MATRIX_COLORBAND_SAT +# define ENABLE_RGB_MATRIX_COLORBAND_SPIRIAL_SAT +# define ENABLE_RGB_MATRIX_COLORBAND_SPIRIAL_VAL +# define ENABLE_RGB_MATRIX_COLORBAND_VAL +# define ENABLE_RGB_MATRIX_CYCLE_ALL +# define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT +# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN +# define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL +# define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL +# define ENABLE_RGB_MATRIX_CYCLE_SPIRAL +# define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN +# define ENABLE_RGB_MATRIX_DIGITAL_RAIN +# define ENABLE_RGB_MATRIX_DUAL_BEACON +# define ENABLE_RGB_MATRIX_FLOWER_BLOOMING +# define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT +# define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN +# define ENABLE_RGB_MATRIX_HUE_BREATHING +# define ENABLE_RGB_MATRIX_HUE_PENDULUM +# define ENABLE_RGB_MATRIX_HUE_WAVE +# define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS +# define ENABLE_RGB_MATRIX_PIXEL_FLOW +# define ENABLE_RGB_MATRIX_PIXEL_FRACTAL +# define ENABLE_RGB_MATRIX_PIXEL_RAIN +# define ENABLE_RGB_MATRIX_RAINBOW_BEACON +# define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON +# define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS +# define ENABLE_RGB_MATRIX_RAINDROPS +# define ENABLE_RGB_MATRIX_RIVERFLOW +# define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE +# define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE +# define ENABLE_RGB_MATRIX_SOLID_SPLASH +# define ENABLE_RGB_MATRIX_SPLASH +# define ENABLE_RGB_MATRIX_STARLIGHT +# define ENABLE_RGB_MATRIX_STARLIGHT_DUAL_HUE +# define ENABLE_RGB_MATRIX_STARLIGHT_DUAL_SAT +# define ENABLE_RGB_MATRIX_TYPING_HEATMAP +#endif |