diff --git a/keyboards/lily58/keymaps/poz/config.h b/keyboards/lily58/keymaps/poz/config.h new file mode 100644 index 0000000000..4256495aeb --- /dev/null +++ b/keyboards/lily58/keymaps/poz/config.h @@ -0,0 +1,66 @@ +/* +This is the c configuration file for the keymap + +Copyright 2012 Jun Wako +Copyright 2015 Jack Humbert + +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 + +/* Select hand configuration */ + +// #define MASTER_LEFT +#define MASTER_RIGHT +// #define EE_HANDS + +#define SPLIT_TRANSACTION_IDS_USER SYNC_KEYPRESSES + +#define QUICK_TAP_TERM 0 +#define TAPPING_TERM 100 + +#undef RGBLIGHT_LED_COUNT +#define RGBLIGHT_EFFECT_BREATHING +#define RGBLIGHT_EFFECT_RAINBOW_MOOD +#define RGBLIGHT_EFFECT_RAINBOW_SWIRL +#define RGBLIGHT_EFFECT_SNAKE +#define RGBLIGHT_EFFECT_KNIGHT +#define RGBLIGHT_EFFECT_CHRISTMAS +#define RGBLIGHT_EFFECT_STATIC_GRADIENT +#define RGBLIGHT_EFFECT_RGB_TEST +#define RGBLIGHT_EFFECT_ALTERNATING +#define RGBLIGHT_EFFECT_TWINKLE +#define RGBLIGHT_LED_COUNT 27 +#define RGBLIGHT_LIMIT_VAL 120 +#define RGBLIGHT_HUE_STEP 10 +#define RGBLIGHT_SAT_STEP 17 +#define RGBLIGHT_VAL_STEP 17 + +#define ENCODER_A_PINS { F5 } +#define ENCODER_B_PINS { F4 } +#define ENCODER_RESOLUTION 4 + +#define ENCODER_A_PINS_RIGHT { F4 } +#define ENCODER_B_PINS_RIGHT { F5 } +#define ENCODER_RESOLUTION_RIGHT 4 + +#define MOUSEKEY_INITIAL_SPEED 250 + +// Underglow +/* +#undef RGBLIGHT_LED_COUNT +#define RGBLIGHT_LED_COUNT 14 // Number of LEDs +#define RGBLIGHT_SLEEP +*/ diff --git a/keyboards/lily58/keymaps/poz/features/etchamouse.c b/keyboards/lily58/keymaps/poz/features/etchamouse.c new file mode 100644 index 0000000000..e1d4c38e81 --- /dev/null +++ b/keyboards/lily58/keymaps/poz/features/etchamouse.c @@ -0,0 +1,101 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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 . + */ + +#include QMK_KEYBOARD_H +#include "etchamouse.h" +#include "pointing_device.h" + +#if defined(POINTING_DEVICE_ENABLE) && defined(ENCODER_ENABLE) + +/** Track movement separately in both directions. This will allow us to + * smooth out the movement along diagonals + */ +typedef struct { + bool clockwise : 1; + uint8_t count : 7; + uint16_t timer : 16; + uint16_t elapsed : 16; +} key_tracker_t; + +static key_tracker_t tracker_x = {false, 0, 0, 0}; +static key_tracker_t tracker_y = {false, 0, 0, 0}; + +/** + * @brief Calculate the mouse move units for the given tracker. + * + * By using a key tracker rederence, we can minimize the amount of space + * required on the stack. As we will have the tracker object, we will also + * take the clockwise direction into account, which completely internalizes + * the movement unit logic within this single function. + * + * @param tracker: Pointer to a key tracker object. + * @return A integer from -127 to 127 + */ +static int8_t move_unit(key_tracker_t *tracker) { + if (0 == tracker->count) return 0; + + const uint16_t modifier = TAPPING_TERM_MOUSE_ENCODER < tracker->elapsed ? 1 : (TAPPING_TERM_MOUSE_ENCODER - tracker->elapsed) >> 1; + uint16_t speed = MOUSEKEY_INITIAL_SPEED + MOUSEKEY_MOVE_DELTA * modifier * (tracker->count >> 1); + + /* convert speed to USB mouse speed 1 to 127 */ + speed = (uint8_t)(speed / (1000.0f / MOUSEKEY_INTERVAL)); + speed = speed < 1 ? 1 : speed; + + return (tracker->clockwise ? 1 : -1) * (speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed); +} + +/** + * @brief Update key press tracker + * + * Update the time elapsed since the last keypress. + * If the key has not been pressed since the tapping term, then reset the count to zero. + * If the key was pressed, update the timer and increment the count. + * Number of keypresses will degrade based on tapping term and zero out based + * on the persistenc term. + * + * @param tracker: The object to update + * @param pressed: A boolean indicating whether or not the key was pressed + * @return None. + */ +static void update_tracker(key_tracker_t *tracker, bool pressed, bool clockwise) { + tracker->elapsed = timer_elapsed(tracker->timer); + if (pressed) { + tracker->timer = timer_read(); + tracker->count += 1; + tracker->clockwise = clockwise; + } else if (TAPPING_TERM_PERSISTENCE < tracker->elapsed) { + tracker->count = 0; + } else if (TAPPING_TERM_MOUSE_ENCODER < tracker->elapsed) { + tracker->count >>= 1; + } +} + +bool encoder_update_mouse(uint8_t index, bool clockwise) { + report_mouse_t curr_report = pointing_device_get_report(); + + update_tracker(&tracker_x, 0 == index, clockwise); + update_tracker(&tracker_y, 1 == index, clockwise); + + curr_report.x += move_unit(&tracker_x); + curr_report.y += move_unit(&tracker_y); + + pointing_device_set_report(curr_report); + pointing_device_send(); + + return true; +} + +#endif diff --git a/keyboards/lily58/keymaps/poz/features/etchamouse.h b/keyboards/lily58/keymaps/poz/features/etchamouse.h new file mode 100644 index 0000000000..86b0d03c6e --- /dev/null +++ b/keyboards/lily58/keymaps/poz/features/etchamouse.h @@ -0,0 +1,59 @@ +/* Copyright 2020 Stephen J. Bush + * + * 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 + +#if defined(POINTING_DEVICE_ENABLE) && defined(ENCODER_ENABLE) + +/* max value on report descriptor */ +# ifndef MOUSEKEY_MOVE_MAX +# define MOUSEKEY_MOVE_MAX 127 +# elif MOUSEKEY_MOVE_MAX > 127 +# error MOUSEKEY_MOVE_MAX needs to be smaller than 127 +# endif +# ifndef MOUSEKEY_MOVE_DELTA +# define MOUSEKEY_MOVE_DELTA 25 +# endif +# ifndef MOUSEKEY_INITIAL_SPEED +# define MOUSEKEY_INITIAL_SPEED 100 +# endif +# ifndef MOUSEKEY_INTERVAL +# define MOUSEKEY_INTERVAL 75 +# endif + +/** Amount of time (ms) before zeroing out the count. + * A higher value will result in smoother curves but may lower accuracy + */ +# ifndef TAPPING_TERM_PERSISTENCE +# define TAPPING_TERM_PERSISTENCE 150 +# endif + +/** Amount of time (ms) to register consecutive key presses + * A higher value will smooth out mouse movement and increase speed for + * consecutive presses. + */ +# ifndef TAPPING_TERM_MOUSE_ENCODER +# define TAPPING_TERM_MOUSE_ENCODER 50 +# endif + +/** @brief Update mouse position based on encoder movement. + * @param index The encoder index. 0 controls x-axis; 1 controls y-axis. + * @param clockwise Indicates direction encoder was turned. + * @returns None. + */ +bool encoder_update_mouse(uint8_t index, bool clockwise); + +#endif diff --git a/keyboards/lily58/keymaps/poz/keymap.c b/keyboards/lily58/keymaps/poz/keymap.c new file mode 100644 index 0000000000..6c5fa25f55 --- /dev/null +++ b/keyboards/lily58/keymaps/poz/keymap.c @@ -0,0 +1,221 @@ +#include QMK_KEYBOARD_H + +#include "features/etchamouse.h" +#include + +enum layer_number { + _BASE = 0, + _LOWER, + _RAISE, + _ADJUST, +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* QWERTY + * ,-----------------------------------------. ,-----------------------------------------. + * | ESC | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | ` | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | Tab | Q | W | E | R | T | | Y | U | I | O | P | - | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * |LCTRL | A | S | D | F | G |-------. ,-------| H | J | K | L | ; | ' | + * |------+------+------+------+------+------|MS_BTN1| |MS_BTN2|------+------+------+------+------+------| + * |LShift| Z | X | C | V | B |-------| |-------| N | M | , | . | / | RAlt | + * `-----------------------------------------/ / \ \-----------------------------------------' + * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI | + * | | | |/ / \ \ | | | | + * `----------------------------' '------''--------------------' + */ + +[_BASE] = 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, MS_BTN1, MS_BTN2, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RALT, + KC_LALT, KC_LGUI, MO(_LOWER), KC_SPC, KC_ENT, MO(_RAISE), KC_BSPC, KC_RGUI +), +/* LOWER + * ,-----------------------------------------. ,-----------------------------------------. + * | | | | | | | | | | | | | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | ` | ! | @ | # | $ | % |-------. ,-------| ^ | & | * | ( | ) | - | + * |------+------+------+------+------+------|MS_BTN1| |MS_BTN2|------+------+------+------+------+------| + * | | | | | | |-------| |-------| | _ | + | { | } | | | + * `-----------------------------------------/ / \ \-----------------------------------------' + * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI | + * | | | |/ / \ \ | | | | + * `----------------------------' '------''--------------------' + */ +[_LOWER] = 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, + _______, _______, _______, _______, _______, _______, _______, _______ +), +/* RAISE + * ,-----------------------------------------. ,-----------------------------------------. + * | | | | | | | | | | | | | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | F1 | F2 | F3 | F4 | F5 | F6 |-------. ,-------| Left | Down | Up |Right | | | + * |------+------+------+------+------+------|MS_BTN1| |MS_BTN2|------+------+------+------+------+------| + * | F7 | F8 | F9 | F10 | F11 | F12 |-------| |-------| + | - | = | [ | ] | \ | + * `-----------------------------------------/ / \ \-----------------------------------------' + * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI | + * | | | |/ / \ \ | | | | + * `----------------------------' '------''--------------------' + */ + +[_RAISE] = 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, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, XXXXXXX, 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, + _______, _______, _______, _______, _______, _______, _______, _______ +), +/* ADJUST + * ,-----------------------------------------. ,-----------------------------------------. + * | | | | | | | | | | | | | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | | | | | | | | | | | | | | + * |------+------+------+------+------+------| |------+------+------+------+------+------| + * | | | | | | |-------. ,-------| | |RGB ON| HUE+ | SAT+ | VAL+ | + * |------+------+------+------+------+------| | | |------+------+------+------+------+------| + * | | | | | | |-------| |-------| | | MODE | HUE- | SAT- | VAL- | + * `-----------------------------------------/ / \ \-----------------------------------------' + * | LAlt | LGUI |LOWER | /Space / \Enter \ |RAISE |BackSP| RGUI | + * | | | |/ / \ \ | | | | + * `----------------------------' '------''--------------------' + */ + [_ADJUST] = 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, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + _______, _______, _______, _______, _______, _______, _______, _______ + ) +}; + +layer_state_t layer_state_set_user(layer_state_t state) { + return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); +} + +//SSD1306 OLED update loop, make sure to enable OLED_ENABLE=yes in rules.mk +#ifdef OLED_ENABLE + +typedef struct { + uint32_t z; + uint32_t x; +} keypresses_t; + +keypresses_t keypresses; + +void sync_handler(uint8_t in_buflen, const void *in_data, uint8_t out_buflen, void *out_data) { + const keypresses_t *m2s = (const keypresses_t *)in_data; + keypresses.z = m2s->z; + keypresses.x = m2s->x; +} + +void keyboard_post_init_user(void) { + keypresses.z = 0; + keypresses.x = 0; + transaction_register_rpc(SYNC_KEYPRESSES, sync_handler); +} + +oled_rotation_t oled_init_user(oled_rotation_t rotation) { + if (is_keyboard_master()) + return OLED_ROTATION_180; // flips the display 180 degrees if master + return rotation; +} + +const char *read_layer_state(void); + +void render_wpm(void) { + oled_set_cursor(0,1); { + uint8_t n = get_current_wpm(); + char wpm_counter[4]; + wpm_counter[3] = '\0'; + wpm_counter[2] = '0' + n % 10; + wpm_counter[1] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' '; + wpm_counter[0] = n / 10 ? '0' + n / 10 : ' '; + oled_write_P(PSTR("WPM: "), false); + oled_write(wpm_counter, false); + } + oled_set_cursor(0,3); { + oled_write_ln(read_layer_state(), false); + } +} + +void render_keypress_count(void) { + oled_set_cursor(0, 1); { + oled_write_P(PSTR("Z: "), false); + char buf[11]; + sprintf(buf, "%ld", keypresses.z); + buf[10] = '\0'; + oled_write_ln(buf, false); + } + oled_set_cursor(0, 3); { + oled_write_P(PSTR("X: "), false); + char buf[11]; + sprintf(buf, "%ld", keypresses.x); + buf[10] = '\0'; + oled_write_ln(buf, false); + } +} + +bool oled_task_user(void) { + if (is_keyboard_left()) { + render_keypress_count(); + } else { + render_wpm(); + } + return false; +} + +#endif // OLED_ENABLE + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + #ifdef OLED_ENABLE + if (record->event.pressed) { + switch (keycode) { + case KC_Z: + keypresses.z += 1; + transaction_rpc_send(SYNC_KEYPRESSES, sizeof(keypresses), &keypresses); + return true; + case KC_X: + keypresses.x += 1; + transaction_rpc_send(SYNC_KEYPRESSES, sizeof(keypresses), &keypresses); + return true; + } + } + #endif // OLED_ENABLE + return true; +} + +#ifdef ENCODER_ENABLE +bool encoder_update_user(uint8_t index, bool clockwise) { +#ifdef POINTING_DEVICE_ENABLE + encoder_update_mouse(index, clockwise); +#endif + // // left board + // if (index == 0) { + // if (clockwise) { + // tap_code(MS_RGHT); + // } else { + // tap_code(MS_LEFT); + // } + // // right board + // } else if (index == 1) { + // if (clockwise) { + // tap_code(MS_DOWN); + // } else { + // tap_code(MS_UP); + // } + // } + return false; +} +#endif diff --git a/keyboards/lily58/keymaps/poz/readme.md b/keyboards/lily58/keymaps/poz/readme.md new file mode 100644 index 0000000000..ce60ca2a5a --- /dev/null +++ b/keyboards/lily58/keymaps/poz/readme.md @@ -0,0 +1,14 @@ +# poz + +the poz (layout) + +encoders used as mouse - encoder rotation control an axis (left - x; right - y), press used for mouse click + +left oled has `x` and `z` press count (osu!) + +right oled has the current wpm and layer + +`features/etchamouse.{c,h}` taken from the PR linked in [this gist](https://gist.github.com/muppetjones/bd7e7ff9bd4c503b37f567289a356721) + +[etchamouse.c](https://github.com/muppetjones/qmk_firmware/blob/7573994e640207e03184c69502dba8b351fad3cd/users/muppetjones/features/etchamouse.c) +[etchamouse.h](https://github.com/muppetjones/qmk_firmware/blob/7573994e640207e03184c69502dba8b351fad3cd/users/muppetjones/features/etchamouse.h) diff --git a/keyboards/lily58/keymaps/poz/rules.mk b/keyboards/lily58/keymaps/poz/rules.mk new file mode 100644 index 0000000000..d207f6f66a --- /dev/null +++ b/keyboards/lily58/keymaps/poz/rules.mk @@ -0,0 +1,20 @@ +LTO_ENABLE = yes # Link Time Optimization enabled +BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite +MOUSEKEY_ENABLE = no # Mouse keys +EXTRAKEY_ENABLE = no # Audio control and System control +CONSOLE_ENABLE = no # Console for debug +COMMAND_ENABLE = no # Commands for debug and configuration +NKRO_ENABLE = no # N-Key Rollover +BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality +AUDIO_ENABLE = no # Audio output +RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. +SWAP_HANDS_ENABLE = no # Enable one-hand typing +OLED_ENABLE = yes # OLED display +WPM_ENABLE = yes # WPM calculation +ENCODER_ENABLE = yes # Encoders (knobs) +MOUSEKEY_ENABLE = yes # Use encoders to move cursor +POINTING_DEVICE_ENABLE = yes # For Etch-A-Mouse +POINTING_DEVICE_DRIVER = custom # For Etch-A-Mouse + +SRC += ./lib/layer_state_reader.c \ + ./features/etchamouse.c \