diff options
| author | Jay Greco <jayv.greco@gmail.com> | 2020-10-22 23:47:14 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-23 17:47:14 +1100 |
| commit | 999326acc81687794e25ad7731f37da59881e0ca (patch) | |
| tree | ceb786ae2dac25486a57c5ed004e921677c922b1 | |
| parent | 8cbaea9e8d00b959ccb1b474fa8a81417b651de2 (diff) | |
| download | qmk_firmware-999326acc81687794e25ad7731f37da59881e0ca.tar.gz qmk_firmware-999326acc81687794e25ad7731f37da59881e0ca.zip | |
Add nullbits nibble (#9250)
* Add NIBBLE keyboard
* Update VID for VIA compatibility
* Add QMK PR feedback
* Update matrix_init_remote_kb()
* Update with requested changes
Clean up config, makefile rules, and keymap files
* Update with changes for unified ANSI/ISO layout
* Add NO_USB_STARTUP_CHECK note in readme
* Add license info, update with PR changes
-Refactor encoder, via_extras code
-Refactor VIA specific code to live in keymap folder
-Remove non-inclusive naming in remote keyboard.c/h
-Add documentation to remote_keyboard.c
-Add compiler check for vusb_detect for non-avr micros
* Fix print formatter in encoder handler
Co-authored-by: Nick Brassel <nick@tzarc.org>
* Small PR updates
-Remove unneded matrix code from nibble.c
-Clean up include code in nibble_encoder.h
* Update Big LED headerfile
-Declare Big LED functions in header file (derp)
* Update keyboards/nullbitsco/nibble/nibble.c
-Update with drashna's suggested CAPS LED code change
Co-authored-by: Drashna Jaelre <drashna@live.com>
* Update keyboards/nullbitsco/nibble/rules.mk
-Update with drasha's suggested makefile formatting changes
Co-authored-by: Drashna Jaelre <drashna@live.com>
* Fix caps_lock typo
Co-authored-by: Nick Brassel <nick@tzarc.org>
Co-authored-by: Drashna Jaelre <drashna@live.com>
21 files changed, 1492 insertions, 0 deletions
diff --git a/keyboards/nullbitsco/nibble/README.md b/keyboards/nullbitsco/nibble/README.md new file mode 100644 index 000000000..92825847d --- /dev/null +++ b/keyboards/nullbitsco/nibble/README.md | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | # NIBBLE | ||
| 2 | |||
| 3 |  | ||
| 4 | |||
| 5 | A unique, tweakable 65% keyboard kit built by nullbits. [More info at nullbits.co](https://nullbits.co/nibble/) | ||
| 6 | |||
| 7 | * Keyboard Maintainer: [Jay Greco](https://github.com/jaygreco) | ||
| 8 | * Hardware Supported: NIBBLE Rev1, Pro Micro comaptible MCUs. | ||
| 9 | * Hardware Availability: [nullbits.co](https://nullbits.co/) | ||
| 10 | |||
| 11 | Note: If you are seeing issues with MacOS and keyboard hangs after sleep, make sure `NO_USB_STARTUP_CHECK = yes` is set in your rules.mk. | ||
| 12 | |||
| 13 | Adds experimental "Remote Keyboard" functionality, which forwards keystrokes from an external macropad, keyboard, or numpad over UART/TRRS, removing the need for an additional USB connection. | ||
| 14 | |||
| 15 | Make example for this keyboard (after setting up your build environment): | ||
| 16 | |||
| 17 | make nullbitsco/nibble:default | ||
| 18 | |||
| 19 | 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). | ||
diff --git a/keyboards/nullbitsco/nibble/big_led.c b/keyboards/nullbitsco/nibble/big_led.c new file mode 100644 index 000000000..eb0d0a507 --- /dev/null +++ b/keyboards/nullbitsco/nibble/big_led.c | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #include "big_led.h" | ||
| 17 | |||
| 18 | void set_big_LED_r(uint8_t mode) { | ||
| 19 | switch(mode) { | ||
| 20 | case LED_ON: | ||
| 21 | setPinOutput(BIG_LED_R_PIN); | ||
| 22 | writePin(BIG_LED_R_PIN, GPIO_STATE_HIGH); | ||
| 23 | break; | ||
| 24 | |||
| 25 | case LED_OFF: | ||
| 26 | setPinOutput(BIG_LED_R_PIN); | ||
| 27 | writePin(BIG_LED_R_PIN, GPIO_STATE_LOW); | ||
| 28 | break; | ||
| 29 | |||
| 30 | default: | ||
| 31 | break; | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | void set_big_LED_g(uint8_t mode) { | ||
| 36 | switch(mode) { | ||
| 37 | case LED_ON: | ||
| 38 | setPinOutput(BIG_LED_G_PIN); | ||
| 39 | writePin(BIG_LED_G_PIN, GPIO_STATE_HIGH); | ||
| 40 | break; | ||
| 41 | |||
| 42 | case LED_OFF: | ||
| 43 | setPinOutput(BIG_LED_G_PIN); | ||
| 44 | writePin(BIG_LED_G_PIN, GPIO_STATE_LOW); | ||
| 45 | break; | ||
| 46 | |||
| 47 | default: | ||
| 48 | break; | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | void set_big_LED_b(uint8_t mode) { | ||
| 53 | switch(mode) { | ||
| 54 | case LED_ON: | ||
| 55 | setPinOutput(BIG_LED_B_PIN); | ||
| 56 | writePin(BIG_LED_B_PIN, GPIO_STATE_HIGH); | ||
| 57 | break; | ||
| 58 | |||
| 59 | case LED_OFF: | ||
| 60 | setPinOutput(BIG_LED_B_PIN); | ||
| 61 | writePin(BIG_LED_B_PIN, GPIO_STATE_LOW); | ||
| 62 | break; | ||
| 63 | |||
| 64 | default: | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | } \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/big_led.h b/keyboards/nullbitsco/nibble/big_led.h new file mode 100644 index 000000000..113aaaf10 --- /dev/null +++ b/keyboards/nullbitsco/nibble/big_led.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | #include "quantum.h" | ||
| 19 | |||
| 20 | /* Optional big LED pins */ | ||
| 21 | #define BIG_LED_R_PIN D7 | ||
| 22 | #define BIG_LED_G_PIN C6 | ||
| 23 | #define BIG_LED_B_PIN D0 | ||
| 24 | |||
| 25 | #define LED_ON 2 | ||
| 26 | #define LED_OFF 0 | ||
| 27 | |||
| 28 | #define GPIO_STATE_LOW 0 | ||
| 29 | #define GPIO_STATE_HIGH 1 | ||
| 30 | |||
| 31 | void | ||
| 32 | set_big_LED_r(uint8_t mode), | ||
| 33 | set_big_LED_g(uint8_t mode), | ||
| 34 | set_big_LED_b(uint8_t mode); \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/bitc_led.c b/keyboards/nullbitsco/nibble/bitc_led.c new file mode 100644 index 000000000..60ffeea27 --- /dev/null +++ b/keyboards/nullbitsco/nibble/bitc_led.c | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #include "bitc_led.h" | ||
| 17 | |||
| 18 | void set_bitc_LED(uint8_t mode) { | ||
| 19 | switch(mode) { | ||
| 20 | case LED_ON: | ||
| 21 | setPinOutput(PIN_LED); | ||
| 22 | writePin(PIN_LED, GPIO_STATE_HIGH); | ||
| 23 | break; | ||
| 24 | |||
| 25 | case LED_DIM: | ||
| 26 | setPinInput(PIN_LED); | ||
| 27 | break; | ||
| 28 | |||
| 29 | case LED_OFF: | ||
| 30 | setPinOutput(PIN_LED); | ||
| 31 | writePin(PIN_LED, GPIO_STATE_LOW); | ||
| 32 | break; | ||
| 33 | |||
| 34 | default: | ||
| 35 | break; | ||
| 36 | } | ||
| 37 | } \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/bitc_led.h b/keyboards/nullbitsco/nibble/bitc_led.h new file mode 100644 index 000000000..b3552a7d1 --- /dev/null +++ b/keyboards/nullbitsco/nibble/bitc_led.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | #include "quantum.h" | ||
| 19 | |||
| 20 | #define LED_ON 2 | ||
| 21 | #define LED_DIM 1 | ||
| 22 | #define LED_OFF 0 | ||
| 23 | |||
| 24 | #define GPIO_STATE_LOW 0 | ||
| 25 | #define GPIO_STATE_HIGH 1 | ||
| 26 | |||
| 27 | #define PIN_LED F0 | ||
| 28 | |||
| 29 | void set_bitc_LED(uint8_t mode); \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/config.h b/keyboards/nullbitsco/nibble/config.h new file mode 100644 index 000000000..3e0adce45 --- /dev/null +++ b/keyboards/nullbitsco/nibble/config.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | #include "config_common.h" | ||
| 19 | |||
| 20 | /* Used to set host for remote KB if VUSB detect doesn't work. */ | ||
| 21 | // #define KEYBOARD_HOST // Force host mode | ||
| 22 | // #define KEYBOARD_REMOTE // Force remote mode | ||
| 23 | |||
| 24 | // Workaround for freezing after MacOS sleep | ||
| 25 | #define NO_USB_STARTUP_CHECK | ||
| 26 | |||
| 27 | /* USB Device descriptor parameter */ | ||
| 28 | #define VENDOR_ID 0x6E61 | ||
| 29 | #define PRODUCT_ID 0x6060 | ||
| 30 | |||
| 31 | #define DEVICE_VER 0x0001 | ||
| 32 | #define MANUFACTURER nullbits | ||
| 33 | #define PRODUCT NIBBLE | ||
| 34 | |||
| 35 | /* key matrix size */ | ||
| 36 | #define MATRIX_ROWS 5 | ||
| 37 | #define MATRIX_COLS 16 | ||
| 38 | #define MATRIX_MUX_COLS 4 | ||
| 39 | |||
| 40 | /* Set 0 if debouncing isn't needed */ | ||
| 41 | #define DEBOUNCE 10 | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Keyboard Matrix Assignments | ||
| 45 | * The nibble uses a demultiplexer for the cols. | ||
| 46 | * to free up more IOs for awesomeness! | ||
| 47 | * See matrix.c for more details. | ||
| 48 | */ | ||
| 49 | #define MATRIX_ROW_PINS { B1, B3, B2, B6, D4 } | ||
| 50 | #define MATRIX_COL_MUX_PINS { F4, F5, F6, F7 } | ||
| 51 | #define MATRIX_COL_PINS { } | ||
| 52 | |||
| 53 | /* Optional SMT LED pins */ | ||
| 54 | #define RGB_DI_PIN E6 | ||
| 55 | #define RGBLED_NUM 10 | ||
| 56 | #define RGBLIGHT_ANIMATIONS | ||
| 57 | #define RGBLIGHT_SLEEP | ||
| 58 | |||
| 59 | /* Optional encoder pins */ | ||
| 60 | #define ENCODERS_PAD_A { B5 } | ||
| 61 | #define ENCODERS_PAD_B { B4 } \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/keymaps/default/keymap.c b/keyboards/nullbitsco/nibble/keymaps/default/keymap.c new file mode 100644 index 000000000..6d453e706 --- /dev/null +++ b/keyboards/nullbitsco/nibble/keymaps/default/keymap.c | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #include QMK_KEYBOARD_H | ||
| 17 | |||
| 18 | #define _MA 0 | ||
| 19 | #define _FN 1 | ||
| 20 | |||
| 21 | enum custom_keycodes { | ||
| 22 | KC_CUST = SAFE_RANGE, | ||
| 23 | }; | ||
| 24 | |||
| 25 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 26 | [_MA] = LAYOUT_ansi( | ||
| 27 | KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_TILD, | ||
| 28 | KC_F13, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, | ||
| 29 | KC_F14, KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, | ||
| 30 | KC_F15, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, | ||
| 31 | KC_F16, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_FN), KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT | ||
| 32 | ), | ||
| 33 | [_FN] = LAYOUT_ansi( | ||
| 34 | RESET, 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_HOME, KC_INS, | ||
| 35 | RGB_TOG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 36 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 37 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 38 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ | ||
| 39 | ), | ||
| 40 | |||
| 41 | }; | ||
| 42 | |||
| 43 | bool process_record_user(uint16_t keycode, keyrecord_t *record) { | ||
| 44 | // Send keystrokes to host keyboard, if connected (see readme) | ||
| 45 | process_record_remote_kb(keycode, record); | ||
| 46 | switch(keycode) { | ||
| 47 | case KC_CUST: //custom macro | ||
| 48 | if (record->event.pressed) { | ||
| 49 | } | ||
| 50 | break; | ||
| 51 | |||
| 52 | case RM_1: //remote macro 1 | ||
| 53 | if (record->event.pressed) { | ||
| 54 | } | ||
| 55 | break; | ||
| 56 | |||
| 57 | case RM_2: //remote macro 2 | ||
| 58 | if (record->event.pressed) { | ||
| 59 | } | ||
| 60 | break; | ||
| 61 | |||
| 62 | case RM_3: //remote macro 3 | ||
| 63 | if (record->event.pressed) { | ||
| 64 | } | ||
| 65 | break; | ||
| 66 | |||
| 67 | case RM_4: //remote macro 4 | ||
| 68 | if (record->event.pressed) { | ||
| 69 | } | ||
| 70 | break; | ||
| 71 | |||
| 72 | } | ||
| 73 | return true; | ||
| 74 | } | ||
| 75 | |||
| 76 | // RGB config, for changing RGB settings on non-VIA firmwares | ||
| 77 | void change_RGB(bool clockwise) { | ||
| 78 | bool shift = get_mods() & MOD_MASK_SHIFT; | ||
| 79 | bool alt = get_mods() & MOD_MASK_ALT; | ||
| 80 | bool ctrl = get_mods() & MOD_MASK_CTRL; | ||
| 81 | |||
| 82 | if (clockwise) { | ||
| 83 | if (alt) { | ||
| 84 | rgblight_increase_hue(); | ||
| 85 | } else if (ctrl) { | ||
| 86 | rgblight_increase_val(); | ||
| 87 | } else if (shift) { | ||
| 88 | rgblight_increase_sat(); | ||
| 89 | } else { | ||
| 90 | rgblight_step(); | ||
| 91 | } | ||
| 92 | |||
| 93 | } else { | ||
| 94 | if (alt) { | ||
| 95 | rgblight_decrease_hue(); | ||
| 96 | } else if (ctrl) { | ||
| 97 | rgblight_decrease_val(); | ||
| 98 | } else if (shift) { | ||
| 99 | rgblight_decrease_sat(); | ||
| 100 | } else { | ||
| 101 | rgblight_step_reverse(); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | void encoder_update_kb(uint8_t index, bool clockwise) { | ||
| 107 | if (layer_state_is(1)) { | ||
| 108 | //change RGB settings | ||
| 109 | change_RGB(clockwise); | ||
| 110 | } | ||
| 111 | else { | ||
| 112 | if (clockwise) { | ||
| 113 | tap_code(KC_VOLU); | ||
| 114 | } else { | ||
| 115 | tap_code(KC_VOLD); | ||
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | void matrix_init_user(void) { | ||
| 121 | // Initialize remote keyboard, if connected (see readme) | ||
| 122 | matrix_init_remote_kb(); | ||
| 123 | } | ||
| 124 | |||
| 125 | void matrix_scan_user(void) { | ||
| 126 | // Scan and parse keystrokes from remote keyboard, if connected (see readme) | ||
| 127 | matrix_scan_remote_kb(); | ||
| 128 | } \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/keymaps/iso/keymap.c b/keyboards/nullbitsco/nibble/keymaps/iso/keymap.c new file mode 100644 index 000000000..46f246d6e --- /dev/null +++ b/keyboards/nullbitsco/nibble/keymaps/iso/keymap.c | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #include QMK_KEYBOARD_H | ||
| 17 | |||
| 18 | #define _MA 0 | ||
| 19 | #define _FN 1 | ||
| 20 | |||
| 21 | enum custom_keycodes { | ||
| 22 | KC_CUST = SAFE_RANGE, | ||
| 23 | }; | ||
| 24 | |||
| 25 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 26 | [_MA] = LAYOUT_iso( | ||
| 27 | KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_TILD, | ||
| 28 | KC_F13, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_DEL, | ||
| 29 | KC_F14, KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, KC_PGUP, | ||
| 30 | KC_F15, KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, | ||
| 31 | KC_F16, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_FN), KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT | ||
| 32 | ), | ||
| 33 | [_FN] = LAYOUT_iso( | ||
| 34 | RESET, 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_HOME, KC_INS, | ||
| 35 | RGB_TOG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 36 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 37 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 38 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ | ||
| 39 | ), | ||
| 40 | |||
| 41 | }; | ||
| 42 | |||
| 43 | bool process_record_user(uint16_t keycode, keyrecord_t *record) { | ||
| 44 | // Send keystrokes to host keyboard, if connected (see readme) | ||
| 45 | process_record_remote_kb(keycode, record); | ||
| 46 | switch(keycode) { | ||
| 47 | case KC_CUST: //custom macro | ||
| 48 | if (record->event.pressed) { | ||
| 49 | } | ||
| 50 | break; | ||
| 51 | |||
| 52 | case RM_1: //remote macro 1 | ||
| 53 | if (record->event.pressed) { | ||
| 54 | } | ||
| 55 | break; | ||
| 56 | |||
| 57 | case RM_2: //remote macro 2 | ||
| 58 | if (record->event.pressed) { | ||
| 59 | } | ||
| 60 | break; | ||
| 61 | |||
| 62 | case RM_3: //remote macro 3 | ||
| 63 | if (record->event.pressed) { | ||
| 64 | } | ||
| 65 | break; | ||
| 66 | |||
| 67 | case RM_4: //remote macro 4 | ||
| 68 | if (record->event.pressed) { | ||
| 69 | } | ||
| 70 | break; | ||
| 71 | |||
| 72 | } | ||
| 73 | return true; | ||
| 74 | } | ||
| 75 | |||
| 76 | // RGB config, for changing RGB settings on non-VIA firmwares | ||
| 77 | void change_RGB(bool clockwise) { | ||
| 78 | bool shift = get_mods() & MOD_MASK_SHIFT; | ||
| 79 | bool alt = get_mods() & MOD_MASK_ALT; | ||
| 80 | bool ctrl = get_mods() & MOD_MASK_CTRL; | ||
| 81 | |||
| 82 | if (clockwise) { | ||
| 83 | if (alt) { | ||
| 84 | rgblight_increase_hue(); | ||
| 85 | } else if (ctrl) { | ||
| 86 | rgblight_increase_val(); | ||
| 87 | } else if (shift) { | ||
| 88 | rgblight_increase_sat(); | ||
| 89 | } else { | ||
| 90 | rgblight_step(); | ||
| 91 | } | ||
| 92 | |||
| 93 | } else { | ||
| 94 | if (alt) { | ||
| 95 | rgblight_decrease_hue(); | ||
| 96 | } else if (ctrl) { | ||
| 97 | rgblight_decrease_val(); | ||
| 98 | } else if (shift) { | ||
| 99 | rgblight_decrease_sat(); | ||
| 100 | } else { | ||
| 101 | rgblight_step_reverse(); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | void encoder_update_kb(uint8_t index, bool clockwise) { | ||
| 107 | if (layer_state_is(1)) { | ||
| 108 | //change RGB settings | ||
| 109 | change_RGB(clockwise); | ||
| 110 | } | ||
| 111 | else { | ||
| 112 | if (clockwise) { | ||
| 113 | tap_code(KC_VOLU); | ||
| 114 | } else { | ||
| 115 | tap_code(KC_VOLD); | ||
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | void matrix_init_user(void) { | ||
| 121 | // Initialize remote keyboard, if connected (see readme) | ||
| 122 | matrix_init_remote_kb(); | ||
| 123 | } | ||
| 124 | |||
| 125 | void matrix_scan_user(void) { | ||
| 126 | // Scan and parse keystrokes from remote keyboard, if connected (see readme) | ||
| 127 | matrix_scan_remote_kb(); | ||
| 128 | } \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/keymaps/via/config.h b/keyboards/nullbitsco/nibble/keymaps/via/config.h new file mode 100644 index 000000000..961e2aed1 --- /dev/null +++ b/keyboards/nullbitsco/nibble/keymaps/via/config.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | // Custom config starts after VIA's EEPROM usage, | ||
| 17 | // dynamic keymaps start after this. | ||
| 18 | // Custom config Usage: | ||
| 19 | // 1 for enabled encoder modes (1 byte) | ||
| 20 | // 6 for 3x custom encoder settings, left, right, and press (18 bytes) | ||
| 21 | #define VIA_EEPROM_CUSTOM_CONFIG_SIZE 19 \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/keymaps/via/keymap.c b/keyboards/nullbitsco/nibble/keymaps/via/keymap.c new file mode 100644 index 000000000..1e1b0c036 --- /dev/null +++ b/keyboards/nullbitsco/nibble/keymaps/via/keymap.c | |||
| @@ -0,0 +1,164 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #include QMK_KEYBOARD_H | ||
| 17 | #include "via_extras.h" | ||
| 18 | |||
| 19 | #define _BASE 0 | ||
| 20 | #define _VIA1 1 | ||
| 21 | #define _VIA2 2 | ||
| 22 | #define _VIA3 3 | ||
| 23 | |||
| 24 | #define KC_DISC_MUTE KC_F23 | ||
| 25 | #define KC_DISC_DEAF KC_F24 | ||
| 26 | #define NUM_CUST_KEYCODES (_NUM_CUST_KCS - SAFE_RANGE) | ||
| 27 | #define VIA_KEYCODE_RANGE 0x5F80 | ||
| 28 | |||
| 29 | enum custom_keycodes { | ||
| 30 | PROG = SAFE_RANGE, | ||
| 31 | DISC_MUTE, | ||
| 32 | DISC_DEAF, | ||
| 33 | SUPER_ALT_TAB, | ||
| 34 | _NUM_CUST_KCS, | ||
| 35 | }; | ||
| 36 | |||
| 37 | // Macro variables | ||
| 38 | bool is_alt_tab_active = false; | ||
| 39 | uint16_t alt_tab_timer = 0; | ||
| 40 | bool muted = false; | ||
| 41 | bool deafened = false; | ||
| 42 | |||
| 43 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
| 44 | [_BASE] = LAYOUT_all( | ||
| 45 | KC_NUBS, KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_HOME, | ||
| 46 | KC_F13, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_DEL, | ||
| 47 | KC_F14, KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_PGUP, | ||
| 48 | KC_F15, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN, | ||
| 49 | KC_F16, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(_VIA1), KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT | ||
| 50 | ), | ||
| 51 | |||
| 52 | [_VIA1] = LAYOUT_all( | ||
| 53 | _______, RESET, 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_HOME, KC_INS, | ||
| 54 | RGB_TOG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 55 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 56 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 57 | _______, _______, _______, _______, _______, _______, _______, _______, KC_MPRV, KC_MPLY, KC_MNXT | ||
| 58 | ), | ||
| 59 | |||
| 60 | [_VIA2] = LAYOUT_all( | ||
| 61 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 62 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 63 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 64 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 65 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ | ||
| 66 | ), | ||
| 67 | |||
| 68 | [_VIA3] = LAYOUT_all( | ||
| 69 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 70 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 71 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 72 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
| 73 | _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ | ||
| 74 | ), | ||
| 75 | |||
| 76 | }; | ||
| 77 | |||
| 78 | void map_via_keycode(uint16_t * keycode) { | ||
| 79 | if (abs(*keycode - VIA_KEYCODE_RANGE) < NUM_CUST_KEYCODES) { //make into macro? | ||
| 80 | dprintf("VIA custom keycode found, mapping to QMK keycode.\n"); | ||
| 81 | uint16_t new_keycode = (*keycode - VIA_KEYCODE_RANGE) + SAFE_RANGE; | ||
| 82 | dprintf("VIA KC: %u QMK KC: %u\n", *keycode, new_keycode); | ||
| 83 | *keycode = new_keycode; | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | bool process_record_user(uint16_t keycode, keyrecord_t *record) { | ||
| 88 | map_via_keycode(&keycode); | ||
| 89 | // Send keystrokes to host keyboard, if connected (see readme) | ||
| 90 | process_record_remote_kb(keycode, record); | ||
| 91 | switch(keycode) { | ||
| 92 | case PROG: | ||
| 93 | if (record->event.pressed) { | ||
| 94 | rgblight_disable_noeeprom(); | ||
| 95 | bootloader_jump(); | ||
| 96 | } | ||
| 97 | break; | ||
| 98 | |||
| 99 | case DISC_MUTE: | ||
| 100 | if (record->event.pressed) { | ||
| 101 | tap_code(KC_DISC_MUTE); | ||
| 102 | if (!rgblight_is_enabled()) break; | ||
| 103 | |||
| 104 | if (muted) { | ||
| 105 | rgblight_enable_noeeprom(); | ||
| 106 | } else { | ||
| 107 | rgblight_timer_disable(); | ||
| 108 | uint8_t val = rgblight_get_val(); | ||
| 109 | rgblight_sethsv_range(255, 255, val, 0, 1); | ||
| 110 | } | ||
| 111 | muted = !muted; | ||
| 112 | } | ||
| 113 | break; | ||
| 114 | |||
| 115 | case DISC_DEAF: | ||
| 116 | if (record->event.pressed) { | ||
| 117 | tap_code(KC_DISC_DEAF); | ||
| 118 | if (!rgblight_is_enabled()) break; | ||
| 119 | |||
| 120 | if (deafened) { | ||
| 121 | rgblight_enable_noeeprom(); | ||
| 122 | } else { | ||
| 123 | rgblight_timer_disable(); | ||
| 124 | uint8_t val = rgblight_get_val(); | ||
| 125 | rgblight_sethsv_range(255, 255, val, 0, RGBLED_NUM-1); | ||
| 126 | } | ||
| 127 | deafened = !deafened; | ||
| 128 | } | ||
| 129 | break; | ||
| 130 | |||
| 131 | case SUPER_ALT_TAB: | ||
| 132 | if (record->event.pressed) { | ||
| 133 | if (!is_alt_tab_active) { | ||
| 134 | is_alt_tab_active = true; | ||
| 135 | register_code(KC_LALT); | ||
| 136 | } | ||
| 137 | alt_tab_timer = timer_read(); | ||
| 138 | register_code(KC_TAB); | ||
| 139 | } else { | ||
| 140 | unregister_code(KC_TAB); | ||
| 141 | } | ||
| 142 | break; | ||
| 143 | |||
| 144 | default: | ||
| 145 | break; | ||
| 146 | } | ||
| 147 | return true; | ||
| 148 | } | ||
| 149 | |||
| 150 | void matrix_init_user(void) { | ||
| 151 | // Initialize remote keyboard, if connected (see readme) | ||
| 152 | matrix_init_remote_kb(); | ||
| 153 | } | ||
| 154 | |||
| 155 | void matrix_scan_user(void) { | ||
| 156 | // Scan and parse keystrokes from remote keyboard, if connected (see readme) | ||
| 157 | matrix_scan_remote_kb(); | ||
| 158 | if (is_alt_tab_active) { | ||
| 159 | if (timer_elapsed(alt_tab_timer) > 1000) { | ||
| 160 | unregister_code(KC_LALT); | ||
| 161 | is_alt_tab_active = false; | ||
| 162 | } | ||
| 163 | } | ||
| 164 | } \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/keymaps/via/nibble_encoder.c b/keyboards/nullbitsco/nibble/keymaps/via/nibble_encoder.c new file mode 100644 index 000000000..bdea1869c --- /dev/null +++ b/keyboards/nullbitsco/nibble/keymaps/via/nibble_encoder.c | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #include "nibble_encoder.h" | ||
| 17 | |||
| 18 | uint8_t encoder_value = 0x20, | ||
| 19 | encoder_mode = ENC_MODE_VOLUME, | ||
| 20 | enabled_encoder_modes = 0x1F; | ||
| 21 | |||
| 22 | uint16_t retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior) { | ||
| 23 | #ifdef DYNAMIC_KEYMAP_ENABLE | ||
| 24 | void* addr = (void*)(EEPROM_CUSTOM_ENCODER + (encoder_idx * 6) + (behavior * 2)); | ||
| 25 | uint16_t keycode = eeprom_read_byte(addr) << 8; | ||
| 26 | keycode |= eeprom_read_byte(addr + 1); | ||
| 27 | return keycode; | ||
| 28 | #else | ||
| 29 | return 0; | ||
| 30 | #endif | ||
| 31 | } | ||
| 32 | |||
| 33 | void set_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior, uint16_t new_code) { | ||
| 34 | #ifdef DYNAMIC_KEYMAP_ENABLE | ||
| 35 | void* addr = (void*)(EEPROM_CUSTOM_ENCODER + (encoder_idx * 6) + (behavior * 2)); | ||
| 36 | eeprom_update_byte(addr, (uint8_t)(new_code >> 8)); | ||
| 37 | eeprom_update_byte(addr + 1, (uint8_t)(new_code & 0xFF)); | ||
| 38 | #endif | ||
| 39 | } | ||
| 40 | |||
| 41 | void pre_encoder_mode_change(void) { | ||
| 42 | dprintf("Changing encoder mode: %u\n", encoder_mode); | ||
| 43 | } | ||
| 44 | |||
| 45 | void post_encoder_mode_change(void) { | ||
| 46 | dprintf("Encoder mode: %u\n", encoder_mode); | ||
| 47 | } | ||
| 48 | |||
| 49 | //??? | ||
| 50 | void change_encoder_mode(bool clockwise) { | ||
| 51 | pre_encoder_mode_change(); | ||
| 52 | if(enabled_encoder_modes == 0){ | ||
| 53 | enabled_encoder_modes = 0x1F; | ||
| 54 | } | ||
| 55 | do { | ||
| 56 | if(!clockwise){ | ||
| 57 | if (encoder_mode == 0){ | ||
| 58 | encoder_mode = _NUM_ENCODER_MODES - 1; | ||
| 59 | } else{ | ||
| 60 | encoder_mode = encoder_mode - 1; | ||
| 61 | } | ||
| 62 | } else { | ||
| 63 | encoder_mode = (encoder_mode + 1) % _NUM_ENCODER_MODES; | ||
| 64 | } | ||
| 65 | } while(((1 << encoder_mode) & enabled_encoder_modes) == 0); | ||
| 66 | post_encoder_mode_change(); | ||
| 67 | } | ||
| 68 | |||
| 69 | uint16_t handle_encoder_cw(void) { | ||
| 70 | dprintf("Encoder mode: %u\n", encoder_mode); | ||
| 71 | uint16_t mapped_code = 0; | ||
| 72 | switch(encoder_mode){ | ||
| 73 | default: | ||
| 74 | break; | ||
| 75 | case ENC_MODE_VOLUME: | ||
| 76 | mapped_code = KC_VOLU; | ||
| 77 | break; | ||
| 78 | case ENC_MODE_MEDIA: | ||
| 79 | mapped_code = KC_MEDIA_NEXT_TRACK; | ||
| 80 | break; | ||
| 81 | case ENC_MODE_SCROLL: | ||
| 82 | mapped_code = KC_WH_D; | ||
| 83 | break; | ||
| 84 | case ENC_MODE_BACKLIGHT: | ||
| 85 | mapped_code = RGB_VAI; | ||
| 86 | break; | ||
| 87 | #ifdef DYNAMIC_KEYMAP_ENABLE | ||
| 88 | case ENC_MODE_CUSTOM0: | ||
| 89 | mapped_code = retrieve_custom_encoder_config(0, ENC_CUSTOM_CW); | ||
| 90 | break; | ||
| 91 | case ENC_MODE_CUSTOM1: | ||
| 92 | mapped_code = retrieve_custom_encoder_config(1, ENC_CUSTOM_CW); | ||
| 93 | break; | ||
| 94 | case ENC_MODE_CUSTOM2: | ||
| 95 | mapped_code = retrieve_custom_encoder_config(2, ENC_CUSTOM_CW); | ||
| 96 | break; | ||
| 97 | #endif | ||
| 98 | } | ||
| 99 | return mapped_code; | ||
| 100 | } | ||
| 101 | |||
| 102 | uint16_t handle_encoder_ccw(void) { | ||
| 103 | dprintf("Encoder mode: %u\n", encoder_mode); | ||
| 104 | uint16_t mapped_code = 0; | ||
| 105 | switch(encoder_mode){ | ||
| 106 | default: | ||
| 107 | break; | ||
| 108 | case ENC_MODE_VOLUME: | ||
| 109 | mapped_code = KC_VOLD; | ||
| 110 | break; | ||
| 111 | case ENC_MODE_MEDIA: | ||
| 112 | mapped_code = KC_MEDIA_PREV_TRACK; | ||
| 113 | break; | ||
| 114 | case ENC_MODE_SCROLL: | ||
| 115 | mapped_code = KC_WH_U; | ||
| 116 | break; | ||
| 117 | case ENC_MODE_BACKLIGHT: | ||
| 118 | mapped_code = RGB_VAD; | ||
| 119 | break; | ||
| 120 | #ifdef DYNAMIC_KEYMAP_ENABLE | ||
| 121 | case ENC_MODE_CUSTOM0: | ||
| 122 | mapped_code = retrieve_custom_encoder_config(0, ENC_CUSTOM_CCW); | ||
| 123 | break; | ||
| 124 | case ENC_MODE_CUSTOM1: | ||
| 125 | mapped_code = retrieve_custom_encoder_config(1, ENC_CUSTOM_CCW); | ||
| 126 | break; | ||
| 127 | case ENC_MODE_CUSTOM2: | ||
| 128 | mapped_code = retrieve_custom_encoder_config(2, ENC_CUSTOM_CCW); | ||
| 129 | break; | ||
| 130 | #endif | ||
| 131 | } | ||
| 132 | return mapped_code; | ||
| 133 | } | ||
diff --git a/keyboards/nullbitsco/nibble/keymaps/via/nibble_encoder.h b/keyboards/nullbitsco/nibble/keymaps/via/nibble_encoder.h new file mode 100644 index 000000000..fc1e61434 --- /dev/null +++ b/keyboards/nullbitsco/nibble/keymaps/via/nibble_encoder.h | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | #include QMK_KEYBOARD_H | ||
| 19 | #include "eeprom.h" | ||
| 20 | |||
| 21 | #define EEPROM_ENABLED_ENCODER_MODES (VIA_EEPROM_CUSTOM_CONFIG_ADDR) | ||
| 22 | #define EEPROM_CUSTOM_ENCODER (VIA_EEPROM_CUSTOM_CONFIG_ADDR+1) | ||
| 23 | |||
| 24 | enum encoder_modes { | ||
| 25 | ENC_MODE_VOLUME, | ||
| 26 | ENC_MODE_MEDIA, | ||
| 27 | ENC_MODE_SCROLL, | ||
| 28 | ENC_MODE_BRIGHTNESS, | ||
| 29 | ENC_MODE_BACKLIGHT, | ||
| 30 | ENC_MODE_CUSTOM0, | ||
| 31 | ENC_MODE_CUSTOM1, | ||
| 32 | ENC_MODE_CUSTOM2, | ||
| 33 | _NUM_ENCODER_MODES, | ||
| 34 | }; | ||
| 35 | |||
| 36 | enum custom_encoder_behavior { | ||
| 37 | ENC_CUSTOM_CW = 0, | ||
| 38 | ENC_CUSTOM_CCW, | ||
| 39 | ENC_CUSTOM_PRESS | ||
| 40 | }; | ||
| 41 | |||
| 42 | uint16_t | ||
| 43 | retrieve_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior), | ||
| 44 | handle_encoder_cw(void), | ||
| 45 | handle_encoder_ccw(void); | ||
| 46 | |||
| 47 | void set_custom_encoder_config(uint8_t encoder_idx, uint8_t behavior, uint16_t new_code), | ||
| 48 | pre_encoder_mode_change(void), | ||
| 49 | post_encoder_mode_change(void), | ||
| 50 | change_encoder_mode(bool clockwise); \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/keymaps/via/rules.mk b/keyboards/nullbitsco/nibble/keymaps/via/rules.mk new file mode 100644 index 000000000..ee197efc0 --- /dev/null +++ b/keyboards/nullbitsco/nibble/keymaps/via/rules.mk | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | VIA_ENABLE = yes | ||
| 2 | |||
| 3 | SRC += keymaps/via/nibble_encoder.c | ||
| 4 | SRC += keymaps/via/via_extras.c \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/keymaps/via/via_extras.c b/keyboards/nullbitsco/nibble/keymaps/via/via_extras.c new file mode 100644 index 000000000..067296b76 --- /dev/null +++ b/keyboards/nullbitsco/nibble/keymaps/via/via_extras.c | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include "via_extras.h" | ||
| 18 | |||
| 19 | // Encoder Behavior | ||
| 20 | extern uint8_t encoder_value; | ||
| 21 | extern uint8_t encoder_mode; | ||
| 22 | extern uint8_t enabled_encoder_modes; | ||
| 23 | |||
| 24 | void raw_hid_receive_kb( uint8_t *data, uint8_t length ) | ||
| 25 | { | ||
| 26 | uint8_t *command_id = &(data[0]); | ||
| 27 | uint8_t *command_data = &(data[1]); | ||
| 28 | dprintf("raw hid recv! command_id: %u\n",*command_id); | ||
| 29 | switch ( *command_id ) | ||
| 30 | { | ||
| 31 | case id_get_keyboard_value: | ||
| 32 | { | ||
| 33 | switch( command_data[0]) | ||
| 34 | { | ||
| 35 | case id_encoder_modes: | ||
| 36 | { | ||
| 37 | command_data[1] = enabled_encoder_modes; | ||
| 38 | dprintf("[read] enabled_encoder_modes: %u\n", enabled_encoder_modes); | ||
| 39 | } | ||
| 40 | break; | ||
| 41 | |||
| 42 | case id_encoder_custom: | ||
| 43 | { | ||
| 44 | uint8_t custom_encoder_idx = command_data[1]; | ||
| 45 | uint16_t keycode = retrieve_custom_encoder_config(custom_encoder_idx, ENC_CUSTOM_CW); | ||
| 46 | command_data[2] = keycode >> 8; | ||
| 47 | command_data[3] = keycode & 0xFF; | ||
| 48 | keycode = retrieve_custom_encoder_config(custom_encoder_idx, ENC_CUSTOM_CCW); | ||
| 49 | command_data[4] = keycode >> 8; | ||
| 50 | command_data[5] = keycode & 0xFF; | ||
| 51 | keycode = retrieve_custom_encoder_config(custom_encoder_idx, ENC_CUSTOM_PRESS); | ||
| 52 | command_data[6] = keycode >> 8; | ||
| 53 | command_data[7] = keycode & 0xFF; | ||
| 54 | } | ||
| 55 | break; | ||
| 56 | |||
| 57 | default: | ||
| 58 | { | ||
| 59 | *command_id = id_unhandled; | ||
| 60 | } | ||
| 61 | break; | ||
| 62 | } | ||
| 63 | } | ||
| 64 | break; | ||
| 65 | case id_set_keyboard_value: | ||
| 66 | { | ||
| 67 | switch(command_data[0]){ | ||
| 68 | case id_encoder_modes: | ||
| 69 | { | ||
| 70 | enabled_encoder_modes = command_data[1]; | ||
| 71 | dprintf("[write] enabled_encoder_modes: %u\n", enabled_encoder_modes); | ||
| 72 | eeprom_update_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES, enabled_encoder_modes); | ||
| 73 | } | ||
| 74 | break; | ||
| 75 | |||
| 76 | case id_encoder_custom: | ||
| 77 | { | ||
| 78 | uint8_t custom_encoder_idx = command_data[1]; | ||
| 79 | uint8_t encoder_behavior = command_data[2]; | ||
| 80 | uint16_t keycode = (command_data[3] << 8) | command_data[4]; | ||
| 81 | set_custom_encoder_config(custom_encoder_idx, encoder_behavior, keycode); | ||
| 82 | } | ||
| 83 | break; | ||
| 84 | |||
| 85 | default: | ||
| 86 | { | ||
| 87 | *command_id = id_unhandled; | ||
| 88 | } | ||
| 89 | break; | ||
| 90 | } | ||
| 91 | } | ||
| 92 | break; | ||
| 93 | |||
| 94 | default: | ||
| 95 | { | ||
| 96 | // Unhandled message. | ||
| 97 | *command_id = id_unhandled; | ||
| 98 | } | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | void encoder_update_kb(uint8_t index, bool clockwise) { | ||
| 104 | if (layer_state_is(1)) { | ||
| 105 | change_encoder_mode(clockwise); | ||
| 106 | return; | ||
| 107 | } | ||
| 108 | uint16_t mapped_code = 0; | ||
| 109 | if (clockwise) { | ||
| 110 | mapped_code = handle_encoder_cw(); | ||
| 111 | } else { | ||
| 112 | mapped_code = handle_encoder_ccw(); | ||
| 113 | } | ||
| 114 | if(mapped_code != 0){ | ||
| 115 | tap_code16(mapped_code); | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | void custom_config_load(void){ | ||
| 120 | #ifdef DYNAMIC_KEYMAP_ENABLE | ||
| 121 | enabled_encoder_modes = eeprom_read_byte((uint8_t*)EEPROM_ENABLED_ENCODER_MODES); | ||
| 122 | #endif | ||
| 123 | } | ||
| 124 | |||
| 125 | void via_init_kb(void) | ||
| 126 | { | ||
| 127 | dprintf("VIA is enabled.\n"); | ||
| 128 | custom_config_load(); | ||
| 129 | } | ||
diff --git a/keyboards/nullbitsco/nibble/keymaps/via/via_extras.h b/keyboards/nullbitsco/nibble/keymaps/via/via_extras.h new file mode 100644 index 000000000..83c3c1312 --- /dev/null +++ b/keyboards/nullbitsco/nibble/keymaps/via/via_extras.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | #include "nibble_encoder.h" | ||
| 19 | #include "via.h" | ||
| 20 | #include "raw_hid.h" | ||
| 21 | #include "dynamic_keymap.h" | ||
| 22 | #include "tmk_core/common/eeprom.h" | ||
| 23 | |||
| 24 | enum nibble_keyboard_value_id { | ||
| 25 | id_encoder_modes = 0x80, | ||
| 26 | id_unused_mode_1, | ||
| 27 | id_encoder_custom, | ||
| 28 | id_unused_mode_2 | ||
| 29 | }; | ||
| 30 | |||
| 31 | // Encoder Behavior | ||
| 32 | extern uint8_t encoder_value, | ||
| 33 | encoder_mode, | ||
| 34 | enabled_encoder_modes; | ||
| 35 | |||
| 36 | void raw_hid_receive_kb(uint8_t *data, uint8_t length), | ||
| 37 | encoder_update_kb(uint8_t index, bool clockwise), | ||
| 38 | custom_config_load(void), | ||
| 39 | via_init_kb(void); \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/matrix.c b/keyboards/nullbitsco/nibble/matrix.c new file mode 100644 index 000000000..8ec9da284 --- /dev/null +++ b/keyboards/nullbitsco/nibble/matrix.c | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #include "quantum.h" | ||
| 17 | |||
| 18 | #define COL_SHIFTER ((uint32_t)1) | ||
| 19 | |||
| 20 | // Column pins | ||
| 21 | static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; | ||
| 22 | static const uint8_t col_pins[MATRIX_MUX_COLS] = MATRIX_COL_MUX_PINS; | ||
| 23 | |||
| 24 | // Internal functions | ||
| 25 | |||
| 26 | static void init_pins(void) { | ||
| 27 | // Set cols to outputs, low | ||
| 28 | for (uint8_t pin = 0; pin < MATRIX_MUX_COLS; pin++) { | ||
| 29 | setPinOutput(col_pins[pin]); | ||
| 30 | } | ||
| 31 | |||
| 32 | // Unselect cols | ||
| 33 | for (uint8_t bit = 0; bit < MATRIX_MUX_COLS; bit++) { | ||
| 34 | writePinLow(col_pins[bit]); | ||
| 35 | } | ||
| 36 | |||
| 37 | // Set rows to input, pullup | ||
| 38 | for (uint8_t pin = 0; pin < MATRIX_ROWS; pin++) { | ||
| 39 | setPinInputHigh(row_pins[pin]); | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | static void select_col(uint8_t col) | ||
| 44 | { | ||
| 45 | for (uint8_t bit = 0; bit < MATRIX_MUX_COLS; bit++) { | ||
| 46 | uint8_t state = (col & (0b1 << bit)) >> bit; | ||
| 47 | writePin(col_pins[bit], state); | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) | ||
| 52 | { | ||
| 53 | bool matrix_changed = false; | ||
| 54 | select_col(current_col); | ||
| 55 | wait_us(5); | ||
| 56 | |||
| 57 | // Read each row sequentially | ||
| 58 | for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) | ||
| 59 | { | ||
| 60 | matrix_row_t last_row_value = current_matrix[row_index]; | ||
| 61 | |||
| 62 | if (!readPin(row_pins[row_index])) | ||
| 63 | { | ||
| 64 | current_matrix[row_index] |= (COL_SHIFTER << current_col); | ||
| 65 | } | ||
| 66 | else | ||
| 67 | { | ||
| 68 | current_matrix[row_index] &= ~(COL_SHIFTER << current_col); | ||
| 69 | } | ||
| 70 | |||
| 71 | if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) | ||
| 72 | { | ||
| 73 | matrix_changed = true; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | return matrix_changed; | ||
| 78 | } | ||
| 79 | |||
| 80 | // Matrix scan functions | ||
| 81 | |||
| 82 | void matrix_init_custom(void) { | ||
| 83 | init_pins(); | ||
| 84 | } | ||
| 85 | |||
| 86 | bool matrix_scan_custom(matrix_row_t current_matrix[]) { | ||
| 87 | bool changed = false; | ||
| 88 | |||
| 89 | //Set col, read rows | ||
| 90 | for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { | ||
| 91 | changed |= read_rows_on_col(current_matrix, current_col); | ||
| 92 | } | ||
| 93 | |||
| 94 | return (uint8_t)changed; | ||
| 95 | } \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/nibble.c b/keyboards/nullbitsco/nibble/nibble.c new file mode 100644 index 000000000..409edd44a --- /dev/null +++ b/keyboards/nullbitsco/nibble/nibble.c | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #include QMK_KEYBOARD_H | ||
| 17 | #include "bitc_led.h" | ||
| 18 | |||
| 19 | // Use Bit-C LED to show CAPS LOCK status | ||
| 20 | bool led_update_kb(led_t led_state) { | ||
| 21 | bool res = led_update_user(led_state); | ||
| 22 | if (res) { | ||
| 23 | set_bitc_LED(led_state.caps_lock ? LED_DIM : LED_OFF); | ||
| 24 | } | ||
| 25 | return res; | ||
| 26 | } | ||
diff --git a/keyboards/nullbitsco/nibble/nibble.h b/keyboards/nullbitsco/nibble/nibble.h new file mode 100644 index 000000000..9744ae745 --- /dev/null +++ b/keyboards/nullbitsco/nibble/nibble.h | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | #define ___ KC_NO | ||
| 19 | |||
| 20 | #include "quantum.h" | ||
| 21 | #include "remote_kb.h" | ||
| 22 | |||
| 23 | #define LAYOUT_all( \ | ||
| 24 | K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G, \ | ||
| 25 | K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G, \ | ||
| 26 | K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2F, K2G, \ | ||
| 27 | K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3F, K3G, \ | ||
| 28 | K41, K42, K43, K44, K47, K4A, K4B, K4C, K4D, K4F, K4G \ | ||
| 29 | ) { \ | ||
| 30 | {K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G}, \ | ||
| 31 | {K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G}, \ | ||
| 32 | {K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, ___, K2F, K2G}, \ | ||
| 33 | {K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, ___, K3F, K3G}, \ | ||
| 34 | {K41, K42, K43, K44, ___, ___, K47, ___, ___, K4A, K4B, K4C, K4D, ___, K4F, K4G}, \ | ||
| 35 | } | ||
| 36 | |||
| 37 | #define LAYOUT_ansi( \ | ||
| 38 | K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G, \ | ||
| 39 | K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G, \ | ||
| 40 | K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2F, K2G, \ | ||
| 41 | K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3F, K3G, \ | ||
| 42 | K41, K42, K43, K44, K47, K4A, K4B, K4C, K4D, K4F, K4G \ | ||
| 43 | ) { \ | ||
| 44 | {___, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G}, \ | ||
| 45 | {K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G}, \ | ||
| 46 | {K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, ___, K2F, K2G}, \ | ||
| 47 | {K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, ___, K3F, K3G}, \ | ||
| 48 | {K41, K42, K43, K44, ___, ___, K47, ___, ___, K4A, K4B, K4C, K4D, ___, K4F, K4G}, \ | ||
| 49 | } | ||
| 50 | |||
| 51 | #define LAYOUT_iso( \ | ||
| 52 | K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G, \ | ||
| 53 | K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1G, \ | ||
| 54 | K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K1F, K2F, K2G, \ | ||
| 55 | K31, K32, K01, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3F, K3G, \ | ||
| 56 | K41, K42, K43, K44, K47, K4A, K4B, K4C, K4D, K4F, K4G \ | ||
| 57 | ) { \ | ||
| 58 | {K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G}, \ | ||
| 59 | {K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G}, \ | ||
| 60 | {K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, ___, K2F, K2G}, \ | ||
| 61 | {K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, ___, K3F, K3G}, \ | ||
| 62 | {K41, K42, K43, K44, ___, ___, K47, ___, ___, K4A, K4B, K4C, K4D, ___, K4F, K4G}, \ | ||
| 63 | } | ||
diff --git a/keyboards/nullbitsco/nibble/remote_kb.c b/keyboards/nullbitsco/nibble/remote_kb.c new file mode 100644 index 000000000..2e36f5f22 --- /dev/null +++ b/keyboards/nullbitsco/nibble/remote_kb.c | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | |||
| 17 | /* | ||
| 18 | Remote keyboard is an experimental feature that allows for connecting another | ||
| 19 | keyboard, macropad, numpad, or accessory without requiring an additional USB connection. | ||
| 20 | The "remote keyboard" forwards its keystrokes using UART serial over TRRS. Dynamic VUSB | ||
| 21 | detect allows the keyboard automatically switch to host or remote mode depending on | ||
| 22 | which is connected to the USB port. | ||
| 23 | |||
| 24 | Possible functionality includes the ability to send data from the host to the remote using | ||
| 25 | a reverse link, allowing for LED sync, configuration, and more data sharing between devices. | ||
| 26 | This will require a new communication protocol, as the current one is limited. | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include "remote_kb.h" | ||
| 30 | |||
| 31 | uint8_t | ||
| 32 | msg[UART_MSG_LEN], | ||
| 33 | msg_idx = 0; | ||
| 34 | |||
| 35 | bool | ||
| 36 | is_host = true; | ||
| 37 | |||
| 38 | // Private functions | ||
| 39 | |||
| 40 | static bool vbus_detect(void) { | ||
| 41 | #if defined(__AVR_ATmega32U4__) | ||
| 42 | //returns true if VBUS is present, false otherwise. | ||
| 43 | USBCON |= (1 << OTGPADE); //enables VBUS pad | ||
| 44 | _delay_us(10); | ||
| 45 | return (USBSTA & (1<<VBUS)); //checks state of VBUS | ||
| 46 | #else | ||
| 47 | #error vbus_detect is not implemented for this architecure! | ||
| 48 | #endif | ||
| 49 | } | ||
| 50 | |||
| 51 | static uint8_t chksum8(const unsigned char *buf, size_t len) { | ||
| 52 | unsigned int sum; | ||
| 53 | for (sum = 0 ; len != 0 ; len--) | ||
| 54 | sum += *(buf++); | ||
| 55 | return (uint8_t)sum; | ||
| 56 | } | ||
| 57 | |||
| 58 | static void send_msg(uint16_t keycode, bool pressed) { | ||
| 59 | msg[IDX_PREAMBLE] = UART_PREAMBLE; | ||
| 60 | msg[IDX_KCLSB] = (keycode & 0xFF); | ||
| 61 | msg[IDX_KCMSB] = (keycode >> 8) & 0xFF; | ||
| 62 | msg[IDX_PRESSED] = pressed; | ||
| 63 | msg[IDX_CHECKSUM] = chksum8(msg, UART_MSG_LEN-1); | ||
| 64 | |||
| 65 | for (int i=0; i<UART_MSG_LEN; i++) { | ||
| 66 | uart_putchar(msg[i]); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | static void print_message_buffer(void) { | ||
| 71 | for (int i=0; i<UART_MSG_LEN; i++) { | ||
| 72 | dprintf("msg[%u]: %u\n", i, msg[i]); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | static void process_uart(void) { | ||
| 77 | uint8_t chksum = chksum8(msg, UART_MSG_LEN-1); | ||
| 78 | if (msg[IDX_PREAMBLE] != UART_PREAMBLE || msg[IDX_CHECKSUM] != chksum) { | ||
| 79 | dprintf("UART checksum mismatch!\n"); | ||
| 80 | print_message_buffer(); | ||
| 81 | dprintf("calc checksum: %u\n", chksum); | ||
| 82 | } else { | ||
| 83 | uint16_t keycode = (uint16_t)msg[IDX_KCLSB] | ((uint16_t)msg[IDX_KCMSB] << 8); | ||
| 84 | bool pressed = (bool)msg[IDX_PRESSED]; | ||
| 85 | if (IS_RM_KC(keycode)) { | ||
| 86 | keyrecord_t record; | ||
| 87 | record.event.pressed = pressed; | ||
| 88 | if (pressed) dprintf("Remote macro: press [%u]\n", keycode); | ||
| 89 | else dprintf("Remote macro: release [%u]\n", keycode); | ||
| 90 | process_record_user(keycode, &record); | ||
| 91 | } else { | ||
| 92 | if (pressed) { | ||
| 93 | dprintf("Remote: press [%u]\n", keycode); | ||
| 94 | register_code(keycode); | ||
| 95 | } else { | ||
| 96 | dprintf("Remote: release [%u]\n", keycode); | ||
| 97 | unregister_code(keycode); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | static void get_msg(void) { | ||
| 104 | while (uart_available()) { | ||
| 105 | msg[msg_idx] = uart_getchar(); | ||
| 106 | dprintf("idx: %u, recv: %u\n", msg_idx, msg[msg_idx]); | ||
| 107 | if (msg_idx == 0 && (msg[msg_idx] != UART_PREAMBLE)) { | ||
| 108 | dprintf("Byte sync error!\n"); | ||
| 109 | msg_idx = 0; | ||
| 110 | } else if (msg_idx == (UART_MSG_LEN-1)) { | ||
| 111 | process_uart(); | ||
| 112 | msg_idx = 0; | ||
| 113 | } else { | ||
| 114 | msg_idx++; | ||
| 115 | } | ||
| 116 | } | ||
| 117 | } | ||
| 118 | |||
| 119 | static void handle_host_incoming(void) { | ||
| 120 | get_msg(); | ||
| 121 | } | ||
| 122 | |||
| 123 | static void handle_host_outgoing(void) { | ||
| 124 | // for future reverse link use | ||
| 125 | } | ||
| 126 | |||
| 127 | static void handle_remote_incoming(void) { | ||
| 128 | // for future reverse link use | ||
| 129 | } | ||
| 130 | |||
| 131 | static void handle_remote_outgoing(uint16_t keycode, keyrecord_t *record) { | ||
| 132 | if (IS_HID_KC(keycode) || IS_RM_KC(keycode)) { | ||
| 133 | dprintf("Remote: send [%u]\n", keycode); | ||
| 134 | send_msg(keycode, record->event.pressed); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | // Public functions | ||
| 139 | |||
| 140 | void matrix_init_remote_kb(void) { | ||
| 141 | uart_init(SERIAL_UART_BAUD); | ||
| 142 | is_host = vbus_detect(); | ||
| 143 | } | ||
| 144 | |||
| 145 | void process_record_remote_kb(uint16_t keycode, keyrecord_t *record) { | ||
| 146 | #if defined (KEYBOARD_HOST) | ||
| 147 | handle_host_outgoing(); | ||
| 148 | |||
| 149 | #elif defined(KEYBOARD_REMOTE) | ||
| 150 | handle_remote_outgoing(keycode, record); | ||
| 151 | |||
| 152 | #else //auto check with VBUS | ||
| 153 | if (is_host) { | ||
| 154 | handle_host_outgoing(); | ||
| 155 | } | ||
| 156 | else { | ||
| 157 | handle_remote_outgoing(keycode, record); | ||
| 158 | } | ||
| 159 | #endif | ||
| 160 | } | ||
| 161 | |||
| 162 | void matrix_scan_remote_kb(void) { | ||
| 163 | #if defined(KEYBOARD_HOST) | ||
| 164 | handle_host_incoming(); | ||
| 165 | |||
| 166 | #elif defined (KEYBOARD_REMOTE) | ||
| 167 | handle_remote_incoming(); | ||
| 168 | |||
| 169 | #else //auto check with VBUS | ||
| 170 | if (is_host) { | ||
| 171 | handle_host_incoming(); | ||
| 172 | } | ||
| 173 | else { | ||
| 174 | handle_remote_incoming(); | ||
| 175 | } | ||
| 176 | #endif | ||
| 177 | } | ||
diff --git a/keyboards/nullbitsco/nibble/remote_kb.h b/keyboards/nullbitsco/nibble/remote_kb.h new file mode 100644 index 000000000..e2b24655b --- /dev/null +++ b/keyboards/nullbitsco/nibble/remote_kb.h | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /* Copyright 2020 Jay Greco | ||
| 2 | * | ||
| 3 | * This program is free software: you can redistribute it and/or modify | ||
| 4 | * it under the terms of the GNU General Public License as published by | ||
| 5 | * the Free Software Foundation, either version 2 of the License, or | ||
| 6 | * (at your option) any later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 15 | */ | ||
| 16 | #pragma once | ||
| 17 | |||
| 18 | #include "quantum.h" | ||
| 19 | #include "tmk_core/common/uart.h" | ||
| 20 | |||
| 21 | #define SERIAL_UART_BAUD 153600 //low error rate for 32u4 @ 16MHz | ||
| 22 | |||
| 23 | #define UART_PREAMBLE 0x69 | ||
| 24 | #define UART_MSG_LEN 5 | ||
| 25 | #define UART_NULL 0 | ||
| 26 | |||
| 27 | #define IDX_PREAMBLE 0 | ||
| 28 | #define IDX_KCLSB 1 | ||
| 29 | #define IDX_KCMSB 2 | ||
| 30 | #define IDX_PRESSED 3 | ||
| 31 | #define IDX_CHECKSUM 4 | ||
| 32 | |||
| 33 | #define IS_HID_KC(x) ((x > 0) && (x < 0xFF)) | ||
| 34 | #define IS_RM_KC(x) ((x >= RM_BASE) && (x <= 0xFFFF)) | ||
| 35 | |||
| 36 | #define RM_BASE 0xFFFF-16 | ||
| 37 | enum remote_macros { | ||
| 38 | RM_1 = RM_BASE, | ||
| 39 | RM_2, RM_3, | ||
| 40 | RM_4, RM_5, | ||
| 41 | RM_6, RM_7, | ||
| 42 | RM_8, RM_9, | ||
| 43 | RM_10, RM_11, | ||
| 44 | RM_12, RM_13, | ||
| 45 | RM_14, RM_15, | ||
| 46 | }; | ||
| 47 | |||
| 48 | |||
| 49 | // Public functions | ||
| 50 | void | ||
| 51 | matrix_init_remote_kb(void), | ||
| 52 | process_record_remote_kb(uint16_t keycode, keyrecord_t *record), | ||
| 53 | matrix_scan_remote_kb(void); \ No newline at end of file | ||
diff --git a/keyboards/nullbitsco/nibble/rules.mk b/keyboards/nullbitsco/nibble/rules.mk new file mode 100644 index 000000000..683e29086 --- /dev/null +++ b/keyboards/nullbitsco/nibble/rules.mk | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | # MCU name | ||
| 2 | MCU = atmega32u4 | ||
| 3 | |||
| 4 | # Interrupt driven control endpoint task(+60) | ||
| 5 | OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT | ||
| 6 | |||
| 7 | # Bootloader selection | ||
| 8 | BOOTLOADER = atmel-dfu | ||
| 9 | |||
| 10 | # Build Options | ||
| 11 | # change yes to no to disable | ||
| 12 | # | ||
| 13 | BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration | ||
| 14 | MOUSEKEY_ENABLE = no # Mouse keys | ||
| 15 | EXTRAKEY_ENABLE = yes # Audio control and System control | ||
| 16 | CONSOLE_ENABLE = no # Console for debug | ||
| 17 | COMMAND_ENABLE = no # Commands for debug and configuration | ||
| 18 | SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend | ||
| 19 | NKRO_ENABLE = yes # USB Nkey Rollover | ||
| 20 | BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality | ||
| 21 | RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow | ||
| 22 | MIDI_ENABLE = no # MIDI support | ||
| 23 | BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID | ||
| 24 | AUDIO_ENABLE = no # Audio output on port C6 | ||
| 25 | FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches | ||
| 26 | ENCODER_ENABLE = yes # Use rotary encoder | ||
| 27 | LTO_ENABLE = yes # Link-time optimization | ||
| 28 | CUSTOM_MATRIX = lite # Lite custom matrix | ||
| 29 | |||
| 30 | # Project specific files | ||
| 31 | SRC += matrix.c \ | ||
| 32 | bitc_led.c \ | ||
| 33 | big_led.c \ | ||
| 34 | remote_kb.c \ | ||
| 35 | tmk_core/common/uart.c | ||
