Update to xealousbrown. (#8215) * Update to xealousbrown. 5-13ms Latency decrease, 4x scan rate improvement. (CUSTOM_MATRIX = lite) is a really great feature! * Updated Readme.md, added an extra speedhack. * More optimizations * Update keyboards/handwired/xealousbrown/rules.mk * Update keyboards/handwired/xealousbrown/rules.mk
6 files changed, 188 insertions(+), 16 deletions(-) M keyboards/handwired/xealousbrown/README.md M keyboards/handwired/xealousbrown/config.h M keyboards/handwired/xealousbrown/keymaps/default/keymap.c A keyboards/handwired/xealousbrown/matrix.c M keyboards/handwired/xealousbrown/rules.mk M keyboards/handwired/xealousbrown/xealousbrown.c
M keyboards/handwired/xealousbrown/README.md => keyboards/handwired/xealousbrown/README.md +7 -1
@@ 7,5 7,11 @@ https://sites.google.com/site/xaelous/keyboards/handwired-keyboard Make example for this keyboard (after setting up your build environment): make handwired/xealous-brown:default make handwired/xealousbrown:default The brief list of speedhacks to make this keyboard blazing fast: 1) bit-bash implementation of scanning rows, columns. Very short delay between pin waiting. 2) Compiling with a few extra flags 3) Eager-per-key Debouncing algorithm (no 5ms delay before message is sent) 4) 1000hz polling
M keyboards/handwired/xealousbrown/config.h => keyboards/handwired/xealousbrown/config.h +4 -1
@@ 29,7 29,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. /* key matrix size */ #define MATRIX_ROWS 5 #define MATRIX_COLS 13 #define DEBOUNCE 10 #define USB_POLLING_INTERVAL_MS 1 /* layer optimization */ #define LAYER_STATE_8BIT /* * Keyboard Matrix Assignments *
M keyboards/handwired/xealousbrown/keymaps/default/keymap.c => keyboards/handwired/xealousbrown/keymaps/default/keymap.c +2 -2
@@ 10,8 10,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [1] = LAYOUT( /* FN_Layer */ KC_GRV, 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_CAPS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_UP, KC_PGDN, KC_PSCR, KC_SLCK,KC_PAUS,\ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_INS, KC_DEL, KC_TRNS, \ KC_CAPS, KC_PGUP, KC_UP, KC_PGDN, KC_TRNS, KC_TRNS, KC_TRNS, KC_PGUP, KC_UP, KC_PGDN, KC_PSCR, KC_SLCK,KC_PAUS,\ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_HOME, KC_HOME, KC_LEFT, KC_DOWN, KC_RGHT, KC_INS, KC_DEL, KC_TRNS, \ KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END, KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_DEL \ )
A keyboards/handwired/xealousbrown/matrix.c => keyboards/handwired/xealousbrown/matrix.c +112 -0
@@ 0,0 1,112 @@ /* Copyright 2019 Alex Ong 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 <http://www.gnu.org/licenses/>. */ #include <stdint.h> #include <stdbool.h> #include "wait.h" #include "util.h" #include "matrix.h" #include "debounce.h" #include "quantum.h" /* matrix state(1:on, 0:off) */ extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values // matrix code // super fast read_cols code. static matrix_row_t read_cols(void) { return (PINC & (1 << 6) ? 0 : (1UL << 0)) | (PIND & (1 << 7) ? 0 : (1UL << 1)) | (PINE & (1 << 6) ? 0 : (1UL << 2)) | (PINB & (1 << 4) ? 0 : (1UL << 3)) | (PINB & (1 << 5) ? 0 : (1UL << 4)) | (PINB & (1 << 6) ? 0 : (1UL << 5)) | (PINB & (1 << 2) ? 0 : (1UL << 6)) | (PINB & (1 << 3) ? 0 : (1UL << 7)) | (PINB & (1 << 1) ? 0 : (1UL << 8)) | (PINF & (1 << 7) ? 0 : (1UL << 9)) | (PINF & (1 << 6) ? 0 : (1UL << 10)) | (PINF & (1 << 5) ? 0 : (1UL << 11)) | (PINF & (1 << 4) ? 0 : (1UL << 12)); } static void unselect_rows(void) { DDRD &= ~0b00011111; PORTD &= ~0b00011111; } static void select_row(uint8_t row) { switch (row) { case 0: DDRD |= (1 << 3); PORTD &= ~(1 << 3); break; case 1: DDRD |= (1 << 2); PORTD &= ~(1 << 2); break; case 2: DDRD |= (1 << 1); PORTD &= ~(1 << 1); break; case 3: DDRD |= (1 << 0); PORTD &= ~(1 << 0); break; case 4: DDRD |= (1 << 4); PORTD &= ~(1 << 4); break; } } static void init_pins(void) { DDRC &= ~(1 << 6); PORTC |= (1 << 6); DDRD &= ~(1 << 7); PORTD |= (1 << 7); DDRE &= ~(1 << 6); PORTE |= (1 << 6); DDRB &= ~(1 << 4 | 1 << 5 | 1 << 6 | 1 << 2 | 1 << 3 | 1 << 1); PORTB |= (1 << 4 | 1 << 5 | 1 << 6 | 1 << 2 | 1 << 3 | 1 << 1); DDRF &= ~(1 << 7 | 1 << 6 | 1 << 5 | 1 << 4); PORTF |= (1 << 7 | 1 << 6 | 1 << 5 | 1 << 4); } // Only need to init the pins. Debounce / raw matrix are initialized already for us. void matrix_init_custom(void) { // initialize key pins init_pins(); } // Only need to scan the result into current_matrix, and return changed. uint8_t matrix_scan_custom(matrix_row_t current_matrix[]) { bool changed = false; // Set row, read cols for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { select_row(current_row); asm volatile("nop"); asm volatile("nop"); matrix_row_t cols = read_cols(); changed |= (current_matrix[current_row] != cols); current_matrix[current_row] = cols; unselect_rows(); } return changed; }
M keyboards/handwired/xealousbrown/rules.mk => keyboards/handwired/xealousbrown/rules.mk +22 -12
@@ 14,17 14,27 @@ BOOTLOADER = caterina # Build Options # change yes to no to disable # BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = no # Mouse keys(+4700) EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration BOOTMAGIC_ENABLE = full # Virtual DIP switch configuration MOUSEKEY_ENABLE = no # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control CONSOLE_ENABLE = yes # Console for debug COMMAND_ENABLE = yes # Commands for debug and configuration # Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend # if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default MIDI_ENABLE = no # MIDI controls UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 NKRO_ENABLE = yes # USB Nkey Rollover BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default MIDI_ENABLE = no # MIDI controls UNICODE_ENABLE = no # Unicode BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE = no # Audio output on port C6 SPACE_CADET_ENABLE = no # Unneeded feature. # special sauce for this keyboard DEBOUNCE_TYPE = eager_pk # Debounce using eager_pk. CUSTOM_MATRIX = lite # Custom matrix that polls at 7000hz instead of a measly 2000hz. LTO_ENABLE = yes # smaller binary SRC += matrix.c # Also remember to open tmk's rules.mk and set compilation optimization to 3
M keyboards/handwired/xealousbrown/xealousbrown.c => keyboards/handwired/xealousbrown/xealousbrown.c +41 -0
@@ 6,3 6,44 @@ void matrix_init_kb(void) { matrix_init_user(); } #ifdef BENCHMARK_MATRIX # include "timer.h" # include <stdint.h> # include <stdbool.h> # include "wait.h" # include "util.h" # include "matrix.h" # include "quantum.h" static int scans = 0; static uint16_t last_print_out = 0; static int last_timer = 0; void matrix_scan_user(void) { scans++; uint16_t timer = timer_read(); if (timer != last_timer && timer != last_timer + 1) { print("MS:\n"); print_dec(timer); print("->"); print_dec(last_timer); print("\n"); } last_timer = timer; if ((timer % 1000 == 0) && (timer != last_print_out)) { print("Benchmark:"); print("\n"); print_dec(timer); print("\n"); print_dec(scans); print("\n"); print("-------"); scans = 0; last_print_out = timer; } } #endif