]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Optimize matrix scanning (#343)
authorEric Tang <e_l_tang@outlook.com>
Tue, 24 May 2016 03:42:21 +0000 (20:42 -0700)
committerJack Humbert <jack.humb@gmail.com>
Tue, 24 May 2016 03:42:21 +0000 (23:42 -0400)
21 files changed:
HAND_WIRE.md
keyboard/Bantam44/config.h
keyboard/atomic/config.h
keyboard/atomic/keymaps/pvc/config.h
keyboard/atreus/config.h
keyboard/clueboard1/config.h
keyboard/clueboard2/config.h
keyboard/cluepad/config.h
keyboard/gh60_rev_c/config.h
keyboard/jd45/config.h
keyboard/planck/config.h
keyboard/planck/keymaps/pvc/config.h
keyboard/preonic/config.h
keyboard/retro_refit/config.h
quantum/config_common.h
quantum/matrix.c
quantum/template/config.h
tmk_core/common/avr/suspend.c
tmk_core/common/bootmagic.c
tmk_core/common/keyboard.c
tmk_core/common/matrix.h

index 3f4d75b272b2f9e044692d1a87f406c9f9fb3457..0b7367eda33dddde7e5a010dbd51cad4966c8df2 100644 (file)
@@ -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/<project_name>/` 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.
-
-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).
+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.
 
-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).
 
 #### \<project_name\>.h
 
-The next file you'll want to look at is `<project_name>.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 `<project_name>.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.
 
index 26d680704d66824ff7aa2b7995316ff4c74a1472..a55f629990ade79b7782d8b01b09a04f621dbe6e 100644 (file)
@@ -35,8 +35,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 // 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 <http://www.gnu.org/licenses/>.
 #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
index 1b34decf9c7b29007ab91e5d04bf5f8862201fb2..bf9550e94803504f044159609e9395c7191cf127 100644 (file)
@@ -41,15 +41,16 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * 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 <http://www.gnu.org/licenses/>.
 /* 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 <http://www.gnu.org/licenses/>.
  * 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.
  *
  */
index 5e956286b542bce4f5db14ba3580e50fbc176088..1473aac34f05a7c27044fea236bf8368de4178f3 100644 (file)
@@ -42,14 +42,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *                  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
index 55d3b62b9293b68a270d4fd7ff754806e67ce527..624d90188cbcda0750b11f0fba220949b62cae4c 100644 (file)
@@ -36,11 +36,13 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 // 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 <http://www.gnu.org/licenses/>.
 //#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
index 2b20c3873d12d639e6e74a6ea282921802a37a42..16338ddb03d20681b3321e9a74f61c45c777b44e 100644 (file)
@@ -32,19 +32,18 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #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 <http://www.gnu.org/licenses/>.
 //#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
index 04166c20f633de5787c10e3300d6718b956cb72e..2887519afd234da24cd389606942861c92ac2aaf 100644 (file)
@@ -32,19 +32,18 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #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 <http://www.gnu.org/licenses/>.
 //#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
index 5ed421a6e0bd6dcc5478c99fc54d3a3594295db6..0955e0f7026791e552816ee2ca5753d287c238d3 100644 (file)
@@ -32,19 +32,18 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #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 <http://www.gnu.org/licenses/>.
 //#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
index 2fd8f574396dea5719ceb38d5e7f9f2fa664f65e..827c08d1be501135eda2ca828c95b33b32ae29b6 100644 (file)
@@ -41,15 +41,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
  * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)\r
  *         ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)\r
  *\r
-*/ \r
-#define COLS (int []){ F0, F1, E6, C7, C6, B6, D4, B1, B7, B5, B4, D7, D6, B3 }\r
-#define ROWS (int []){ D0, D1, D2, D3, D5 }\r
+*/\r
+#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5 }\r
+#define MATRIX_COL_PINS { F0, F1, E6, C7, C6, B6, D4, B1, B7, B5, B4, D7, D6, B3 }\r
+#define UNUSED_PINS\r
 \r
 /* COL2ROW or ROW2COL */\r
 #define DIODE_DIRECTION COL2ROW\r
 \r
 /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */\r
-#define DEBOUNC 5\r
+#define DEBOUNCING_DELAY 5\r
 \r
 /* define if matrix has ghost (lacks anti-ghosting diodes) */\r
 //#define MATRIX_HAS_GHOST\r
@@ -62,17 +63,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
 /* Locking resynchronize hack */\r
 #define LOCKING_RESYNC_ENABLE\r
 \r
-/* \r
+/*\r
  * Force NKRO\r
  *\r
- * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved \r
+ * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved\r
  * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the\r
  * makefile for this to work.)\r
  *\r
  * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)\r
  * until the next keyboard reset.\r
  *\r
- * NKRO may prevent your keystrokes from being detected in the BIOS, but it is \r
+ * NKRO may prevent your keystrokes from being detected in the BIOS, but it is\r
  * fully operational during normal computer usage.\r
  *\r
  * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)\r
@@ -90,7 +91,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
  * the keyboard. They are best used in combination with the HID Listen program,\r
  * found here: https://www.pjrc.com/teensy/hid_listen.html\r
  *\r
- * The options below allow the magic key functionality to be changed. This is \r
+ * The options below allow the magic key functionality to be changed. This is\r
  * useful if your keyboard/keypad is missing keys and you want magic key support.\r
  *\r
  */\r
index 1b81fe32ed3f255cd098d0d8bdffe5482167162e..ffedb6a1a98ad32724bf7ff9dad930dbece22abc 100644 (file)
@@ -30,11 +30,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 /* 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 <http://www.gnu.org/licenses/>.
 #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
index 7d64f09773f97c5c32539dc2157a590d8833a8bf..b6489310819c78adcf8ab9e930fbda06a5acbe9c 100644 (file)
@@ -33,8 +33,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #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 <http://www.gnu.org/licenses/>.
 #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
index d435cc795c5a402a4e88aa518d61bf51c1119167..b8960038abba6777be3840c86508d57c9b3eb613 100644 (file)
@@ -33,8 +33,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #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 <http://www.gnu.org/licenses/>.
 #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
index bb9d29dab771309978ac5e3208dc943b9abd3bf1..e8d0e82fc9ceaaebd726286dcb50dd85a70cc08a 100644 (file)
@@ -33,8 +33,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #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 <http://www.gnu.org/licenses/>.
 #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
index 05fceb92b2bede788b7add3e675d1634a15721f4..f2194e550cc029b788ea399bb5698ed7fe1de689 100644 (file)
@@ -33,8 +33,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #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 <http://www.gnu.org/licenses/>.
 #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 <http://www.gnu.org/licenses/>.
 //#define NO_ACTION_MACRO
 //#define NO_ACTION_FUNCTION
 
-#endif
\ No newline at end of file
+#endif
index da53fce89b5b8ddaeabb40469433b20bf21dd32f..02f11d979c579d436c928937b25443503b667427 100644 (file)
@@ -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<<UDRE1))
-    #define SERIAL_UART_INIT()     do { \
-        UBRR1L = (uint8_t) SERIAL_UART_UBRR;       /* baud rate */ \
-        UBRR1H = (uint8_t) (SERIAL_UART_UBRR>>8);  /* baud rate */ \
-        UCSR1B = (1<<TXEN1);                /* TX: enable */ \
-        UCSR1C = (0<<UPM11) | (0<<UPM10) | /* parity: none(00), even(01), odd(11) */ \
-                 (0<<UCSZ12) | (1<<UCSZ11) | (1<<UCSZ10); /* data-8bit(011) */ \
-               sei(); \
-    } while(0)
-#else
-#   error "USART configuration is needed."
+#   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 & _BV(UDRE1))
+#      define SERIAL_UART_INIT() do { \
+            /* baud rate */ \
+            UBRR1L = SERIAL_UART_UBRR; \
+            /* baud rate */ \
+            UBRR1H = SERIAL_UART_UBRR >> 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
 
 /*
 #endif
 
 #endif
-
index cab39e117a41bc13cb9f69d68d4b962c3a94bccb..22126aa7ae1175459d58aae40f6518dc06f4cfe5 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.
 */
-
-/*
- * scan matrix
- */
 #include <stdint.h>
 #include <stdbool.h>
 #include <avr/io.h>
-#include <util/delay.h>
+#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) */
-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];
+#ifndef DEBOUNCING_DELAY
+#   define DEBOUNCING_DELAY 5
 #endif
 
-
-#if MATRIX_COLS > 16
-    #define SHIFTER 1UL
+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 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<<JTD);
-    MCUCR |= (1<<JTD);
-
-
-    // initialize row and col
-    unselect_rows();
-    init_cols();
-
-    // initialize matrix state: all keys off
-    for (uint8_t i=0; i < MATRIX_ROWS; i++) {
-        matrix[i] = 0;
-        matrix_debouncing[i] = 0;
+void matrix_init(void) {
+    /* frees PORTF by setting the JTD bit twice within four cycles */
+    MCUCR |= _BV(JTD);
+    MCUCR |= _BV(JTD);
+    /* initializes the I/O pins */
+#if DIODE_DIRECTION == COL2ROW
+    for (int8_t r = MATRIX_ROWS - 1; r >= 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 (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");
+        else {
+            for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
+                matrix[r] = debouncing_matrix[r];
             }
-            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)) >> 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<col));
+static matrix_row_t read_cols(void) {
+    matrix_row_t state = 0;
+    for (int8_t c = MATRIX_COLS - 1; c >= 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);
     }
-}
-
-uint8_t matrix_key_count(void)
-{
-    uint8_t count = 0;
-    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
-        count += bitpop16(matrix[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 c = MATRIX_COLS - 1; c >= 0; --c) {
+                matrix[c] = debouncing_matrix[c];
+            }
+        }
     }
-    return count;
+    matrix_scan_quantum();
+    return 1;
 }
 
-static void init_cols(void)
-{
-    int B = 0, C = 0, D = 0, E = 0, F = 0;
+static void toggle_col(uint8_t col) {
+    /* PINxn */
+    _SFR_IO8(col_pins[col].input_addr) = _BV(col_pins[col].bit);
+}
 
-#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)); 
-        } 
+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;
+        }
     }
-    DDRB &= ~(B); PORTB |= (B);
-    DDRC &= ~(C); PORTC |= (C); 
-    DDRD &= ~(D); PORTD |= (D);
-    DDRE &= ~(E); PORTE |= (E);
-    DDRF &= ~(F); PORTF |= (F);
+    return state;
 }
 
-static matrix_row_t read_cols(void)
-{
-    matrix_row_t result = 0;
+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;
+}
 
-#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<<x)); 
-        } else if ((col & 0xF0) == 0x30) { 
-            result |= (PINC&(1<<(col & 0x0F)) ? 0 : (SHIFTER<<x)); 
-        } else if ((col & 0xF0) == 0x40) { 
-            result |= (PIND&(1<<(col & 0x0F)) ? 0 : (SHIFTER<<x)); 
-        } else if ((col & 0xF0) == 0x50) { 
-            result |= (PINE&(1<<(col & 0x0F)) ? 0 : (SHIFTER<<x)); 
-        } else if ((col & 0xF0) == 0x60) { 
-            result |= (PINF&(1<<(col & 0x0F)) ? 0 : (SHIFTER<<x)); 
-        } 
-    }
-    return result;
+bool matrix_is_modified(void) {
+    if (debouncing_delay >= 0) return false;
+    return true;
 }
 
-static void unselect_rows(void)
-{
-    int B = 0, C = 0, D = 0, E = 0, F = 0;
+bool matrix_is_on(uint8_t row, uint8_t col) {
+    return matrix_get_row(row) & (matrix_row_t)1 << col;
+}
 
-#if DIODE_DIRECTION == COL2ROW
-    for(int x = 0; x < MATRIX_ROWS; x++) { 
-        int row = ROWS[x];
-#else
-    for(int x = 0; x < MATRIX_COLS; x++) { 
-        int row = COLS[x];
-#endif
-        if ((row & 0xF0) == 0x20) { 
-            B |= (1<<(row & 0x0F)); 
-        } else if ((row & 0xF0) == 0x30) { 
-            C |= (1<<(row & 0x0F)); 
-        } else if ((row & 0xF0) == 0x40) { 
-            D |= (1<<(row & 0x0F)); 
-        } else if ((row & 0xF0) == 0x50) { 
-            E |= (1<<(row & 0x0F)); 
-        } else if ((row & 0xF0) == 0x60) { 
-            F |= (1<<(row & 0x0F)); 
-        } 
+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)));
     }
-    DDRB &= ~(B); PORTB |= (B);
-    DDRC &= ~(C); PORTC |= (C); 
-    DDRD &= ~(D); PORTD |= (D);
-    DDRE &= ~(E); PORTE |= (E);
-    DDRF &= ~(F); PORTF |= (F);
 }
 
-static void select_row(uint8_t row)
-{
-
-#if DIODE_DIRECTION == COL2ROW
-    int row_pin = ROWS[row];
-#else
-    int row_pin = COLS[row];
-#endif
-
-    if ((row_pin & 0xF0) == 0x20) { 
-        DDRB  |= (1<<(row_pin & 0x0F));
-        PORTB &= ~(1<<(row_pin & 0x0F));
-    } else if ((row_pin & 0xF0) == 0x30) { 
-        DDRC  |= (1<<(row_pin & 0x0F));
-        PORTC &= ~(1<<(row_pin & 0x0F));
-    } else if ((row_pin & 0xF0) == 0x40) { 
-        DDRD  |= (1<<(row_pin & 0x0F));
-        PORTD &= ~(1<<(row_pin & 0x0F));
-    } else if ((row_pin & 0xF0) == 0x50) { 
-        DDRE  |= (1<<(row_pin & 0x0F));
-        PORTE &= ~(1<<(row_pin & 0x0F));
-    } else if ((row_pin & 0xF0) == 0x60) { 
-        DDRF  |= (1<<(row_pin & 0x0F));
-        PORTF &= ~(1<<(row_pin & 0x0F));
-    }  
-}
\ No newline at end of file
+uint8_t matrix_key_count(void) {
+    uint8_t count = 0;
+    for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
+        count += bitpop16(matrix_get_row(r));
+    }
+    return count;
+}
index e6fb7866c6ca1b0d56c69f69150f1979c7e062ff..cad3e3260a0137fc15fe9a6e840ae0366a41c8d5 100644 (file)
@@ -41,15 +41,16 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * 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 <http://www.gnu.org/licenses/>.
 /* 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 <http://www.gnu.org/licenses/>.
  * 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.
  *
  */
index 4980680198e20775f1a51d8c6d6f0e0a85aaf52a..a6f3c6441475d4240e1c86c044d13a99f2dd6245 100644 (file)
@@ -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
-
index 2c1b1adfc5d6f86050f039139a81622c4c195ec7..30e8a0f20feab7ba2bec60e72460c9c6b43303fc 100644 (file)
@@ -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<<c)) {
-                if (keycode == keymap_key_to_keycode(0, (keypos_t){ .row = r, .col = c })) {
-                    return true;
-                }
+        for (int8_t c = MATRIX_COLS - 1; c >= 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;
             }
         }
     }
index 1d998184811d6a9db8aa9a3b5072addf05d7bbdc..c6d54ae3338d16a7564afed4d154d034e6d23d41 100644 (file)
@@ -1,5 +1,5 @@
 /*
-Copyright 2011,2012,2013 Jun Wako <wakojun@gmail.com>
+Copyright 2011, 2012, 2013 Jun Wako <wakojun@gmail.com>
 
 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 <http://www.gnu.org/licenses/>.
 #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 <http://www.gnu.org/licenses/>.
 #   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<<c)) {
-                    action_exec((keyevent_t){
-                        .key = (keypos_t){ .row = r, .col = c },
-                        .pressed = (matrix_row & ((matrix_row_t)1<<c)),
-                        .time = (timer_read() | 1) /* time should not be 0 */
-                    });
-                    // record a processed key
-                    matrix_prev[r] ^= ((matrix_row_t)1<<c);
-                    // process a key per task call
-                    goto MATRIX_LOOP_END;
+            for (int8_t c = MATRIX_COLS - 1; c >= 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);
 }
index ad0871bfb735f85254bfcc5d14285e215aef0093..5f380aaaba003d98a8aacd211f7f912914bb223b 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.
 */
-
 #ifndef MATRIX_H
 #define MATRIX_H
 
 #include <stdint.h>
 #include <stdbool.h>
 
-
-#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<<col))
+#if DIODE_DIRECTION == ROW2COL
+#   if MATRIX_ROWS <= 8
+typedef uint8_t matrix_col_t;
+#   elif MATRIX_ROWS <= 16
+typedef uint16_t matrix_col_t;
+#   elif MATRIX_ROWS <= 32
+typedef uint32_t matrix_col_t;
+#   else
+#       error "There are too many rows."
+#   endif
+#endif
 
+typedef struct {
+    uint8_t input_addr:4;
+    uint8_t bit:4;
+} io_pin_t;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
-
-/* number of matrix rows */
+/* counts the number of rows in the matrix */
 uint8_t matrix_rows(void);
-/* number of matrix columns */
+/* counts the number of columns in the matrix */
 uint8_t matrix_cols(void);
-/* should be called at early stage of startup before matrix_init.(optional) */
+/* sets up the matrix before matrix_init */
 void matrix_setup(void);
-/* intialize matrix for scaning. */
+/* intializes the matrix */
 void matrix_init(void);
-/* scan all key states on matrix */
+/* scans the entire matrix */
 uint8_t matrix_scan(void);
-/* whether modified from previous scan. used after matrix_scan. */
+/* checks if the matrix has been modified */
 bool matrix_is_modified(void) __attribute__ ((deprecated));
-/* whether a swtich is on */
+/* checks if a key is pressed */
 bool matrix_is_on(uint8_t row, uint8_t col);
-/* matrix state on row */
+/* inspects the state of a row in the matrix */
 matrix_row_t matrix_get_row(uint8_t row);
-/* print matrix for debug */
+/* prints the matrix for debugging */
 void matrix_print(void);
-
-
-/* power control */
+/* counts the total number of keys pressed */
+uint8_t matrix_key_count(void);
+/* controls power to the matrix */
 void matrix_power_up(void);
 void matrix_power_down(void);
-
-/* keyboard-specific setup/loop functionality */
+/* executes code for Quantum */
 void matrix_init_quantum(void);
 void matrix_scan_quantum(void);
-
 #ifdef __cplusplus
 }
 #endif