From aaa758f1d3f97dda39879f2b055ad2da9680adfe Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Mon, 23 May 2016 20:42:21 -0700 Subject: Optimize matrix scanning (#343) --- tmk_core/common/avr/suspend.c | 5 +- tmk_core/common/bootmagic.c | 14 ++--- tmk_core/common/keyboard.c | 134 ++++++++++++++++++------------------------ tmk_core/common/matrix.h | 61 +++++++++++-------- 4 files changed, 98 insertions(+), 116 deletions(-) (limited to 'tmk_core') diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index 4980680198..a6f3c64414 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c @@ -114,9 +114,7 @@ bool suspend_wakeup_condition(void) matrix_power_up(); matrix_scan(); matrix_power_down(); - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - if (matrix_get_row(r)) return true; - } + if (matrix_key_count()) return true; return false; } @@ -146,4 +144,3 @@ ISR(WDT_vect) } } #endif - diff --git a/tmk_core/common/bootmagic.c b/tmk_core/common/bootmagic.c index 2c1b1adfc5..30e8a0f20f 100644 --- a/tmk_core/common/bootmagic.c +++ b/tmk_core/common/bootmagic.c @@ -105,15 +105,13 @@ void bootmagic(void) } } -static bool scan_keycode(uint8_t keycode) -{ - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { +static bool scan_keycode(uint8_t keycode) { + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { matrix_row_t matrix_row = matrix_get_row(r); - for (uint8_t c = 0; c < MATRIX_COLS; c++) { - if (matrix_row & ((matrix_row_t)1<= 0; --c) { + if (matrix_row & (matrix_row_t)1 << c) { + keypos_t key = (keypos_t){ .row = r, .col = c }; + if (keycode == keymap_key_to_keycode(0, key)) return true; } } } diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 1d99818481..c6d54ae333 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -1,5 +1,5 @@ /* -Copyright 2011,2012,2013 Jun Wako +Copyright 2011, 2012, 2013 Jun Wako 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 @@ -27,13 +27,13 @@ along with this program. If not, see . #include "command.h" #include "util.h" #include "sendchar.h" +#include "eeconfig.h" +#include "backlight.h" #ifdef BOOTMAGIC_ENABLE - #include "bootmagic.h" +# include "bootmagic.h" #else - #include "magic.h" +# include "magic.h" #endif -#include "eeconfig.h" -#include "backlight.h" #ifdef MOUSEKEY_ENABLE # include "mousekey.h" #endif @@ -41,40 +41,35 @@ along with this program. If not, see . # include "ps2_mouse.h" #endif #ifdef SERIAL_MOUSE_ENABLE -#include "serial_mouse.h" +# include "serial_mouse.h" #endif #ifdef ADB_MOUSE_ENABLE -#include "adb.h" +# include "adb.h" #endif - #ifdef MATRIX_HAS_GHOST -static bool has_ghost_in_row(uint8_t row) -{ - matrix_row_t matrix_row = matrix_get_row(row); - // No ghost exists when less than 2 keys are down on the row - if (((matrix_row - 1) & matrix_row) == 0) - return false; - - // Ghost occurs when the row shares column line with other row - for (uint8_t i=0; i < MATRIX_ROWS; i++) { - if (i != row && (matrix_get_row(i) & matrix_row)) - return true; +static bool is_row_ghosting(uint8_t row){ + matrix_row_t state = matrix_get_row(row); + /* no ghosting happens when only one key in the row is pressed */ + if (!(state - 1 & state)) return false; + /* ghosting occurs when two keys in the same column are pressed */ + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + if (r != row && matrix_get_row(r) & state) return true; } return false; } + #endif +__attribute__ ((weak)) +void matrix_setup(void) { +} -__attribute__ ((weak)) void matrix_setup(void) {} -void keyboard_setup(void) -{ +void keyboard_setup(void) { matrix_setup(); } -void keyboard_init(void) -{ - +void keyboard_init(void) { timer_init(); matrix_init(); #ifdef PS2_MOUSE_ENABLE @@ -86,104 +81,87 @@ void keyboard_init(void) #ifdef ADB_MOUSE_ENABLE adb_mouse_init(); #endif - - #ifdef BOOTMAGIC_ENABLE bootmagic(); #else magic(); #endif - #ifdef BACKLIGHT_ENABLE backlight_init(); #endif - #if defined(NKRO_ENABLE) && defined(FORCE_NKRO) keyboard_nkro = true; #endif - } -/* - * Do keyboard routine jobs: scan mantrix, light LEDs, ... - * This is repeatedly called as fast as possible. - */ -void keyboard_task(void) -{ - static matrix_row_t matrix_prev[MATRIX_ROWS]; +/* does routine keyboard jobs */ +void keyboard_task(void) { + static matrix_row_t previous_matrix[MATRIX_ROWS]; #ifdef MATRIX_HAS_GHOST - static matrix_row_t matrix_ghost[MATRIX_ROWS]; + static matrix_row_t deghosting_matrix[MATRIX_ROWS]; #endif static uint8_t led_status = 0; - matrix_row_t matrix_row = 0; - matrix_row_t matrix_change = 0; - matrix_scan(); - for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - matrix_row = matrix_get_row(r); - matrix_change = matrix_row ^ matrix_prev[r]; - if (matrix_change) { + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + matrix_row_t state = matrix_get_row(r); + matrix_row_t changes = state ^ previous_matrix[r]; + if (changes) { #ifdef MATRIX_HAS_GHOST - if (has_ghost_in_row(r)) { - /* Keep track of whether ghosted status has changed for - * debugging. But don't update matrix_prev until un-ghosted, or - * the last key would be lost. + if (is_row_ghosting(r)) { + /* debugs the deghosting mechanism */ + /* doesn't update previous_matrix until the ghosting has stopped + * in order to prevent the last key from being lost */ - if (debug_matrix && matrix_ghost[r] != matrix_row) { + if (debug_matrix && deghosting_matrix[r] != state) { matrix_print(); } - matrix_ghost[r] = matrix_row; + deghosting_matrix[r] = state; continue; } - matrix_ghost[r] = matrix_row; + deghosting_matrix[r] = state; #endif if (debug_matrix) matrix_print(); - for (uint8_t c = 0; c < MATRIX_COLS; c++) { - if (matrix_change & ((matrix_row_t)1<= 0; --c) { + matrix_row_t mask = (matrix_row_t)1 << c; + if (changes & mask) { + keyevent_t event; + event.key = (keypos_t){ .row = r, .col = c }; + event.pressed = state & mask; + /* the time should not be 0 */ + event.time = timer_read() | 1; + action_exec(event); + /* records the processed key event */ + previous_matrix[r] ^= mask; + /* processes one key event per call */ + goto event_processed; } } } } - // call with pseudo tick event when no real key event. + /* sends tick events when the keyboard is idle */ action_exec(TICK); - -MATRIX_LOOP_END: - +event_processed: #ifdef MOUSEKEY_ENABLE - // mousekey repeat & acceleration + /* repeats and accelerates the mouse keys */ mousekey_task(); #endif - #ifdef PS2_MOUSE_ENABLE ps2_mouse_task(); #endif - #ifdef SERIAL_MOUSE_ENABLE - serial_mouse_task(); + serial_mouse_task(); #endif - #ifdef ADB_MOUSE_ENABLE - adb_mouse_task(); + adb_mouse_task(); #endif - - // update LED + /* updates the LEDs */ if (led_status != host_keyboard_leds()) { led_status = host_keyboard_leds(); keyboard_set_leds(led_status); } } -void keyboard_set_leds(uint8_t leds) -{ - if (debug_keyboard) { debug("keyboard_set_led: "); debug_hex8(leds); debug("\n"); } +void keyboard_set_leds(uint8_t leds) { + if (debug_keyboard) dprintf("Keyboard LEDs state: %x\n", leds); led_set(leds); } diff --git a/tmk_core/common/matrix.h b/tmk_core/common/matrix.h index ad0871bfb7..5f380aaaba 100644 --- a/tmk_core/common/matrix.h +++ b/tmk_core/common/matrix.h @@ -14,59 +14,68 @@ 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 . */ - #ifndef MATRIX_H #define MATRIX_H #include #include - -#if (MATRIX_COLS <= 8) -typedef uint8_t matrix_row_t; -#elif (MATRIX_COLS <= 16) -typedef uint16_t matrix_row_t; -#elif (MATRIX_COLS <= 32) -typedef uint32_t matrix_row_t; +#if MATRIX_COLS <= 8 +typedef uint8_t matrix_row_t; +#elif MATRIX_COLS <= 16 +typedef uint16_t matrix_row_t; +#elif MATRIX_COLS <= 32 +typedef uint32_t matrix_row_t; #else -#error "MATRIX_COLS: invalid value" +# error "There are too many columns." #endif -#define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1< Date: Mon, 23 May 2016 23:44:36 -0400 Subject: updates midi in play_note to better octave --- tmk_core/protocol/lufa/lufa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tmk_core') diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index aba94cd597..b70b52bf4d 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -947,10 +947,10 @@ void fallthrough_callback(MidiDevice * device, if (cnt == 3) { switch (byte0 & 0xF0) { case MIDI_NOTEON: - play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8); + play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8); break; case MIDI_NOTEOFF: - stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(byte1 & 0x7F)/12.0)); + stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0)); break; } } -- cgit v1.2.3 From 1ae6011cef2230826a9e6db6c5b638677bc640b7 Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Tue, 24 May 2016 08:44:40 -0700 Subject: Clean up #343's code (#348) --- tmk_core/common/keyboard.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'tmk_core') diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index c6d54ae333..bd543c45e1 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -96,17 +96,15 @@ void keyboard_init(void) { /* does routine keyboard jobs */ void keyboard_task(void) { - static matrix_row_t previous_matrix[MATRIX_ROWS]; -#ifdef MATRIX_HAS_GHOST - static matrix_row_t deghosting_matrix[MATRIX_ROWS]; -#endif - static uint8_t led_status = 0; + static uint8_t led_status; matrix_scan(); for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + static matrix_row_t previous_matrix[MATRIX_ROWS]; matrix_row_t state = matrix_get_row(r); matrix_row_t changes = state ^ previous_matrix[r]; if (changes) { #ifdef MATRIX_HAS_GHOST + static matrix_row_t deghosting_matrix[MATRIX_ROWS]; if (is_row_ghosting(r)) { /* debugs the deghosting mechanism */ /* doesn't update previous_matrix until the ghosting has stopped -- cgit v1.2.3 From 287eb7ad148abc8fe3fb014218d71e205fd9131d Mon Sep 17 00:00:00 2001 From: Jack Humbert Date: Tue, 24 May 2016 11:56:53 -0400 Subject: Converted audio play functions to *_user (#349) * Updated personal layouts * tweaked personal * Nightly - Audio Cleanup Refactored the LUTs. Abstracted some of the registers out of audio to use more functional names. Split audio into audio and audio_pwm. WIP * nightly - collapsed code * Added check for note playing to LEDs * Usability tweaks * TWEAE * nightly added extra kcs to keymap common * turned on Plank audio * Added backlight breathing to atomic * reverted accidental merge * Added music and audio toggles to Quantum.c * Redid the audio callbacks * Adjusted default planck layout to use the user tone naming * tabs to spaces * Rewrote the ALL recipe to allow for faster parallel make * tabs to spaces * Renamed custom event functions to be 'startup_user' and 'shutdown_user'. Also moved the prototypes around. * Tweaked pvc atomic layout to work with the pvc planck. * updates midi scale calling --- tmk_core/common/command.c | 13 +++++++------ tmk_core/rules.mk | 8 +++++++- 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'tmk_core') diff --git a/tmk_core/common/command.c b/tmk_core/common/command.c index 9edcc42a05..024d7c67a3 100644 --- a/tmk_core/common/command.c +++ b/tmk_core/common/command.c @@ -33,20 +33,21 @@ along with this program. If not, see . #include "led.h" #include "command.h" #include "backlight.h" +#include "quantum.h" #ifdef MOUSEKEY_ENABLE #include "mousekey.h" #endif #ifdef PROTOCOL_PJRC -# include "usb_keyboard.h" -# ifdef EXTRAKEY_ENABLE -# include "usb_extra.h" -# endif + #include "usb_keyboard.h" + #ifdef EXTRAKEY_ENABLE + #include "usb_extra.h" + #endif #endif #ifdef PROTOCOL_VUSB -# include "usbdrv.h" + #include "usbdrv.h" #endif #ifdef AUDIO_ENABLE @@ -358,7 +359,7 @@ static bool command_common(uint8_t code) print("\n\nJumping to bootloader... "); #ifdef AUDIO_ENABLE stop_all_notes(); - play_goodbye_tone(); + shutdown_user(); #else _delay_ms(1000); #endif diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index 552f32331a..1d384574f6 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -366,7 +366,13 @@ ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS) # Default target. -all: begin gccversion sizebefore build sizeafter end +all: + $(MAKE) begin + $(MAKE) gccversion + $(MAKE) sizebefore + $(MAKE) build + $(MAKE) sizeafter + $(MAKE) end # Change the build target to build a HEX file or a library. build: elf hex eep lss sym -- cgit v1.2.3