aboutsummaryrefslogtreecommitdiff
path: root/keyboards/mechboards
diff options
context:
space:
mode:
authorDasky <[email protected]>2025-02-28 19:07:51 +0000
committerGitHub <[email protected]>2025-02-28 11:07:51 -0800
commita4d86a63f2b9a075648ac02f4e20582f418a332a (patch)
tree18b1c139de90bcd39fcde280ddf61b828c0e8b9a /keyboards/mechboards
parenta63fd7f01cdabd9ce85bb09ae2b573fd3b8e60aa (diff)
downloadqmk_firmware-a4d86a63f2b9a075648ac02f4e20582f418a332a.tar.gz
qmk_firmware-a4d86a63f2b9a075648ac02f4e20582f418a332a.zip
Add Mechboards Lily58 variant and common code. (#24937)
* Add lily58 and common code * Apply suggestions from code review Co-authored-by: jack <[email protected]> * Apply suggestions from code review Co-authored-by: jack <[email protected]> --------- Co-authored-by: jack <[email protected]>
Diffstat (limited to 'keyboards/mechboards')
-rw-r--r--keyboards/mechboards/common/display_oled.c385
-rw-r--r--keyboards/mechboards/common/post_rules.mk3
-rw-r--r--keyboards/mechboards/common/rgb_effects.h54
-rw-r--r--keyboards/mechboards/lily58/pro/config.h6
-rw-r--r--keyboards/mechboards/lily58/pro/keyboard.json206
-rw-r--r--keyboards/mechboards/lily58/pro/keymaps/default/keymap.c51
-rw-r--r--keyboards/mechboards/lily58/pro/keymaps/default/rules.mk1
-rw-r--r--keyboards/mechboards/lily58/pro/post_rules.mk1
-rw-r--r--keyboards/mechboards/lily58/pro/pro.c15
-rw-r--r--keyboards/mechboards/lily58/pro/readme.md25
10 files changed, 747 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
diff --git a/keyboards/mechboards/lily58/pro/config.h b/keyboards/mechboards/lily58/pro/config.h
new file mode 100644
index 0000000000..43a4b3eb9f
--- /dev/null
+++ b/keyboards/mechboards/lily58/pro/config.h
@@ -0,0 +1,6 @@
+// Copyright 2025 Dasky (@daskygit)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "keyboards/mechboards/common/rgb_effects.h"
diff --git a/keyboards/mechboards/lily58/pro/keyboard.json b/keyboards/mechboards/lily58/pro/keyboard.json
new file mode 100644
index 0000000000..d655377f19
--- /dev/null
+++ b/keyboards/mechboards/lily58/pro/keyboard.json
@@ -0,0 +1,206 @@
+{
+ "manufacturer": "Mechboards",
+ "keyboard_name": "Lily58 Pro",
+ "maintainer": "dasky",
+ "build": {
+ "lto": true
+ },
+ "development_board": "promicro",
+ "diode_direction": "COL2ROW",
+ "encoder": {
+ "rotary": [
+ {"pin_a": "F5", "pin_b": "F4"}
+ ]
+ },
+ "features": {
+ "bootmagic": true,
+ "encoder": true,
+ "extrakey": true,
+ "mousekey": true,
+ "oled": true,
+ "os_detection": true,
+ "rgb_matrix": true,
+ "wpm": true
+ },
+ "matrix_pins": {
+ "cols": ["F6", "F7", "B1", "B3", "B2", "B6"],
+ "rows": ["C6", "D7", "E6", "B4", "B5"]
+ },
+ "rgb_matrix": {
+ "animations": {
+ "cycle_left_right": true
+ },
+ "default": {
+ "animation": "cycle_left_right"
+ },
+ "driver": "ws2812",
+ "layout": [
+ {"matrix": [0, 5], "x": 72, "y": 4, "flags": 4},
+ {"matrix": [0, 4], "x": 58, "y": 2, "flags": 4},
+ {"matrix": [0, 3], "x": 43, "y": 0, "flags": 4},
+ {"matrix": [0, 2], "x": 29, "y": 2, "flags": 4},
+ {"matrix": [0, 1], "x": 14, "y": 6, "flags": 4},
+ {"matrix": [0, 0], "x": 0, "y": 8, "flags": 4},
+ {"matrix": [1, 0], "x": 0, "y": 23, "flags": 4},
+ {"matrix": [1, 1], "x": 14, "y": 21, "flags": 4},
+ {"matrix": [1, 2], "x": 29, "y": 17, "flags": 4},
+ {"matrix": [1, 3], "x": 43, "y": 15, "flags": 4},
+ {"matrix": [1, 4], "x": 58, "y": 17, "flags": 4},
+ {"matrix": [1, 5], "x": 72, "y": 19, "flags": 4},
+ {"matrix": [2, 5], "x": 72, "y": 34, "flags": 4},
+ {"matrix": [2, 4], "x": 58, "y": 32, "flags": 4},
+ {"matrix": [2, 3], "x": 43, "y": 30, "flags": 4},
+ {"matrix": [2, 2], "x": 29, "y": 32, "flags": 4},
+ {"matrix": [2, 1], "x": 14, "y": 36, "flags": 4},
+ {"matrix": [2, 0], "x": 0, "y": 38, "flags": 4},
+ {"matrix": [3, 0], "x": 0, "y": 53, "flags": 4},
+ {"matrix": [3, 1], "x": 14, "y": 51, "flags": 4},
+ {"matrix": [3, 2], "x": 29, "y": 47, "flags": 4},
+ {"matrix": [3, 3], "x": 43, "y": 45, "flags": 4},
+ {"matrix": [3, 4], "x": 58, "y": 47, "flags": 4},
+ {"matrix": [3, 5], "x": 72, "y": 49, "flags": 4},
+ {"matrix": [4, 5], "x": 87, "y": 41, "flags": 4},
+ {"matrix": [4, 4], "x": 87, "y": 64, "flags": 4},
+ {"matrix": [4, 3], "x": 65, "y": 64, "flags": 4},
+ {"matrix": [4, 2], "x": 51, "y": 62, "flags": 4},
+ {"matrix": [4, 1], "x": 36, "y": 62, "flags": 4},
+ {"x": 96, "y": 64, "flags": 2},
+ {"x": 32, "y": 64, "flags": 2},
+ {"x": 0, "y": 64, "flags": 2},
+ {"x": 0, "y": 32, "flags": 2},
+ {"x": 16, "y": 0, "flags": 2},
+ {"x": 50, "y": 0, "flags": 2},
+ {"x": 80, "y": 0, "flags": 2},
+ {"x": 96, "y": 32, "flags": 2},
+ {"matrix": [5, 5], "x": 152, "y": 4, "flags": 4},
+ {"matrix": [5, 4], "x": 166, "y": 2, "flags": 4},
+ {"matrix": [5, 3], "x": 181, "y": 0, "flags": 4},
+ {"matrix": [5, 2], "x": 195, "y": 2, "flags": 4},
+ {"matrix": [5, 1], "x": 210, "y": 6, "flags": 4},
+ {"matrix": [5, 0], "x": 224, "y": 8, "flags": 4},
+ {"matrix": [6, 0], "x": 224, "y": 23, "flags": 4},
+ {"matrix": [6, 1], "x": 210, "y": 21, "flags": 4},
+ {"matrix": [6, 2], "x": 195, "y": 17, "flags": 4},
+ {"matrix": [6, 3], "x": 181, "y": 15, "flags": 4},
+ {"matrix": [6, 4], "x": 166, "y": 17, "flags": 4},
+ {"matrix": [6, 5], "x": 152, "y": 19, "flags": 4},
+ {"matrix": [7, 5], "x": 152, "y": 34, "flags": 4},
+ {"matrix": [7, 4], "x": 166, "y": 32, "flags": 4},
+ {"matrix": [7, 3], "x": 181, "y": 30, "flags": 4},
+ {"matrix": [7, 2], "x": 195, "y": 32, "flags": 4},
+ {"matrix": [7, 1], "x": 210, "y": 36, "flags": 4},
+ {"matrix": [7, 0], "x": 224, "y": 38, "flags": 4},
+ {"matrix": [8, 0], "x": 224, "y": 53, "flags": 4},
+ {"matrix": [8, 1], "x": 210, "y": 51, "flags": 4},
+ {"matrix": [8, 2], "x": 195, "y": 47, "flags": 4},
+ {"matrix": [8, 3], "x": 181, "y": 45, "flags": 4},
+ {"matrix": [8, 4], "x": 166, "y": 47, "flags": 4},
+ {"matrix": [8, 5], "x": 152, "y": 49, "flags": 4},
+ {"matrix": [9, 5], "x": 137, "y": 41, "flags": 4},
+ {"matrix": [9, 4], "x": 137, "y": 64, "flags": 4},
+ {"matrix": [9, 3], "x": 159, "y": 64, "flags": 4},
+ {"matrix": [9, 2], "x": 173, "y": 62, "flags": 4},
+ {"matrix": [9, 1], "x": 188, "y": 62, "flags": 4},
+ {"x": 128, "y": 64, "flags": 2},
+ {"x": 192, "y": 64, "flags": 2},
+ {"x": 224, "y": 64, "flags": 2},
+ {"x": 224, "y": 32, "flags": 2},
+ {"x": 206, "y": 0, "flags": 2},
+ {"x": 150, "y": 0, "flags": 2},
+ {"x": 140, "y": 0, "flags": 2},
+ {"x": 128, "y": 32, "flags": 2}
+ ],
+ "max_brightness": 120,
+ "sleep": true,
+ "split_count": [37, 37]
+ },
+ "rgblight": {
+ "max_brightness": 120
+ },
+ "split": {
+ "enabled": true,
+ "serial": {
+ "pin": "D2"
+ },
+ "transport": {
+ "sync": {
+ "matrix_state": true,
+ "oled": true,
+ "wpm": true
+ }
+ }
+ },
+ "url": "mechboards.co.uk",
+ "usb": {
+ "device_version": "1.0.0",
+ "pid": "0x0002",
+ "vid": "0x7171"
+ },
+ "ws2812": {
+ "pin": "D3"
+ },
+ "layouts": {
+ "LAYOUT": {
+ "layout": [
+ {"matrix": [0, 0], "x": 0, "y": 0.5},
+ {"matrix": [0, 1], "x": 1, "y": 0.375},
+ {"matrix": [0, 2], "x": 2, "y": 0.125},
+ {"matrix": [0, 3], "x": 3, "y": 0},
+ {"matrix": [0, 4], "x": 4, "y": 0.125},
+ {"matrix": [0, 5], "x": 5, "y": 0.25},
+ {"matrix": [5, 5], "x": 10.5, "y": 0.25},
+ {"matrix": [5, 4], "x": 11.5, "y": 0.125},
+ {"matrix": [5, 3], "x": 12.5, "y": 0},
+ {"matrix": [5, 2], "x": 13.5, "y": 0.125},
+ {"matrix": [5, 1], "x": 14.5, "y": 0.375},
+ {"matrix": [5, 0], "x": 15.5, "y": 0.5},
+ {"matrix": [1, 0], "x": 0, "y": 1.5},
+ {"matrix": [1, 1], "x": 1, "y": 1.375},
+ {"matrix": [1, 2], "x": 2, "y": 1.125},
+ {"matrix": [1, 3], "x": 3, "y": 1},
+ {"matrix": [1, 4], "x": 4, "y": 1.125},
+ {"matrix": [1, 5], "x": 5, "y": 1.25},
+ {"matrix": [6, 5], "x": 10.5, "y": 1.25},
+ {"matrix": [6, 4], "x": 11.5, "y": 1.125},
+ {"matrix": [6, 3], "x": 12.5, "y": 1},
+ {"matrix": [6, 2], "x": 13.5, "y": 1.125},
+ {"matrix": [6, 1], "x": 14.5, "y": 1.375},
+ {"matrix": [6, 0], "x": 15.5, "y": 1.5},
+ {"matrix": [2, 0], "x": 0, "y": 2.5},
+ {"matrix": [2, 1], "x": 1, "y": 2.375},
+ {"matrix": [2, 2], "x": 2, "y": 2.125},
+ {"matrix": [2, 3], "x": 3, "y": 2},
+ {"matrix": [2, 4], "x": 4, "y": 2.125},
+ {"matrix": [2, 5], "x": 5, "y": 2.25},
+ {"matrix": [7, 5], "x": 10.5, "y": 2.25},
+ {"matrix": [7, 4], "x": 11.5, "y": 2.125},
+ {"matrix": [7, 3], "x": 12.5, "y": 2},
+ {"matrix": [7, 2], "x": 13.5, "y": 2.125},
+ {"matrix": [7, 1], "x": 14.5, "y": 2.375},
+ {"matrix": [7, 0], "x": 15.5, "y": 2.5},
+ {"matrix": [3, 0], "x": 0, "y": 3.5},
+ {"matrix": [3, 1], "x": 1, "y": 3.375},
+ {"matrix": [3, 2], "x": 2, "y": 3.125},
+ {"matrix": [3, 3], "x": 3, "y": 3},
+ {"matrix": [3, 4], "x": 4, "y": 3.125},
+ {"matrix": [3, 5], "x": 5, "y": 3.25},
+ {"matrix": [4, 5], "x": 6, "y": 2.75},
+ {"matrix": [9, 5], "x": 9.5, "y": 2.75},
+ {"matrix": [8, 5], "x": 10.5, "y": 3.25},
+ {"matrix": [8, 4], "x": 11.5, "y": 3.125},
+ {"matrix": [8, 3], "x": 12.5, "y": 3},
+ {"matrix": [8, 2], "x": 13.5, "y": 3.125},
+ {"matrix": [8, 1], "x": 14.5, "y": 3.375},
+ {"matrix": [8, 0], "x": 15.5, "y": 3.5},
+ {"matrix": [4, 1], "x": 2.5, "y": 4.125},
+ {"matrix": [4, 2], "x": 3.5, "y": 4.15},
+ {"matrix": [4, 3], "x": 4.5, "y": 4.25},
+ {"matrix": [4, 4], "x": 6, "y": 4.25, "h": 1.5},
+ {"matrix": [9, 4], "x": 9.5, "y": 4.25, "h": 1.5},
+ {"matrix": [9, 3], "x": 11, "y": 4.25},
+ {"matrix": [9, 2], "x": 12, "y": 4.15},
+ {"matrix": [9, 1], "x": 13, "y": 4.15}
+ ]
+ }
+ }
+}
diff --git a/keyboards/mechboards/lily58/pro/keymaps/default/keymap.c b/keyboards/mechboards/lily58/pro/keymaps/default/keymap.c
new file mode 100644
index 0000000000..6c23650b05
--- /dev/null
+++ b/keyboards/mechboards/lily58/pro/keymaps/default/keymap.c
@@ -0,0 +1,51 @@
+// Copyright 2025 Dasky (@daskygit)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+// clang-format off
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+ [0] = LAYOUT(
+ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_GRV,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_MINS,
+ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC, KC_RBRC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
+ KC_LALT, KC_LGUI, MO(1), KC_SPC, KC_ENT, MO(2), KC_BSPC, KC_RGUI
+),
+
+[1] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______,_______, _______, _______,
+ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12,
+ KC_GRV, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_TILD,
+ _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
+ _______, _______, _______, _______, _______, MO(3), _______, _______
+),
+
+
+[2] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______,
+ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, XXXXXXX,
+ KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, KC_PLUS, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
+ _______, _______, MO(3), _______, _______, _______, _______, _______
+),
+
+ [3] = LAYOUT(
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ RM_TOGG, RM_HUEU, RM_SATU, RM_VALU, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ RM_NEXT, RM_HUED, RM_SATD, RM_VALD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
+ _______, _______, _______, _______, _______, _______, _______, _______
+ )
+};
+
+#if defined(ENCODER_MAP_ENABLE)
+const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
+ [0] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU), ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
+ [1] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS), ENCODER_CCW_CW(KC_TRNS, KC_TRNS)},
+ [2] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS), ENCODER_CCW_CW(KC_TRNS, KC_TRNS)},
+ [3] = { ENCODER_CCW_CW(KC_TRNS, KC_TRNS), ENCODER_CCW_CW(KC_TRNS, KC_TRNS)}
+};
+#endif
+// clang-format on
diff --git a/keyboards/mechboards/lily58/pro/keymaps/default/rules.mk b/keyboards/mechboards/lily58/pro/keymaps/default/rules.mk
new file mode 100644
index 0000000000..ee32568148
--- /dev/null
+++ b/keyboards/mechboards/lily58/pro/keymaps/default/rules.mk
@@ -0,0 +1 @@
+ENCODER_MAP_ENABLE = yes
diff --git a/keyboards/mechboards/lily58/pro/post_rules.mk b/keyboards/mechboards/lily58/pro/post_rules.mk
new file mode 100644
index 0000000000..4bfdc8ca89
--- /dev/null
+++ b/keyboards/mechboards/lily58/pro/post_rules.mk
@@ -0,0 +1 @@
+include keyboards/mechboards/common/post_rules.mk
diff --git a/keyboards/mechboards/lily58/pro/pro.c b/keyboards/mechboards/lily58/pro/pro.c
new file mode 100644
index 0000000000..34c1f6409e
--- /dev/null
+++ b/keyboards/mechboards/lily58/pro/pro.c
@@ -0,0 +1,15 @@
+// Copyright 2025 Dasky (@daskygit)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "quantum.h"
+
+#ifdef OLED_ENABLE
+void render_logo(void) {
+ static const char PROGMEM pro_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, 254, 252, 0, 0, 0, 248, 248, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 0, 0, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 248, 24, 24, 24, 24, 24, 24, 0, 0, 240, 248, 24, 24, 24, 24, 24, 248, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 249, 249, 0, 0, 255, 255, 0, 0, 248, 248, 0, 0, 0, 0, 248, 248, 0, 0, 7, 7, 6, 6, 6, 6, 254, 252, 0, 0, 251, 255, 6, 6, 6, 6, 6, 255, 251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 3, 3, 0, 0, 3, 3, 0, 0, 131, 131, 131, 131, 131, 131,
+ 255, 255, 0, 0, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 225, 240, 48, 176, 176, 112, 240, 48, 176, 176, 112, 240, 112, 176, 176, 112, 240, 224, 0, 0, 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, 127, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 63, 48, 61, 61, 62, 63, 48, 61, 61, 50, 63, 56, 55, 55, 56, 63, 31, 0, 0,
+ };
+ oled_write_raw_P(pro_logo, sizeof(pro_logo));
+}
+#endif
diff --git a/keyboards/mechboards/lily58/pro/readme.md b/keyboards/mechboards/lily58/pro/readme.md
new file mode 100644
index 0000000000..9ec83c2800
--- /dev/null
+++ b/keyboards/mechboards/lily58/pro/readme.md
@@ -0,0 +1,25 @@
+# Lily58 Pro
+
+A refreshed Lily58 PCB with RGB, battery, power switch and encoder support.
+
+* Keyboard Maintainer: [dasky](https://github.com/daskygit)
+* Hardware Supported: Controllers using promicro footprint.
+* Hardware Availability: https://mechboards.co.uk
+
+Make example for this keyboard (after setting up your build environment):
+
+ qmk compile -kb mechboards/lily58/pro -km default
+
+Flashing example for this keyboard:
+
+ qmk flash -kb mechboards/lily58/pro -km default
+
+See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
+
+## Bootloader
+
+Enter the bootloader in 3 ways:
+
+* **Bootmagic reset**: Hold down the top left key (for left half) or top right key (for right half) when plugging in USB.
+* **Physical reset button**: Briefly double press the button below the TRRS socket.
+* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available