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

add m4, small test board for various matrix styles #20227

Closed
wants to merge 17 commits into from
Closed
36 changes: 36 additions & 0 deletions keyboards/mlego/m4/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2022-2023 alin m elena (@alinelena)
// SPDX-License-Identifier: GPL-2.0-or-later

#include QMK_KEYBOARD_H

// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

[_QW] = LAYOUT_ortho_2x2(
KC_2 , KC_4 ,
TT(_LWR), TT(_RSE)),

[_LWR] = LAYOUT_ortho_2x2(
RGB_TOG, KC_3 ,
_______, _______ ),

[_RSE] = LAYOUT_ortho_2x2(
KC_5 , KC_6 ,
_______, _______),

[_ADJ] = LAYOUT_ortho_2x2(
RGB_TOG , QK_BOOT ,
_______, _______),

};
// clang-format on

#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
[_QW] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
[_LWR] = {ENCODER_CCW_CW(RGB_HUD, RGB_HUI)},
[_RSE] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)},
[_ADJ] = {ENCODER_CCW_CW(RGB_RMOD, RGB_MOD)},
};
#endif

1 change: 1 addition & 0 deletions keyboards/mlego/m4/keymaps/default/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ENCODER_MAP_ENABLE = yes
5 changes: 5 additions & 0 deletions keyboards/mlego/m4/keymaps/default_adv/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2022-2023 alin m elena (@alinelena)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#define TAPPING_TOGGLE 2
257 changes: 257 additions & 0 deletions keyboards/mlego/m4/keymaps/default_adv/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
// Copyright 2022-2023 alin m elena (@alinelena)
// SPDX-License-Identifier: GPL-2.0-or-later

#include QMK_KEYBOARD_H
#include "print.h"
#include "wait.h"
// let us assume we start with both layers off
static bool toggle_lwr = false;
static bool toggle_rse = false;


#ifdef OLED_ENABLE

static uint32_t oled_logo_timer = 0;
static bool clear_logo = true;
static const char PROGMEM m65_logo[] = {0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0};

#endif

#ifdef RGBLIGHT_ENABLE

const rgblight_segment_t PROGMEM my_qwerty_layer[] = RGBLIGHT_LAYER_SEGMENTS({0, RGBLED_NUM, HSV_PURPLE});
const rgblight_segment_t PROGMEM my_lwr_layer[] = RGBLIGHT_LAYER_SEGMENTS({0, RGBLED_NUM, HSV_CYAN});
const rgblight_segment_t PROGMEM my_rse_layer[] = RGBLIGHT_LAYER_SEGMENTS({0, RGBLED_NUM, HSV_RED});
const rgblight_segment_t PROGMEM my_adj_layer[] = RGBLIGHT_LAYER_SEGMENTS({0, RGBLED_NUM, HSV_GREEN});

const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(my_qwerty_layer, my_lwr_layer, my_rse_layer, my_adj_layer);

#endif

// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

[_QW] = LAYOUT_ortho_2x2(
KC_2 , KC_4 ,
TT(_LWR), TT(_RSE)),

[_LWR] = LAYOUT_ortho_2x2(
RGB_TOG, KC_3 ,
_______, _______ ),

[_RSE] = LAYOUT_ortho_2x2(
KC_5 , KC_6 ,
_______, _______),

[_ADJ] = LAYOUT_ortho_2x2(
RGB_TOG , QK_BOOT ,
_______, _______),

};
// clang-format on

#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {
[_QW] = {ENCODER_CCW_CW(KC_VOLD, KC_VOLU)},
[_LWR] = {ENCODER_CCW_CW(RGB_HUD, RGB_HUI)},
[_RSE] = {ENCODER_CCW_CW(RGB_VAD, RGB_VAI)},
[_ADJ] = {ENCODER_CCW_CW(RGB_RMOD, RGB_MOD)},
};
#endif

void matrix_scan_user(void) {
toggle_leds(toggle_lwr, toggle_rse);
}

bool process_record_user(uint16_t keycode, keyrecord_t* record) {
// If console is enabled, it will print the matrix position and status of each key pressed
#ifdef CONSOLE_ENABLE
uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %u, time: %5u, int: %u, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count);
#endif
switch (keycode) {
case (TT(_LWR)):
if (!record->event.pressed && record->tap.count == TAPPING_TOGGLE) {
// This runs before the TT() handler toggles the layer state, so the current layer state is the opposite of the final one after toggle.
set_led_toggle(_LWR, !layer_state_is(_LWR));
}
return true;
break;
case (TT(_RSE)):
if (record->event.pressed && record->tap.count == TAPPING_TOGGLE) {
set_led_toggle(_RSE, !layer_state_is(_RSE));
}
return true;
break;
default:
return true;
}
}

layer_state_t layer_state_set_user(layer_state_t state) {
#ifdef RGBLIGHT_ENABLE

set_rgb_layers(state);

#endif

return update_tri_layer_state(state, _LWR, _RSE, _ADJ);
}

#ifdef RGBLIGHT_ENABLE

layer_state_t default_layer_state_set_user(layer_state_t state) {
set_default_rgb_layers(state);
return state;
}

#endif

#ifdef RGBLIGHT_ENABLE

void set_rgb_layers(layer_state_t state) {
rgblight_set_layer_state(0, layer_state_cmp(state, _QW));
rgblight_set_layer_state(1, layer_state_cmp(state, _LWR));
rgblight_set_layer_state(2, layer_state_cmp(state, _RSE));
rgblight_set_layer_state(3, layer_state_cmp(state, _ADJ));
}

void set_default_rgb_layers(layer_state_t state) {
rgblight_set_layer_state(0, layer_state_cmp(state, _QW));
}

const rgblight_segment_t* const* my_rgb(void) {
return my_rgb_layers;
}

#endif

void set_led_toggle(const uint8_t layer, const bool state) {
switch (layer) {
case _LWR:
toggle_lwr = state;
break;
case _RSE:
toggle_rse = state;
break;
default:
break;
}
}

#ifdef OLED_ENABLE

void user_oled_magic(void) {
// Host Keyboard Layer Status
oled_write_P(PSTR("Layer: "), false);

switch (get_highest_layer(layer_state)) {
case _QW:
oled_write_P(PSTR("Default\n"), false);
break;
case _LWR:
oled_write_P(PSTR("Lower\n"), false);
break;
case _RSE:
oled_write_P(PSTR("Raise\n"), false);
break;
case _ADJ:
oled_write_P(PSTR("ADJ\n"), false);
break;
default:
// Or use the write_ln shortcut over adding '\n' to the end of your string
oled_write_ln_P(PSTR("Undefined"), false);
}
// Host Keyboard LED Status
led_t led_state = host_keyboard_led_state();
oled_write_P(led_state.caps_lock ? PSTR("Caps Lock") : PSTR(" "), false);

# ifdef UNICODE_COMMON_ENABLE
oled_write_P(PSTR("\nunicode: "), false);
switch (get_unicode_input_mode()) {
case UC_LNX:
oled_write_P(PSTR("Linux"), false);
break;
case UC_MAC:
oled_write_P(PSTR("apple"), false);
break;
case UC_WIN:
oled_write_P(PSTR("windows"), false);
break;
case UC_WINC:
oled_write_P(PSTR("windows c"), false);
break;
default:
oled_write_ln_P(PSTR("not supported"), false);
}
# endif

# ifdef WPM_ENABLE
oled_write_P(PSTR("\nwpm: "), false);
uint8_t wpm = get_current_wpm();
oled_write_P(wpm != 0 ? get_u8_str(wpm, ' ') : PSTR(" "), false);
# endif
}

void init_timer(void) {
oled_logo_timer = timer_read32();
};

void render_logo(void) {
oled_write_P(m65_logo, false);
}

void clear_screen(void) {
if (clear_logo) {
for (uint8_t i = 0; i < OLED_DISPLAY_HEIGHT; ++i) {
for (uint8_t j = 0; j < OLED_DISPLAY_WIDTH; ++j) {
oled_write_raw_byte(0x0, i * OLED_DISPLAY_WIDTH + j);
}
}
clear_logo = false;
}
}

oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
return OLED_ROTATION_180;
}

# define SHOW_LOGO 5000
bool oled_task_kb(void) {
if (!oled_task_user()) {
return false;
}
if ((timer_elapsed32(oled_logo_timer) < SHOW_LOGO)) {
render_logo();
} else {
clear_screen();
user_oled_magic();
}
return false;
}

#endif

void keyboard_post_init_user(void) {
#ifdef RGBLIGHT_ENABLE
# ifdef RGB_ENABLE_PIN
setPinOutput(RGB_ENABLE_PIN);
writePinHigh(RGB_ENABLE_PIN);
wait_ms(20);
# endif

// Enable the LED layers
rgblight_layers = my_rgb();
#endif

init_lwr_rse_led();

#ifdef CONSOLE_ENABLE
debug_enable = true;
debug_matrix = true;
debug_keyboard = true;
#endif

#ifdef OLED_ENABLE
init_timer();
#endif
}
1 change: 1 addition & 0 deletions keyboards/mlego/m4/keymaps/default_adv/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ENCODER_MAP_ENABLE = yes
13 changes: 13 additions & 0 deletions keyboards/mlego/m4/m4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2022 alin m elena (@alinelena)
// SPDX-License-Identifier: GPL-2.0-or-later

#include "m4.h"

void toggle_leds(const bool toggle_lwr, const bool toggle_rse) {
led_lwr(toggle_lwr);
led_rse(toggle_rse);
if (layer_state_is(_ADJ)) {
led_lwr(true);
led_rse(true);
}
}
49 changes: 49 additions & 0 deletions keyboards/mlego/m4/m4.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2022 alin m elena (@alinelena)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once

#include "quantum.h"

enum layer_names { _QW = 0, _LWR, _RSE, _ADJ };

#ifdef OLED_ENABLE
void user_oled_magic(void);
void render_logo(void);
void clear_screen(void);
void init_timer(void);
#endif

#ifdef RGBLIGHT_ENABLE
void set_rgb_layers(layer_state_t);
const rgblight_segment_t* const* my_rgb(void);
void set_default_rgb_layers(layer_state_t);
#endif

void toggle_leds(const bool, const bool);
void set_led_toggle(const uint8_t, const bool);

static inline void init_lwr_rse_led(void) {
#ifdef LED_LWR_PIN
setPinOutput(LED_LWR_PIN);
writePin(LED_LWR_PIN, false);
wait_ms(30);
#endif

#ifdef LED_RSE_PIN
setPinOutput(LED_RSE_PIN);
writePin(LED_RSE_PIN, false);
wait_ms(30);
#endif
}

static inline void led_lwr(const bool on) {
#ifdef LED_LWR_PIN
writePin(LED_LWR_PIN, !on);
#endif
}

static inline void led_rse(const bool on) {
#ifdef LED_RSE_PIN
writePin(LED_RSE_PIN, !on);
#endif
}
Loading