From aaa758f1d3f97dda39879f2b055ad2da9680adfe Mon Sep 17 00:00:00 2001 From: Eric Tang Date: Mon, 23 May 2016 20:42:21 -0700 Subject: [PATCH] Optimize matrix scanning (#343) --- HAND_WIRE.md | 26 +- keyboard/Bantam44/config.h | 7 +- keyboard/atomic/config.h | 17 +- keyboard/atomic/keymaps/pvc/config.h | 7 +- keyboard/atreus/config.h | 12 +- keyboard/clueboard1/config.h | 25 +- keyboard/clueboard2/config.h | 19 +- keyboard/cluepad/config.h | 19 +- keyboard/gh60_rev_c/config.h | 17 +- keyboard/jd45/config.h | 9 +- keyboard/planck/config.h | 7 +- keyboard/planck/keymaps/pvc/config.h | 7 +- keyboard/preonic/config.h | 7 +- keyboard/retro_refit/config.h | 9 +- quantum/config_common.h | 125 ++++----- quantum/matrix.c | 393 +++++++++++---------------- quantum/template/config.h | 17 +- tmk_core/common/avr/suspend.c | 5 +- tmk_core/common/bootmagic.c | 14 +- tmk_core/common/keyboard.c | 136 ++++----- tmk_core/common/matrix.h | 61 +++-- 21 files changed, 421 insertions(+), 518 deletions(-) diff --git a/HAND_WIRE.md b/HAND_WIRE.md index 3f4d75b27..0b7367eda 100644 --- a/HAND_WIRE.md +++ b/HAND_WIRE.md @@ -51,11 +51,11 @@ A problem arises when you start pressing more than one key at a time. Looking at x row0 ---(-+-0)---(-+-1) x row0 ---(-+-0)---(-+-1) | | | | x row1 ---(key2)---(-+-3) x row1 ---(key2)---(-+-3) - + Remember that this ^ is still connected to row1 The data we get from that is: - + col0: 0b11 col1: 0b11 │└row0 @@ -73,7 +73,7 @@ Which isn't accurate, since we only have 3 keys pressed down, not all 4. This be │ │ | │ (key2) (key3) (key2) (key3) ! ! ! ! - row1 ─────┴────────┘ row1 ─────┴────────┘ + row1 ─────┴────────┘ row1 ─────┴────────┘ In practical applications, the black line of the diode will be placed facing the row, and away from the keyswitch - the `!` in this case is the diode, where the gap represents the black line. A good way to remember this is to think of this symbol: `>|` @@ -89,10 +89,10 @@ Now when we press the three keys, invoking what would be a ghosting scenario: │ │ │ │ (key2) (┌─┘3) (key2) (┌─┘3) ! ! ! ! - row1 ─────┴────────┘ x row1 ─────┴────────┘ + row1 ─────┴────────┘ x row1 ─────┴────────┘ Things act as they should! Which will get us the following data: - + col0: 0b01 col1: 0b11 │└row0 @@ -106,7 +106,7 @@ The firmware can then use this correct data to detect what it should do, and eve When starting this, you should have all of your stabilisers and keyswitches already installed (and optionally keycaps). If you're using a Cherry-type stabiliser (plate-mounted only, obviously), you'll need to install that before your keyswitches. If you're using Costar ones, you can installed them afterwards. -To make things easier on yourself, make sure all of the keyswitches are oriented the same way (if they can be - not all layouts support this). Despite this, it's important to remember that the contacts on the keyswitches are completely symmetrical. We'll be using the keyswitch's left side contact for wiring the rows, and the right side one for wiring the columns. +To make things easier on yourself, make sure all of the keyswitches are oriented the same way (if they can be - not all layouts support this). Despite this, it's important to remember that the contacts on the keyswitches are completely symmetrical. We'll be using the keyswitch's left side contact for wiring the rows, and the right side one for wiring the columns. Get your soldering iron heated-up and collect the rest of the materials from the part list at the beginning of the guide. Place your keyboard so that the bottoms of the keyswitches are accessible - it may be a good idea to place it on a cloth to protect your keyswitches/keycaps. @@ -155,7 +155,7 @@ When all of the diodes are completely soldered, it's a good idea to quickly insp ### Soldering the columns -You'll have some options in the next process - it's a good idea to insulate the column wires (since the diodes aren't), but if you're careful enough, you can use exposed wires for the columns - it's not recommended, though. If you're using single-cored wire, stripping the plastic off of the whole wire and feeding it back on is probably the best option, but can be difficult depending on the size and materials. You'll want to leave parts of the wire exposed where you're going to be solder it onto the keyswitch. +You'll have some options in the next process - it's a good idea to insulate the column wires (since the diodes aren't), but if you're careful enough, you can use exposed wires for the columns - it's not recommended, though. If you're using single-cored wire, stripping the plastic off of the whole wire and feeding it back on is probably the best option, but can be difficult depending on the size and materials. You'll want to leave parts of the wire exposed where you're going to be solder it onto the keyswitch. If you're using stranded wire, it's probably easiest to just use a lot of small wires to connect each keyswitch along the column. It's possible to use one and melt through the insulation, but this isn't recommended, will produce even more harmful fumes, and can ruin your soldering iron. @@ -195,15 +195,13 @@ You'll want to navigate to the `keyboard//` folder by typing, like #### config.h -The first thing we're going to want to modify is the `config.h` file. On line 32 and 33, you'll see `MATRIX_ROWS` and `MATRIX_COLS` - set both these variables to however many rows and columns you have on your keyboard. +The first thing you're going to want to modify is the `config.h` file. Find `MATRIX_ROWS` and `MATRIX_COLS` and them to match the dimensions of your keyboard's matrix. -On line 38 and 39 you'll see the `COLS` and `ROWS` definitions - this is where you'll enter the pins you used, in order (left-to-right when looking at the top of the keyboard, but right-to-left when looking at the bottom). - -There are some other variables that you'll be able to modify (lines 23-29), but it's not necessary to do that now (or ever, really). +Farther down are `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`. Change their definitions to match how you wired up your matrix (looking from the top of the keyboard, the rows run top-to-bottom and the columns run left-to-right). Likewise, change the definition of `UNUSED_PINS` to match the pins you did not use (this will save power). #### \.h -The next file you'll want to look at is `.h`. You're going to want to rewrite the `KEYMAP` definition - the format and syntax here is extremely important, so pay attention to how things are setup. The first half of the definition are considered the arguments - this is the format that you'll be following in your keymap later on, so you'll want to have as many k*xy* variables here as you do keys. The second half is the part that the firmware actually looks at, and will contain gaps depending on how you wired your matrix. +The next file you'll want to look at is `.h`. You're going to want to rewrite the `KEYMAP` definition - the format and syntax here is extremely important, so pay attention to how things are setup. The first half of the definition are considered the arguments - this is the format that you'll be following in your keymap later on, so you'll want to have as many k*xy* variables here as you do keys. The second half is the part that the firmware actually looks at, and will contain gaps depending on how you wired your matrix. We'll dive into how this will work with the following example. Say we have a keyboard like this: @@ -230,7 +228,7 @@ The middle column is unused on the bottom row in this example. Our `KEYMAP` defi { \ { k00, k01, k02 }, \ { k10, KC_NO, k11 }, \ - } + } Notice how the top half is spaced to resemble our physical layout - this helps us understand which keys are associated with which columns. The bottom half uses the keycode `KC_NO` where there is no keyswitch wired in. It's easiest to keep the bottom half aligned in a grid to help us make sense of how the firmware actually sees the wiring. @@ -251,7 +249,7 @@ This would require our `KEYMAP` definition to look like this: { \ { k00, k01, k02 }, \ { k10, k11, KC_NO }, \ - } + } Notice how the `k11` and `KC_NO` switched places to represent the wiring, and the unused final column on the bottom row. Sometimes it'll make more sense to put a keyswitch on a particular column, but in the end, it won't matter, as long as all of them are accounted for. You can use this process to write out the `KEYMAP` for your entire keyboard - be sure to remember that your keyboard is actually backwards when looking at the underside of it. diff --git a/keyboard/Bantam44/config.h b/keyboard/Bantam44/config.h index 26d680704..a55f62999 100644 --- a/keyboard/Bantam44/config.h +++ b/keyboard/Bantam44/config.h @@ -35,8 +35,9 @@ along with this program. If not, see . // Planck PCB default pin-out // Change this to how you wired your keyboard // COLS: Left to right, ROWS: Top to bottom -#define COLS (int []){ B0, B1, B2, B3, B7, D0, B6, F7, F6, F5, F4, F1 } -#define ROWS (int []){ F0, D6, D4, D5 } +#define MATRIX_ROW_PINS { F0, D6, D4, D5 } +#define MATRIX_COL_PINS { B0, B1, B2, B3, B7, D0, B6, F7, F6, F5, F4, F1 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -48,7 +49,7 @@ along with this program. If not, see . #define BACKLIGHT_LEVELS 3 /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboard/atomic/config.h b/keyboard/atomic/config.h index 1b34decf9..bf9550e94 100644 --- a/keyboard/atomic/config.h +++ b/keyboard/atomic/config.h @@ -41,15 +41,16 @@ along with this program. If not, see . * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) * -*/ -#define COLS (int []){ F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7, D3, D2, D1 } -#define ROWS (int []){ D0, D5, B5, B6, C6 } +*/ +#define MATRIX_ROW_PINS { D0, D5, B5, B6, C6 } +#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7, D3, D2, D1 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* define if matrix has ghost (lacks anti-ghosting diodes) */ //#define MATRIX_HAS_GHOST @@ -62,17 +63,17 @@ along with this program. If not, see . /* Locking resynchronize hack */ #define LOCKING_RESYNC_ENABLE -/* +/* * Force NKRO * - * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the * makefile for this to work.) * * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) * until the next keyboard reset. * - * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is * fully operational during normal computer usage. * * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) @@ -90,7 +91,7 @@ along with this program. If not, see . * the keyboard. They are best used in combination with the HID Listen program, * found here: https://www.pjrc.com/teensy/hid_listen.html * - * The options below allow the magic key functionality to be changed. This is + * The options below allow the magic key functionality to be changed. This is * useful if your keyboard/keypad is missing keys and you want magic key support. * */ diff --git a/keyboard/atomic/keymaps/pvc/config.h b/keyboard/atomic/keymaps/pvc/config.h index 5e956286b..1473aac34 100644 --- a/keyboard/atomic/keymaps/pvc/config.h +++ b/keyboard/atomic/keymaps/pvc/config.h @@ -42,14 +42,15 @@ along with this program. If not, see . * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) * */ -#define COLS (int []){ F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7, D3, D2, D1 } -#define ROWS (int []){ D0, D5, B5, B6, B3 } +#define MATRIX_ROW_PINS { D0, D5, B5, B6, B3 } +#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7, D3, D2, D1 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* define if matrix has ghost (lacks anti-ghosting diodes) */ //#define MATRIX_HAS_GHOST diff --git a/keyboard/atreus/config.h b/keyboard/atreus/config.h index 55d3b62b9..624d90188 100644 --- a/keyboard/atreus/config.h +++ b/keyboard/atreus/config.h @@ -36,11 +36,13 @@ along with this program. If not, see . // Change this to how you wired your keyboard // COLS: Left to right, ROWS: Top to bottom #if defined(ATREUS_ASTAR) - #define COLS (int []){ D7, C6, B5, B4, E6, D4, B6, F6, F7, D6, B7 } - #define ROWS (int []){ D0, D1, D3, D2 } +# define MATRIX_ROW_PINS { D0, D1, D3, D2 } +# define MATRIX_COL_PINS { D7, C6, B5, B4, E6, D4, B6, F6, F7, D6, B7 } +# define UNUSED_PINS #elif defined(ATREUS_TEENSY2) - #define COLS (int []){ F6, F5, F4, B7, B6, B5, B4, B3, B2, B1, B0} - #define ROWS (int []){ D0, D1, D2, D3 } +# define MATRIX_ROW_PINS { D0, D1, D2, D3 } +# define MATRIX_COL_PINS { F6, F5, F4, B7, B6, B5, B4, B3, B2, B1, B0 } +# define UNUSED_PINS #endif /* COL2ROW or ROW2COL */ @@ -53,7 +55,7 @@ along with this program. If not, see . //#define BACKLIGHT_LEVELS 3 /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboard/clueboard1/config.h b/keyboard/clueboard1/config.h index 2b20c3873..16338ddb0 100644 --- a/keyboard/clueboard1/config.h +++ b/keyboard/clueboard1/config.h @@ -32,19 +32,18 @@ along with this program. If not, see . #define MATRIX_ROWS 5 #define MATRIX_COLS 16 -// COLS: Left to right, ROWS: Top to bottom - +// ROWS: Top to bottom, COLS: Left to right /* Column pin configuration - * col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - * pin: B3 F1 F4 F5 F6 C7 C6 B6 B5 B4 D7 D6 D4 F7 B0 B1 - */ -#define COLS (int []){ B3, F1, F4, F5, F6, C7, C6, B6, B5, B4, D7, D6, D4, F7, B0, B1 } - - /* Row pin configuration - * row: 0 1 2 3 4 - * pin: D1 D0 D2 D5 D3 - */ -#define ROWS (int []){ D1, D0, D2, D5, D3 } +* col: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +* pin: B3 F1 F4 F5 F6 C7 C6 B6 B5 B4 D7 D6 D4 F7 B0 B1 +*/ +#define MATRIX_COL_PINS { B3, F1, F4, F5, F6, C7, C6, B6, B5, B4, D7, D6, D4, F7, B0, B1 } +/* Row pin configuration +* row: 0 1 2 3 4 +* pin: D1 D0 D2 D5 D3 +*/ +#define MATRIX_ROW_PINS { D1, D0, D2, D5, D3 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -53,7 +52,7 @@ along with this program. If not, see . //#define MATRIX_HAS_GHOST /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboard/clueboard2/config.h b/keyboard/clueboard2/config.h index 04166c20f..2887519af 100644 --- a/keyboard/clueboard2/config.h +++ b/keyboard/clueboard2/config.h @@ -32,19 +32,18 @@ along with this program. If not, see . #define MATRIX_ROWS 10 #define MATRIX_COLS 8 -// COLS: Left to right, ROWS: Top to bottom - +// ROWS: Top to bottom, COLS: Left to right +/* Row pin configuration +* row: 0 1 2 3 4 5 6 7 8 9 +* pin: B2 C7 C6 B6 B5 B0 B3 D5 D3 D2 +*/ +#define MATRIX_ROW_PINS { B2, C7, C6, B6, B5, B0, B3, D5, D3, D2 } /* Column pin configuration * col: 0 1 2 3 4 5 6 7 * pin: F0 F1 F4 F5 F6 F7 E6 B1 */ -#define COLS (int []){ F0, F1, F4, F5, F6, F7, E6, B1 } - - /* Row pin configuration - * row: 0 1 2 3 4 5 6 7 8 9 - * pin: B2 C7 C6 B6 B5 B0 B3 D5 D3 D2 - */ -#define ROWS (int []){ B2, C7, C6, B6, B5, B0, B3, D5, D3, D2 } +#define MATRIX_COL_PINS { F0, F1, F4, F5, F6, F7, E6, B1 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -53,7 +52,7 @@ along with this program. If not, see . //#define MATRIX_HAS_GHOST /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboard/cluepad/config.h b/keyboard/cluepad/config.h index 5ed421a6e..0955e0f70 100644 --- a/keyboard/cluepad/config.h +++ b/keyboard/cluepad/config.h @@ -32,19 +32,18 @@ along with this program. If not, see . #define MATRIX_ROWS 5 #define MATRIX_COLS 4 -// COLS: Left to right, ROWS: Top to bottom - +// ROWS: Top to bottom, COLS: Left to right +/* Row pin configuration +* row: 0 1 2 3 4 +* pin: +*/ +#define MATRIX_ROW_PINS { B0, D3, D5, D4, D6 } /* Column pin configuration * col: 0 1 2 3 * pin: F4 E6 B1 D2 */ -#define COLS (int []){ F4, E6, B1, D2 } - - /* Row pin configuration - * row: 0 1 2 3 4 - * pin: - */ -#define ROWS (int []){ B0, D3, D5, D4, D6 } +#define MATRIX_COL_PINS { F4, E6, B1, D2 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -53,7 +52,7 @@ along with this program. If not, see . //#define MATRIX_HAS_GHOST /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Number of backlighting levels */ #define BACKLIGHT_LEVELS 3 diff --git a/keyboard/gh60_rev_c/config.h b/keyboard/gh60_rev_c/config.h index 2fd8f5743..827c08d1b 100644 --- a/keyboard/gh60_rev_c/config.h +++ b/keyboard/gh60_rev_c/config.h @@ -41,15 +41,16 @@ along with this program. If not, see . * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) * -*/ -#define COLS (int []){ F0, F1, E6, C7, C6, B6, D4, B1, B7, B5, B4, D7, D6, B3 } -#define ROWS (int []){ D0, D1, D2, D3, D5 } +*/ +#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5 } +#define MATRIX_COL_PINS { F0, F1, E6, C7, C6, B6, D4, B1, B7, B5, B4, D7, D6, B3 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* define if matrix has ghost (lacks anti-ghosting diodes) */ //#define MATRIX_HAS_GHOST @@ -62,17 +63,17 @@ along with this program. If not, see . /* Locking resynchronize hack */ #define LOCKING_RESYNC_ENABLE -/* +/* * Force NKRO * - * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the * makefile for this to work.) * * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) * until the next keyboard reset. * - * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is * fully operational during normal computer usage. * * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) @@ -90,7 +91,7 @@ along with this program. If not, see . * the keyboard. They are best used in combination with the HID Listen program, * found here: https://www.pjrc.com/teensy/hid_listen.html * - * The options below allow the magic key functionality to be changed. This is + * The options below allow the magic key functionality to be changed. This is * useful if your keyboard/keypad is missing keys and you want magic key support. * */ diff --git a/keyboard/jd45/config.h b/keyboard/jd45/config.h index 1b81fe32e..ffedb6a1a 100644 --- a/keyboard/jd45/config.h +++ b/keyboard/jd45/config.h @@ -30,11 +30,12 @@ along with this program. If not, see . /* key matrix size */ #define MATRIX_ROWS 4 -#define MATRIX_COLS 13 +#define MATRIX_COLS 13 /* Planck PCB default pin-out */ -#define COLS (int []){F4, D7, B5, B6, C6, C7, D4, D6, D5, D0, D1, D2, B0} -#define ROWS (int []){F0, F1, F5, B4} +#define MATRIX_ROW_PINS { F0, F1, F5, B4 } +#define MATRIX_COL_PINS { F4, D7, B5, B6, C6, C7, D4, D6, D5, D0, D1, D2, B0 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -46,7 +47,7 @@ along with this program. If not, see . #define BACKLIGHT_LEVELS 3 /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboard/planck/config.h b/keyboard/planck/config.h index 7d64f0977..b64893108 100644 --- a/keyboard/planck/config.h +++ b/keyboard/planck/config.h @@ -33,8 +33,9 @@ along with this program. If not, see . #define MATRIX_COLS 12 /* Planck PCB default pin-out */ -#define COLS (int []){ F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 } -#define ROWS (int []){ D0, D5, B5, B6 } +#define MATRIX_ROW_PINS { D0, D5, B5, B6 } +#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -46,7 +47,7 @@ along with this program. If not, see . #define BACKLIGHT_LEVELS 3 /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboard/planck/keymaps/pvc/config.h b/keyboard/planck/keymaps/pvc/config.h index d435cc795..b8960038a 100644 --- a/keyboard/planck/keymaps/pvc/config.h +++ b/keyboard/planck/keymaps/pvc/config.h @@ -33,8 +33,9 @@ along with this program. If not, see . #define MATRIX_COLS 12 /* Planck PCB default pin-out */ -#define COLS (int []){ F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 } -#define ROWS (int []){ D0, D5, B5, B6 } +#define MATRIX_ROW_PINS { D0, D5, B5, B6 } +#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -46,7 +47,7 @@ along with this program. If not, see . #define BACKLIGHT_LEVELS 3 /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboard/preonic/config.h b/keyboard/preonic/config.h index bb9d29dab..e8d0e82fc 100644 --- a/keyboard/preonic/config.h +++ b/keyboard/preonic/config.h @@ -33,8 +33,9 @@ along with this program. If not, see . #define MATRIX_COLS 12 /* Planck PCB default pin-out */ -#define COLS (int []){ F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 } -#define ROWS (int []){ D2, D5, B5, B6, D3 } +#define MATRIX_ROW_PINS { D2, D5, B5, B6, D3 } +#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -46,7 +47,7 @@ along with this program. If not, see . #define BACKLIGHT_LEVELS 3 /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboard/retro_refit/config.h b/keyboard/retro_refit/config.h index 05fceb92b..f2194e550 100644 --- a/keyboard/retro_refit/config.h +++ b/keyboard/retro_refit/config.h @@ -33,8 +33,9 @@ along with this program. If not, see . #define MATRIX_COLS 8 // See note in retro_refit.h for an explanation of how this matrix is wired up -#define COLS (int []){ B0, B1, B2, B3, D2, D3, C7, D5 } -#define ROWS (int []){ D4, D7, B4, B5, B6, F7, F6, F5, F4, F1, F0 } +#define MATRIX_ROW_PINS { D4, D7, B4, B5, B6, F7, F6, F5, F4, F1, F0 } +#define MATRIX_COL_PINS { B0, B1, B2, B3, D2, D3, C7, D5 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW @@ -46,7 +47,7 @@ along with this program. If not, see . #define BACKLIGHT_LEVELS 0 /* Set 0 if debouncing isn't needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE @@ -119,4 +120,4 @@ along with this program. If not, see . //#define NO_ACTION_MACRO //#define NO_ACTION_FUNCTION -#endif \ No newline at end of file +#endif diff --git a/quantum/config_common.h b/quantum/config_common.h index da53fce89..02f11d979 100644 --- a/quantum/config_common.h +++ b/quantum/config_common.h @@ -1,70 +1,74 @@ #ifndef CONFIG_DEFINITIONS_H #define CONFIG_DEFINITIONS_H -#define B0 0x20 -#define B1 0x21 -#define B2 0x22 -#define B3 0x23 -#define B4 0x24 -#define B5 0x25 -#define B6 0x26 -#define B7 0x27 -#define C0 0x30 -#define C1 0x31 -#define C2 0x32 -#define C3 0x33 -#define C4 0x34 -#define C5 0x35 -#define C6 0x36 -#define C7 0x37 -#define D0 0x40 -#define D1 0x41 -#define D2 0x42 -#define D3 0x43 -#define D4 0x44 -#define D5 0x45 -#define D6 0x46 -#define D7 0x47 -#define E0 0x50 -#define E1 0x51 -#define E2 0x52 -#define E3 0x53 -#define E4 0x54 -#define E5 0x55 -#define E6 0x56 -#define E7 0x57 -#define F0 0x60 -#define F1 0x61 -#define F2 0x62 -#define F3 0x63 -#define F4 0x64 -#define F5 0x65 -#define F6 0x66 -#define F7 0x67 - -#define COL2ROW 0x0 -#define ROW2COL 0x1 +/* diode directions */ +#define COL2ROW 0 +#define ROW2COL 1 +/* I/O pins */ +#define B0 { .input_addr = 3, .bit = 0 } +#define B1 { .input_addr = 3, .bit = 1 } +#define B2 { .input_addr = 3, .bit = 2 } +#define B3 { .input_addr = 3, .bit = 3 } +#define B4 { .input_addr = 3, .bit = 4 } +#define B5 { .input_addr = 3, .bit = 5 } +#define B6 { .input_addr = 3, .bit = 6 } +#define B7 { .input_addr = 3, .bit = 7 } +#define C0 { .input_addr = 6, .bit = 0 } +#define C1 { .input_addr = 6, .bit = 1 } +#define C2 { .input_addr = 6, .bit = 2 } +#define C3 { .input_addr = 6, .bit = 3 } +#define C4 { .input_addr = 6, .bit = 4 } +#define C5 { .input_addr = 6, .bit = 5 } +#define C6 { .input_addr = 6, .bit = 6 } +#define C7 { .input_addr = 6, .bit = 7 } +#define D0 { .input_addr = 9, .bit = 0 } +#define D1 { .input_addr = 9, .bit = 1 } +#define D2 { .input_addr = 9, .bit = 2 } +#define D3 { .input_addr = 9, .bit = 3 } +#define D4 { .input_addr = 9, .bit = 4 } +#define D5 { .input_addr = 9, .bit = 5 } +#define D6 { .input_addr = 9, .bit = 6 } +#define D7 { .input_addr = 9, .bit = 7 } +#define E0 { .input_addr = 0xC, .bit = 0 } +#define E1 { .input_addr = 0xC, .bit = 1 } +#define E2 { .input_addr = 0xC, .bit = 2 } +#define E3 { .input_addr = 0xC, .bit = 3 } +#define E4 { .input_addr = 0xC, .bit = 4 } +#define E5 { .input_addr = 0xC, .bit = 5 } +#define E6 { .input_addr = 0xC, .bit = 6 } +#define E7 { .input_addr = 0xC, .bit = 7 } +#define F0 { .input_addr = 0xF, .bit = 0 } +#define F1 { .input_addr = 0xF, .bit = 1 } +#define F2 { .input_addr = 0xF, .bit = 2 } +#define F3 { .input_addr = 0xF, .bit = 3 } +#define F4 { .input_addr = 0xF, .bit = 4 } +#define F5 { .input_addr = 0xF, .bit = 5 } +#define F6 { .input_addr = 0xF, .bit = 6 } +#define F7 { .input_addr = 0xF, .bit = 7 } +/* USART configuration */ #ifdef BLUETOOTH_ENABLE -#ifdef __AVR_ATmega32U4__ - #define SERIAL_UART_BAUD 9600 - #define SERIAL_UART_DATA UDR1 - #define SERIAL_UART_UBRR ((F_CPU/(16UL*SERIAL_UART_BAUD))-1) - #define SERIAL_UART_RXD_VECT USART1_RX_vect - #define SERIAL_UART_TXD_READY (UCSR1A&(1<>8); /* baud rate */ \ - UCSR1B = (1<> 8; \ + /* enable TX */ \ + UCSR1B = _BV(TXEN1); \ + /* 8-bit data */ \ + UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ + sei(); \ + } while(0) +# else +# error "USART configuration is needed." #endif - // I'm fairly sure these aren't needed, but oh well - Jack /* @@ -113,4 +117,3 @@ #endif #endif - diff --git a/quantum/matrix.c b/quantum/matrix.c index cab39e117..22126aa7a 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -1,6 +1,6 @@ /* -Copyright 2012 Jun Wako -Generated by planckkeyboard.com (2014 Jack Humbert) +Copyright 2012 Jun Wako +Copyright 2014 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 @@ -15,300 +15,211 @@ 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 . */ - -/* - * scan matrix - */ #include #include #include -#include +#include "wait.h" #include "print.h" #include "debug.h" #include "util.h" #include "matrix.h" -#ifndef DEBOUNCE -# define DEBOUNCE 10 +#ifdef MATRIX_HAS_GHOST +# error "The universal matrix.c file cannot be used for this keyboard." #endif -static uint8_t debouncing = DEBOUNCE; -/* matrix state(1:on, 0:off) */ +#ifndef DEBOUNCING_DELAY +# define DEBOUNCING_DELAY 5 +#endif + +static const io_pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; +static const io_pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; +/* matrix state */ +#if DIODE_DIRECTION == COL2ROW static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; - -#if DIODE_DIRECTION == ROW2COL - static matrix_row_t matrix_reversed[MATRIX_COLS]; - static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS]; -#endif - - -#if MATRIX_COLS > 16 - #define SHIFTER 1UL +static matrix_row_t debouncing_matrix[MATRIX_ROWS]; #else - #define SHIFTER 1 +static matrix_col_t matrix[MATRIX_COLS]; +static matrix_col_t debouncing_matrix[MATRIX_COLS]; #endif +static int8_t debouncing_delay = -1; +#if DIODE_DIRECTION == COL2ROW +static void toggle_row(uint8_t row); static matrix_row_t read_cols(void); -static void init_cols(void); -static void unselect_rows(void); -static void select_row(uint8_t row); +#else +static void toggle_col(uint8_t col); +static matrix_col_t read_rows(void); +#endif __attribute__ ((weak)) void matrix_init_quantum(void) { - } __attribute__ ((weak)) void matrix_scan_quantum(void) { - } -inline -uint8_t matrix_rows(void) -{ +uint8_t matrix_rows(void) { return MATRIX_ROWS; } -inline -uint8_t matrix_cols(void) -{ +uint8_t matrix_cols(void) { return MATRIX_COLS; } -void matrix_init(void) -{ - // To use PORTF disable JTAG with writing JTD bit twice within four cycles. - MCUCR |= (1<= 0; --r) { + /* DDRxn */ + _SFR_IO8(row_pins[r].input_addr + 1) |= _BV(row_pins[r].bit); + toggle_row(r); } - + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + /* PORTxn */ + _SFR_IO8(col_pins[c].input_addr + 2) |= _BV(col_pins[c].bit); + } +#else + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + /* DDRxn */ + _SFR_IO8(col_pins[c].input_addr + 1) |= _BV(col_pins[c].bit); + toggle_col(c); + } + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + /* PORTxn */ + _SFR_IO8(row_pins[r].input_addr + 2) |= _BV(row_pins[r].bit); + } +#endif matrix_init_quantum(); } - -uint8_t matrix_scan(void) -{ - #if DIODE_DIRECTION == COL2ROW - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - select_row(i); - _delay_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(); - if (matrix_debouncing[i] != cols) { - matrix_debouncing[i] = cols; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCE; +uint8_t matrix_scan(void) { + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + toggle_row(r); + matrix_row_t state = read_cols(); + if (debouncing_matrix[r] != state) { + debouncing_matrix[r] = state; + debouncing_delay = DEBOUNCING_DELAY; } - unselect_rows(); + toggle_row(r); } - - if (debouncing) { - if (--debouncing) { - _delay_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = matrix_debouncing[i]; + if (debouncing_delay >= 0) { + dprintf("Debouncing delay remaining: %X\n", debouncing_delay); + --debouncing_delay; + if (debouncing_delay >= 0) { + wait_ms(1); + } + else { + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + matrix[r] = debouncing_matrix[r]; } } } -#else - for (uint8_t i = 0; i < MATRIX_COLS; i++) { - select_row(i); - _delay_us(30); // without this wait read unstable value. - matrix_row_t rows = read_cols(); - if (matrix_reversed_debouncing[i] != rows) { - matrix_reversed_debouncing[i] = rows; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCE; - } - unselect_rows(); - } - - if (debouncing) { - if (--debouncing) { - _delay_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_COLS; i++) { - matrix_reversed[i] = matrix_reversed_debouncing[i]; - } - } - } - for (uint8_t y = 0; y < MATRIX_ROWS; y++) { - matrix_row_t row = 0; - for (uint8_t x = 0; x < MATRIX_COLS; x++) { - row |= ((matrix_reversed[x] & (1<> y) << x; - } - matrix[y] = row; - } -#endif - matrix_scan_quantum(); - return 1; } -bool matrix_is_modified(void) -{ - if (debouncing) return false; - return true; +static void toggle_row(uint8_t row) { + /* PINxn */ + _SFR_IO8(row_pins[row].input_addr) = _BV(row_pins[row].bit); } -inline -bool matrix_is_on(uint8_t row, uint8_t col) -{ - return (matrix[row] & ((matrix_row_t)1= 0; --c) { + /* PINxn */ + if (!(_SFR_IO8(col_pins[c].input_addr) & _BV(col_pins[c].bit))) { + state |= (matrix_row_t)1 << c; + } + } + return state; } -inline -matrix_row_t matrix_get_row(uint8_t row) -{ +matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } -void matrix_print(void) -{ - print("\nr/c 0123456789ABCDEF\n"); - for (uint8_t row = 0; row < MATRIX_ROWS; row++) { - phex(row); print(": "); - pbin_reverse16(matrix_get_row(row)); - print("\n"); +#else +uint8_t matrix_scan(void) { + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + toggle_col(c); + matrix_col_t state = read_rows(); + if (debouncing_matrix[c] != state) { + debouncing_matrix[c] = state; + debouncing_delay = DEBOUNCING_DELAY; + } + toggle_col(c); + } + if (debouncing_delay >= 0) { + dprintf("Debouncing delay remaining: %X\n", debouncing_delay); + --debouncing_delay; + if (debouncing_delay >= 0) { + wait_ms(1); + } + else { + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + matrix[c] = debouncing_matrix[c]; + } + } + } + matrix_scan_quantum(); + return 1; +} + +static void toggle_col(uint8_t col) { + /* PINxn */ + _SFR_IO8(col_pins[col].input_addr) = _BV(col_pins[col].bit); +} + +static matrix_col_t read_rows(void) { + matrix_col_t state = 0; + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + /* PINxn */ + if (!(_SFR_IO8(row_pins[r].input_addr) & _BV(row_pins[r].bit))) { + state |= (matrix_col_t)1 << r; + } + } + return state; +} + +matrix_row_t matrix_get_row(uint8_t row) { + matrix_row_t state = 0; + matrix_col_t mask = (matrix_col_t)1 << row; + for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { + if (matrix[c] & mask) { + state |= (matrix_row_t)1 << c; + } + } + return state; +} + +#endif + +bool matrix_is_modified(void) { + if (debouncing_delay >= 0) return false; + return true; +} + +bool matrix_is_on(uint8_t row, uint8_t col) { + return matrix_get_row(row) & (matrix_row_t)1 << col; +} + +void matrix_print(void) { + dprintln("Human-readable matrix state:"); + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { + dprintf("State of row %X: %016b\n", r, bitrev16(matrix_get_row(r))); } } -uint8_t matrix_key_count(void) -{ +uint8_t matrix_key_count(void) { uint8_t count = 0; - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - count += bitpop16(matrix[i]); + for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { + count += bitpop16(matrix_get_row(r)); } return count; } - -static void init_cols(void) -{ - int B = 0, C = 0, D = 0, E = 0, F = 0; - -#if DIODE_DIRECTION == COL2ROW - for(int x = 0; x < MATRIX_COLS; x++) { - int col = COLS[x]; -#else - for(int x = 0; x < MATRIX_ROWS; x++) { - int col = ROWS[x]; -#endif - if ((col & 0xF0) == 0x20) { - B |= (1<<(col & 0x0F)); - } else if ((col & 0xF0) == 0x30) { - C |= (1<<(col & 0x0F)); - } else if ((col & 0xF0) == 0x40) { - D |= (1<<(col & 0x0F)); - } else if ((col & 0xF0) == 0x50) { - E |= (1<<(col & 0x0F)); - } else if ((col & 0xF0) == 0x60) { - F |= (1<<(col & 0x0F)); - } - } - DDRB &= ~(B); PORTB |= (B); - DDRC &= ~(C); PORTC |= (C); - DDRD &= ~(D); PORTD |= (D); - DDRE &= ~(E); PORTE |= (E); - DDRF &= ~(F); PORTF |= (F); -} - -static matrix_row_t read_cols(void) -{ - matrix_row_t result = 0; - -#if DIODE_DIRECTION == COL2ROW - for(int x = 0; x < MATRIX_COLS; x++) { - int col = COLS[x]; -#else - for(int x = 0; x < MATRIX_ROWS; x++) { - int col = ROWS[x]; -#endif - - if ((col & 0xF0) == 0x20) { - result |= (PINB&(1<<(col & 0x0F)) ? 0 : (SHIFTER<. * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode) * ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode) * -*/ -#define COLS (int []){ F1, F0, B0 } -#define ROWS (int []){ D0, D5 } +*/ +#define MATRIX_ROW_PINS { D0, D5 } +#define MATRIX_COL_PINS { F1, F0, B0 } +#define UNUSED_PINS /* COL2ROW or ROW2COL */ #define DIODE_DIRECTION COL2ROW /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ -#define DEBOUNCE 5 +#define DEBOUNCING_DELAY 5 /* define if matrix has ghost (lacks anti-ghosting diodes) */ //#define MATRIX_HAS_GHOST @@ -62,17 +63,17 @@ along with this program. If not, see . /* Locking resynchronize hack */ #define LOCKING_RESYNC_ENABLE -/* +/* * Force NKRO * - * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved + * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the * makefile for this to work.) * * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N) * until the next keyboard reset. * - * NKRO may prevent your keystrokes from being detected in the BIOS, but it is + * NKRO may prevent your keystrokes from being detected in the BIOS, but it is * fully operational during normal computer usage. * * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N) @@ -90,7 +91,7 @@ along with this program. If not, see . * the keyboard. They are best used in combination with the HID Listen program, * found here: https://www.pjrc.com/teensy/hid_listen.html * - * The options below allow the magic key functionality to be changed. This is + * The options below allow the magic key functionality to be changed. This is * useful if your keyboard/keypad is missing keys and you want magic key support. * */ diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index 498068019..a6f3c6441 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 2c1b1adfc..30e8a0f20 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 1d9981848..c6d54ae33 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" -#ifdef BOOTMAGIC_ENABLE - #include "bootmagic.h" -#else - #include "magic.h" -#endif #include "eeconfig.h" #include "backlight.h" +#ifdef BOOTMAGIC_ENABLE +# include "bootmagic.h" +#else +# include "magic.h" +#endif #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 ad0871bfb..5f380aaab 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<