diff --git a/keyboards/mlego/m4/keymaps/default/keymap.c b/keyboards/mlego/m4/keymaps/default/keymap.c new file mode 100644 index 000000000000..2679c36028ee --- /dev/null +++ b/keyboards/mlego/m4/keymaps/default/keymap.c @@ -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 + diff --git a/keyboards/mlego/m4/keymaps/default/rules.mk b/keyboards/mlego/m4/keymaps/default/rules.mk new file mode 100644 index 000000000000..ee325681483f --- /dev/null +++ b/keyboards/mlego/m4/keymaps/default/rules.mk @@ -0,0 +1 @@ +ENCODER_MAP_ENABLE = yes diff --git a/keyboards/mlego/m4/keymaps/default_adv/config.h b/keyboards/mlego/m4/keymaps/default_adv/config.h new file mode 100644 index 000000000000..703e8b146525 --- /dev/null +++ b/keyboards/mlego/m4/keymaps/default_adv/config.h @@ -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 diff --git a/keyboards/mlego/m4/keymaps/default_adv/keymap.c b/keyboards/mlego/m4/keymaps/default_adv/keymap.c new file mode 100644 index 000000000000..0a4afd34985e --- /dev/null +++ b/keyboards/mlego/m4/keymaps/default_adv/keymap.c @@ -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 +} diff --git a/keyboards/mlego/m4/keymaps/default_adv/rules.mk b/keyboards/mlego/m4/keymaps/default_adv/rules.mk new file mode 100644 index 000000000000..ee325681483f --- /dev/null +++ b/keyboards/mlego/m4/keymaps/default_adv/rules.mk @@ -0,0 +1 @@ +ENCODER_MAP_ENABLE = yes diff --git a/keyboards/mlego/m4/m4.c b/keyboards/mlego/m4/m4.c new file mode 100644 index 000000000000..5b51e837a290 --- /dev/null +++ b/keyboards/mlego/m4/m4.c @@ -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); + } +} diff --git a/keyboards/mlego/m4/m4.h b/keyboards/mlego/m4/m4.h new file mode 100644 index 000000000000..a06fa2486107 --- /dev/null +++ b/keyboards/mlego/m4/m4.h @@ -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 +} diff --git a/keyboards/mlego/m4/readme.md b/keyboards/mlego/m4/readme.md new file mode 100644 index 000000000000..c21458ab41c8 --- /dev/null +++ b/keyboards/mlego/m4/readme.md @@ -0,0 +1,60 @@ +# M4 + +![M4](https://i.imgur.com/1rrREGY.jpg) + +A (2x2) ortholinear keyboard that can be hand wired or using a pcb. + +* Keyboard Maintainer: [Alin Elena](https://github.com/alinelena) ([@drFaustroll on GitLab](https://gitlab.com/drFaustroll)) +* Hardware Supported: custom pcb [see](https://mlego.elena.space/m4/ seeeduino xiao rp2040, rev2) +* Hardware Availability: [custom how to](https://mlego.elena.space) + + +Make example for this keyboard (after setting up your build environment): + + make mlego/m4/rev2:default + +Flashing example for this keyboard: + + make mlego/m4/rev2:default + +To enter flashing mode, press Lower+Raise+2 also on microcontroller keep pressed BOOT with mcu unpowered and then power, release BOOT after 1-2s. device will appear as a mass storage device and copy the uf2 + +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). + + +## Pins for rev2 + +| Rows | C0 | C1 | Pins | +| :---: | :---: | :---: | :---: | +| R0 | 1 | 2 | D0-GP26| +| R1 | Lwr | Rse | D3-GP29| +| Pins |SR1-QA |SR2-QA | | + +SRx - shift register x + +### Encoders: + + - Pad_A: D1 - GP27 + - Pad_B: D2 - GP28 + +### Oled + + - SDA: D4-GP6 + - SCL: D5-GP7 + +### 74HC595 + + - data: D10 - GP3 + - latch: D7 - GP1 + = clock: D8 - GP2 + +### Leds + +| Leds | Pin | +| ----------- | --- | +| NUM_LOCK | GP17 | +| CAPS_LOCK | GP25 | +| SCROLL_LOCK | GP16 | +| RBG_DI | GP12 | + +rgb power on GP11 diff --git a/keyboards/mlego/m4/rev2/config.h b/keyboards/mlego/m4/rev2/config.h new file mode 100644 index 000000000000..9d1faf2a092f --- /dev/null +++ b/keyboards/mlego/m4/rev2/config.h @@ -0,0 +1,89 @@ +/* +Copyright 2021-2022 Alin M Elena + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#pragma once +#define MATRIX_ROWS 2 +#define MATRIX_COLS 2 + +/* +ShiftRegister SN74HC595N + +1 +QB |1 16| VCC +QC |2 15| QA +QD |3 14| SER data +QE |4 13| OE +QF |5 12| RCLK latch +QG |6 11| SRCLK clock +QH |7 10| SRCLR + G |8 9 | QH* + +2 +QB |1 16| VCC +QC |2 15| QA +QD |3 14| SER +QE |4 13| OE +QF |5 12| RCLK +QG |6 11| SRCLK +QH |7 10| SRCLR + G |8 9 | QH* + +SRCLR - 10 to VCC - 16 +1QH* - 9 (on first) to 2SER - 14 (on second) +common 1SRCLK-2SRCLK, 1RCLK-2RCLK between the two +OE - G +It uses four pins from the MCU to provide 16 output pins */ +/* Shift Register Clock/Latch configuration (MCU to ShiftRegister.RCLK - 12) */ +/* Shift Register SPI Data Out configuration (MCU to ShiftRegister.SER - 14) */ +/* Shift Register SPI Serial Clock configuration (MCU to ShiftRegister.SRCLK - 11) */ + +#define ROWS \ + { GP26, GP29 } + +#define SPI_DRIVER SPID0 +#define SPI_LATCH_PIN GP1 +#define SPI_SCK_PIN GP2 +#define SPI_MISO_PIN GP4 +#define SPI_MOSI_PIN GP3 +#define SPI_DIVISOR 32 +#define SPI_MODE 3 +#define SPI_lsbFirst true +#define DEBUG_MATRIX_SCAN_RATE + +// 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000 +// 1QA 1QB 1QC 1QD 1QE 1QF 1QG 1QH 2QA 2QB 2QC 2QD 2QE 2QF 2QG 2QH + +// C0 C1 +// 1QA 2QA +#define COLS \ + { 0x0001, 0x0100 } + +#define RGB_ENABLE_PIN GP11 + +#define LED_LWR_PIN GP16 +#define LED_RSE_PIN GP17 + +/* Double tap reset button to enter bootloader */ +#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET +#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED GP17 +#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 500U + +#define I2C1_SCL_PIN GP7 +#define I2C1_SDA_PIN GP6 +#define I2C_DRIVER I2CD1 +#define OLED_BRIGHTNESS 128 +#define OLED_FONT_H "keyboards/mlego/m65/lib/glcdfont.c" diff --git a/keyboards/mlego/m4/rev2/halconf.h b/keyboards/mlego/m4/rev2/halconf.h new file mode 100644 index 000000000000..27fea71d1756 --- /dev/null +++ b/keyboards/mlego/m4/rev2/halconf.h @@ -0,0 +1,12 @@ +// Copyright 2022 alin m elena (@alinelena) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#define HAL_USE_I2C TRUE +#define HAL_USE_SPI TRUE +#define SPI_USE_WAIT TRUE +#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD + +#define SERIAL_USB_BUFFERS_SIZE 256 +#include_next diff --git a/keyboards/mlego/m4/rev2/info.json b/keyboards/mlego/m4/rev2/info.json new file mode 100644 index 000000000000..b3a1378fd8b3 --- /dev/null +++ b/keyboards/mlego/m4/rev2/info.json @@ -0,0 +1,76 @@ +{ + "manufacturer": "Alin Elena", + "keyboard_name": "mlego/m4 rev2", + "maintainer": "alin elena", + "processor": "RP2040", + "bootloader": "rp2040", + "board":"GENERIC_RP_RP2040", + "debounce": 10, + "diode_direction": "COL2ROW", + "encoder": { + "rotary": [ + { + "pin_a": "GP27", + "pin_b": "GP28" + } + ] + }, + "features": { + "audio": false, + "backlight": false, + "bootmagic": true, + "command": false, + "console": false, + "encoder": true, + "extrakey": true, + "mousekey": true, + "nkro": true, + "oled": true, + "rgblight": true, + "wpm": true + }, + "indicators": { + "caps_lock": "GP25", + "on_state": 0 + }, + "ws2812": { + "pin": "GP12", + "driver":"vendor" + }, + "rgblight": { + "animations": { + "alternating": true, + "breathing": true, + "christmas": true, + "knight": true, + "rainbow_mood": true, + "rainbow_swirl": true, + "rgb_test": true, + "snake": true, + "static_gradient": true, + "twinkle": true + }, + "layers": { + "enabled": true + }, + "led_count": 1, + "max_brightness": 64 + + }, + "url": "mlego.elena.space/m4", + "usb": { + "device_version": "0.0.1", + "pid": "0x6560", + "vid": "0xBABA" + }, + "layouts": { + "LAYOUT_ortho_2x2": { + "layout": [ + { "label": "2", "matrix": [0, 0], "x": 0, "y": 0 }, + { "label": "4", "matrix": [0, 1], "x": 1, "y": 0 }, + { "label": "Lower", "matrix": [1, 0], "x": 0, "y": 1 }, + { "label": "Raise", "matrix": [1, 1], "x": 1, "y": 1 } + ] + } + } +} diff --git a/keyboards/mlego/m4/rev2/matrix.c b/keyboards/mlego/m4/rev2/matrix.c new file mode 100644 index 000000000000..3b6589ba09e6 --- /dev/null +++ b/keyboards/mlego/m4/rev2/matrix.c @@ -0,0 +1,73 @@ +// Copyright 2022-2023 alin m elena (@alinelena) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "quantum.h" + +#include "wait.h" +#include "spi_master.h" + +#ifdef CONSOLE_ENABLE +# include "print.h" +#endif + +static const uint16_t col_values[MATRIX_COLS] = COLS; +static const pin_t row_pins[MATRIX_ROWS] = ROWS; + +static const int msize = MATRIX_ROWS * sizeof(matrix_row_t); +static matrix_row_t prev_matrix[MATRIX_ROWS]; + +static inline uint8_t read_rows(void) { + uint8_t r = readPin(row_pins[0]); + + for (uint8_t row = 1; row < MATRIX_ROWS; row++) { + r |= (readPin(row_pins[row]) << row); + } + return r; +} + +static inline void shift_out(uint16_t value) { + uint8_t message[2] = {(value >> 8) & 0xFF, (uint8_t)(value & 0xFF)}; + + // writePinLow(SPI_LATCH_PIN); + spi_start(SPI_LATCH_PIN, SPI_lsbFirst, SPI_MODE, SPI_DIVISOR); + spi_transmit(message, 2); + spi_stop(); + // writePinHigh(SPI_LATCH_PIN); + // matrix_output_select_delay(); +} + +static inline void select_col(uint8_t col) { + shift_out(col_values[col]); +} + +void matrix_init_custom(void) { +#ifdef CONSOLE_ENABLE + wait_ms(3000); +#endif + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + setPinInputLow(row_pins[row]); + } + matrix_io_delay(); + spi_init(); + matrix_io_delay(); + + setPinOutput(SPI_LATCH_PIN); + // spi_start(SPI_LATCH_PIN, true, 3, SPI_DIVISOR); + matrix_io_delay(); +} + +bool matrix_scan_custom(matrix_row_t current_matrix[]) { + memset(current_matrix, 0, msize); + + for (uint8_t col = 0; col < MATRIX_COLS; col++) { + select_col(col); + + uint8_t rows = read_rows(); + for (uint8_t row = 0; row < MATRIX_ROWS; row++) { + current_matrix[row] |= (((rows & (1 << row)) ? 1 : 0) << col); + } + } + bool changed = (memcmp(current_matrix, prev_matrix, msize) != 0); + memcpy(prev_matrix, current_matrix, msize); + return changed; +} diff --git a/keyboards/mlego/m4/rev2/mcuconf.h b/keyboards/mlego/m4/rev2/mcuconf.h new file mode 100644 index 000000000000..20b555d4438b --- /dev/null +++ b/keyboards/mlego/m4/rev2/mcuconf.h @@ -0,0 +1,11 @@ +// Copyright 2022 alin m elena (@alinelena) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include_next +#undef RP_I2C_USE_I2C1 +#define RP_I2C_USE_I2C1 TRUE + +#undef RP_SPI_USE_SPI0 +#define RP_SPI_USE_SPI0 TRUE diff --git a/keyboards/mlego/m4/rev2/readme.md b/keyboards/mlego/m4/rev2/readme.md new file mode 100644 index 000000000000..016f85508709 --- /dev/null +++ b/keyboards/mlego/m4/rev2/readme.md @@ -0,0 +1,2 @@ +main ideas in here +https://mehmedbasic.dk/post/74hc595-keyboard/ diff --git a/keyboards/mlego/m4/rev2/rules.mk b/keyboards/mlego/m4/rev2/rules.mk new file mode 100644 index 000000000000..81b4a0d96253 --- /dev/null +++ b/keyboards/mlego/m4/rev2/rules.mk @@ -0,0 +1,4 @@ +CUSTOM_MATRIX = lite + +SRC += matrix.c +QUANTUM_LIB_SRC += spi_master.c