From b11d8780d9dcc63c4bc19b8668b6be8082b6ddf2 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sun, 19 Aug 2012 21:16:52 -0700 Subject: [PATCH] updated matrix to match PCB; made pin direction an option - rows are now 0..6, cols now 0..D (matching the pics Fredrik posted of his first flippable PCB) - either rows or columns can now be the driving pins. the option is in ".../keyboard/.../options.h" --- src/TODO | 15 +- src/keyboard/ergodox/circuit-diagram.svg | 38 +-- src/keyboard/ergodox/controller/mcp23018.c | 133 +++++++--- src/keyboard/ergodox/controller/mcp23018.md | 31 +-- src/keyboard/ergodox/controller/teensy-2-0.c | 227 ++++++++++-------- src/keyboard/ergodox/controller/teensy-2-0.md | 39 +-- src/keyboard/ergodox/matrix.h | 89 ++++--- 7 files changed, 337 insertions(+), 235 deletions(-) diff --git a/src/TODO b/src/TODO index 87f0cc9..430fb14 100644 --- a/src/TODO +++ b/src/TODO @@ -1,11 +1,20 @@ -- change stuff to correspond with the PCB Fredrik made +-+ change stuff to correspond with the PCB Fredrik made - rows 0..6, cols 0..13 -- write macros so that either rows or columns can be the driving pins (macro +-+ write macros so that either rows or columns can be the driving pins (macro should be set in the keyboard/.../controller folder somewhere, i think) - - set them by default to match the direction of keyswitch internal diodes; if + -- set them by default to match the direction of keyswitch internal diodes; if fredrik or dominic put theirs together differently first, i can change the default to match theirs + + can't do this, since i don't know which direction internal diodes go! + lol, and i can't seem to find it online. i left a note in the file where + the direction is set (.../keyboard/.../options.h), and hopefully i'll + updated it later (maybe when i get my brown switches). :) + +-+ (test) +- (check in) +- (merge) +- (push) - write the python script for Ben, to extract all that useful stuff from the .map file and comments diff --git a/src/keyboard/ergodox/circuit-diagram.svg b/src/keyboard/ergodox/circuit-diagram.svg index b7999ea..c4107d7 100644 --- a/src/keyboard/ergodox/circuit-diagram.svg +++ b/src/keyboard/ergodox/circuit-diagram.svg @@ -2388,7 +2388,7 @@ sodipodi:role="line" x="-339.98328" y="299.83008" - id="tspan12254">col 6 + id="tspan12254">col D col 4 + id="tspan12258">col B col 5 + id="tspan12260">col C col 0 + id="tspan12264">col 7 row B + id="tspan12264-1">row 5 row A + y="559.83008">row 4 row 9 + y="579.83008">row 3 row 8 + y="599.83008">row 2 row 7 + y="619.83008">row 1 row 6 + y="639.83008">row 0 col 1 + id="tspan12234-5">col 5 col 2 + y="578.09943">col 4 col 4 + y="618.09943">col 2 col 5 + y="638.09943">col 1 col 6 + y="658.26935">col 0 col 0 + id="tspan12234-5-3">col 6 col 1 + id="tspan12264-7">col 8 col 2 + id="tspan12264-5">col 9 col 3 + id="tspan12264-7-6">col A #include #include "../../../lib/twi.h" // `TWI_FREQ` defined in "teensy-2-0.c" +#include "../options.h" #include "../matrix.h" #include "./mcp23018--functions.h" // ---------------------------------------------------------------------------- +// check options +#if (MCP23018__DRIVE_ROWS && MCP23018__DRIVE_COLUMNS) \ + || !(MCP23018__DRIVE_ROWS || MCP23018__DRIVE_COLUMNS) + #error "See 'Pin drive direction' in 'options.h'" +#endif + +// ---------------------------------------------------------------------------- + // register addresses (see "mcp23018.md") #define IODIRA 0x00 // i/o direction register #define IODIRB 0x01 @@ -45,32 +54,42 @@ uint8_t mcp23018_init(void) { // set pin direction // - unused : input : 1 - // - row : input : 1 - // - column : output : 0 + // - input : input : 1 + // - driving : output : 0 twi_start(); ret = twi_send(TWI_ADDR_WRITE); if (ret) goto out; // make sure we got an ACK twi_send(IODIRA); - twi_send(0b10000000); // IODIRA - twi_send(0b11111111); // IODIRB + #if MCP23018__DRIVE_ROWS + twi_send(0b11111111); // IODIRA + twi_send(0b11000000); // IODIRB + #elif MCP23018__DRIVE_COLUMNS + twi_send(0b10000000); // IODIRA + twi_send(0b11111111); // IODIRB + #endif twi_stop(); // set pull-up // - unused : on : 1 - // - rows : on : 1 - // - columns : off : 0 + // - input : on : 1 + // - driving : off : 0 twi_start(); ret = twi_send(TWI_ADDR_WRITE); if (ret) goto out; // make sure we got an ACK twi_send(GPPUA); - twi_send(0b10000000); // GPPUA - twi_send(0b11111111); // GPPUB + #if MCP23018__DRIVE_ROWS + twi_send(0b11111111); // GPPUA + twi_send(0b11000000); // GPPUB + #elif MCP23018__DRIVE_COLUMNS + twi_send(0b10000000); // GPPUA + twi_send(0b11111111); // GPPUB + #endif twi_stop(); // set logical value (doesn't matter on inputs) - // - unused : high (hi-Z) : 1 - // - rows : high (hi-Z) : 1 - // - columns : high (hi-Z) : 1 + // - unused : hi-Z : 1 + // - input : hi-Z : 1 + // - driving : hi-Z : 1 twi_start(); ret = twi_send(TWI_ADDR_WRITE); if (ret) goto out; // make sure we got an ACK @@ -87,7 +106,7 @@ out: * - success: 0 * - failure: twi status code */ -#if KB_ROWS != 12 || KB_COLUMNS != 7 +#if KB_ROWS != 6 || KB_COLUMNS != 14 #error "Expecting different keyboard dimensions" #endif uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { @@ -102,43 +121,85 @@ uint8_t mcp23018_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { // if there was an error if (ret) { // clear our part of the matrix - for (uint8_t row=0x6; row<=0xB; row++) + for (uint8_t row=0; row<=5; row++) for (uint8_t col=0; col<=6; col++) matrix[row][col] = 0; return ret; } - // update our part of the matrix - for (uint8_t col=0; col<=6; col++) { - // set active column low : 0 - // set other columns high (hi-Z) : 1 - twi_start(); - twi_send(TWI_ADDR_WRITE); - twi_send(OLATA); - twi_send( 0xFF & ~(1<<(6-col)) ); - twi_stop(); - // read row data + // -------------------------------------------------------------------- + // update our part of the matrix + + #if MCP23018__DRIVE_ROWS + for (uint8_t row=0; row<=5; row++) { + // set active row low : 0 + // set other rows hi-Z : 1 + twi_start(); + twi_send(TWI_ADDR_WRITE); + twi_send(GPIOB); + twi_send( 0xFF & ~(1<<(5-row)) ); + twi_stop(); + + // read column data + twi_start(); + twi_send(TWI_ADDR_WRITE); + twi_send(GPIOA); + twi_start(); + twi_send(TWI_ADDR_READ); + twi_read(&data); + twi_stop(); + + // update matrix + for (uint8_t col=0; col<=6; col++) { + matrix[row][col] = !( data & (1<) set as + hi-Z without pull-ups, and the other set of pins set as input with + pull-ups. During the update function, we'll cycle through setting the + first set low and checking each pin in the second set. * abbreviations: * IODIR = I/O Direction Register diff --git a/src/keyboard/ergodox/controller/teensy-2-0.c b/src/keyboard/ergodox/controller/teensy-2-0.c index 9932ab0..8b20fa4 100644 --- a/src/keyboard/ergodox/controller/teensy-2-0.c +++ b/src/keyboard/ergodox/controller/teensy-2-0.c @@ -15,26 +15,35 @@ #include #include #include "../../../lib/twi.h" +#include "../options.h" #include "../matrix.h" #include "./teensy-2-0--functions.h" #include "./teensy-2-0--led.h" // ---------------------------------------------------------------------------- +// check options +#if (TEENSY__DRIVE_ROWS && TEENSY__DRIVE_COLUMNS) \ + || !(TEENSY__DRIVE_ROWS || TEENSY__DRIVE_COLUMNS) + #error "See 'Pin drive direction' in 'options.h'" +#endif +// ---------------------------------------------------------------------------- + // processor frequency (from ) -#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) -#define CPU_16MHz 0x00 -#define CPU_8MHz 0x01 -#define CPU_4MHz 0x02 -#define CPU_2MHz 0x03 -#define CPU_1MHz 0x04 -#define CPU_500kHz 0x05 -#define CPU_250kHz 0x06 -#define CPU_125kHz 0x07 -#define CPU_62kHz 0x08 +#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) +#define CPU_16MHz 0x00 +#define CPU_8MHz 0x01 +#define CPU_4MHz 0x02 +#define CPU_2MHz 0x03 +#define CPU_1MHz 0x04 +#define CPU_500kHz 0x05 +#define CPU_250kHz 0x06 +#define CPU_125kHz 0x07 +#define CPU_62kHz 0x08 -/* pin macros +/* + * pin macros * - note: you can move the `UNUSED`, `ROW`, and `COLUMN` pins around, but be * sure to keep the set of all the pins listed constant. other pins are not * movable, and either are referenced explicitly or have macros defined for @@ -43,20 +52,48 @@ * "teensy-2-0.md", and the '.svg' circuit diagram. */ -// --- helpers -#define _teensypin_write(register, operation, pin_letter, pin_number) \ - ((register##pin_letter) operation (1<<(pin_number))) -#define teensypin_write(register, operation, pin) do { \ - _teensypin_write(register, operation, pin); \ - _delay_us(1); /* allow pins time to stabilize */ \ - } while(0) +// --- unused +#define UNUSED_0 C, 7 +#define UNUSED_1 D, 7 +#define UNUSED_2 D, 4 // hard to use with breadboard (on the end) +#define UNUSED_3 D, 5 // hard to use with breadboard (on the end) +#define UNUSED_4 E, 6 // hard to use with breadboard (internal) -#define _teensypin_read(pin_letter, pin_number) \ +// --- rows +#define ROW_0 F, 7 +#define ROW_1 F, 6 +#define ROW_2 F, 5 +#define ROW_3 F, 4 +#define ROW_4 F, 1 +#define ROW_5 F, 0 + +// --- columns +#define COLUMN_7 B, 0 +#define COLUMN_8 B, 1 +#define COLUMN_9 B, 2 +#define COLUMN_A B, 3 +#define COLUMN_B D, 2 +#define COLUMN_C D, 3 +#define COLUMN_D C, 6 + +// --- helpers +#define SET |= +#define CLEAR &=~ + +#define _teensypin_write(register, operation, pin_letter, pin_number) \ + do { \ + ((register##pin_letter) operation (1<<(pin_number))); \ + _delay_us(1); /* allow pins time to stabilize */ \ + } while(0) +#define teensypin_write(register, operation, pin) \ + _teensypin_write(register, operation, pin) + +#define _teensypin_read(pin_letter, pin_number) \ ((PIN##pin_letter) & (1<<(pin_number))) -#define teensypin_read(pin) \ +#define teensypin_read(pin) \ _teensypin_read(pin) -#define teensypin_write_all_unused(register, operation) \ +#define teensypin_write_all_unused(register, operation) \ do { \ teensypin_write(register, operation, UNUSED_0); \ teensypin_write(register, operation, UNUSED_1); \ @@ -65,7 +102,7 @@ teensypin_write(register, operation, UNUSED_4); } \ while(0) -#define teensypin_write_all_row(register, operation) \ +#define teensypin_write_all_row(register, operation) \ do { \ teensypin_write(register, operation, ROW_0); \ teensypin_write(register, operation, ROW_1); \ @@ -75,43 +112,51 @@ teensypin_write(register, operation, ROW_5); } \ while(0) -#define teensypin_write_all_column(register, operation) \ +#define teensypin_write_all_column(register, operation) \ do { \ - teensypin_write(register, operation, COLUMN_0); \ - teensypin_write(register, operation, COLUMN_1); \ - teensypin_write(register, operation, COLUMN_2); \ - teensypin_write(register, operation, COLUMN_3); \ - teensypin_write(register, operation, COLUMN_4); \ - teensypin_write(register, operation, COLUMN_5); \ - teensypin_write(register, operation, COLUMN_6); } \ + teensypin_write(register, operation, COLUMN_7); \ + teensypin_write(register, operation, COLUMN_8); \ + teensypin_write(register, operation, COLUMN_9); \ + teensypin_write(register, operation, COLUMN_A); \ + teensypin_write(register, operation, COLUMN_B); \ + teensypin_write(register, operation, COLUMN_C); \ + teensypin_write(register, operation, COLUMN_D); } \ while(0) -#define SET |= -#define CLEAR &=~ -// --- unused -#define UNUSED_0 C, 7 -#define UNUSED_1 D, 7 -#define UNUSED_2 D, 4 // hard to use with breadboard (on the end) -#define UNUSED_3 D, 5 // hard to use with breadboard (on the end) -#define UNUSED_4 E, 6 // hard to use with breadboard (internal) +/* + * update macros + */ +#define update_rows_for_column(matrix, column) \ + do { \ + /* set column low (set as output) */ \ + teensypin_write(DDR, SET, COLUMN_##column); \ + /* read rows 0..5 and update matrix */ \ + matrix[0x0][0x##column] = ! teensypin_read(ROW_0); \ + matrix[0x1][0x##column] = ! teensypin_read(ROW_1); \ + matrix[0x2][0x##column] = ! teensypin_read(ROW_2); \ + matrix[0x3][0x##column] = ! teensypin_read(ROW_3); \ + matrix[0x4][0x##column] = ! teensypin_read(ROW_4); \ + matrix[0x5][0x##column] = ! teensypin_read(ROW_5); \ + /* set column hi-Z (set as input) */ \ + teensypin_write(DDR, CLEAR, COLUMN_##column); \ + } while(0) -// --- rows -#define ROW_0 F, 7 -#define ROW_1 F, 6 -#define ROW_2 F, 5 -#define ROW_3 F, 4 -#define ROW_4 F, 1 -#define ROW_5 F, 0 - -// --- columns -#define COLUMN_0 B, 0 -#define COLUMN_1 B, 1 -#define COLUMN_2 B, 2 -#define COLUMN_3 B, 3 -#define COLUMN_4 D, 2 -#define COLUMN_5 D, 3 -#define COLUMN_6 C, 6 +#define update_columns_for_row(matrix, row) \ + do { \ + /* set row low (set as output) */ \ + teensypin_write(DDR, SET, ROW_##row); \ + /* read columns 7..D and update matrix */ \ + matrix[0x##row][0x7] = ! teensypin_read(COLUMN_7); \ + matrix[0x##row][0x8] = ! teensypin_read(COLUMN_8); \ + matrix[0x##row][0x9] = ! teensypin_read(COLUMN_9); \ + matrix[0x##row][0xA] = ! teensypin_read(COLUMN_A); \ + matrix[0x##row][0xB] = ! teensypin_read(COLUMN_B); \ + matrix[0x##row][0xC] = ! teensypin_read(COLUMN_C); \ + matrix[0x##row][0xD] = ! teensypin_read(COLUMN_D); \ + /* set row hi-Z (set as input) */ \ + teensypin_write(DDR, CLEAR, ROW_##row); \ + } while(0) // ---------------------------------------------------------------------------- @@ -146,14 +191,16 @@ uint8_t teensy_init(void) { teensypin_write_all_unused(DDR, CLEAR); // set as input teensypin_write_all_unused(PORT, SET); // set internal pull-up enabled - // rows - teensypin_write_all_row(DDR, CLEAR); // set as input - teensypin_write_all_row(PORT, SET); // set internal pull-up enabled - - // columns - teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z) - teensypin_write_all_column(PORT, CLEAR); // set internal pull-up - // disabled + // rows and columns + teensypin_write_all_row(DDR, CLEAR); // set as input (hi-Z) + teensypin_write_all_column(DDR, CLEAR); // set as input (hi-Z) + #if TEENSY__DRIVE_ROWS + teensypin_write_all_row(PORT, CLEAR); // pull-up disabled + teensypin_write_all_column(PORT, SET); // pull-up enabled + #elif TEENSY__DRIVE_COLUMNS + teensypin_write_all_row(PORT, SET); // pull-up enabled + teensypin_write_all_column(PORT, CLEAR); // pull-up disabled + #endif return 0; // success } @@ -161,47 +208,27 @@ uint8_t teensy_init(void) { /* returns * - success: 0 */ -#if KB_ROWS != 12 || KB_COLUMNS != 7 +#if KB_ROWS != 6 || KB_COLUMNS != 14 #error "Expecting different keyboard dimensions" #endif -static inline void _update_rows( - bool matrix[KB_ROWS][KB_COLUMNS], uint8_t column ) { - matrix[0][column] = ! teensypin_read(ROW_0); - matrix[1][column] = ! teensypin_read(ROW_1); - matrix[2][column] = ! teensypin_read(ROW_2); - matrix[3][column] = ! teensypin_read(ROW_3); - matrix[4][column] = ! teensypin_read(ROW_4); - matrix[5][column] = ! teensypin_read(ROW_5); -} + uint8_t teensy_update_matrix(bool matrix[KB_ROWS][KB_COLUMNS]) { - teensypin_write(DDR, SET, COLUMN_0); // set col low (set as output) - _update_rows(matrix, 0); // read row 0..5 & update matrix - teensypin_write(DDR, CLEAR, COLUMN_0); // set col hi-Z (set as input) - - teensypin_write(DDR, SET, COLUMN_1); - _update_rows(matrix, 1); - teensypin_write(DDR, CLEAR, COLUMN_1); - - teensypin_write(DDR, SET, COLUMN_2); - _update_rows(matrix, 2); - teensypin_write(DDR, CLEAR, COLUMN_2); - - teensypin_write(DDR, SET, COLUMN_3); - _update_rows(matrix, 3); - teensypin_write(DDR, CLEAR, COLUMN_3); - - teensypin_write(DDR, SET, COLUMN_4); - _update_rows(matrix, 4); - teensypin_write(DDR, CLEAR, COLUMN_4); - - teensypin_write(DDR, SET, COLUMN_5); - _update_rows(matrix, 5); - teensypin_write(DDR, CLEAR, COLUMN_5); - - teensypin_write(DDR, SET, COLUMN_6); - _update_rows(matrix, 6); - teensypin_write(DDR, CLEAR, COLUMN_6); + #if TEENSY__DRIVE_ROWS + update_columns_for_row(matrix, 0); + update_columns_for_row(matrix, 1); + update_columns_for_row(matrix, 2); + update_columns_for_row(matrix, 3); + update_columns_for_row(matrix, 4); + update_columns_for_row(matrix, 5); + #elif TEENSY__DRIVE_COLUMNS + update_rows_for_column(matrix, 7); + update_rows_for_column(matrix, 8); + update_rows_for_column(matrix, 9); + update_rows_for_column(matrix, A); + update_rows_for_column(matrix, B); + update_rows_for_column(matrix, C); + update_rows_for_column(matrix, D); + #endif return 0; // success } - diff --git a/src/keyboard/ergodox/controller/teensy-2-0.md b/src/keyboard/ergodox/controller/teensy-2-0.md index 48a5c75..a1df8f6 100644 --- a/src/keyboard/ergodox/controller/teensy-2-0.md +++ b/src/keyboard/ergodox/controller/teensy-2-0.md @@ -29,16 +29,16 @@ ### Teensy 2.0 Pin Assignments power_negative GND +---.....---+ Vcc power_positive - column_0 PB0 + + PF0 row_5 - column_1 PB1 + + PF1 row_4 - column_2 PB2 + + PF4 row_3 - column_3 PB3 + o o + PF5 row_2 + column_7 PB0 + + PF0 row_5 + column_8 PB1 + + PF1 row_4 + column_9 PB2 + + PF4 row_3 + column_A PB3 + o o + PF5 row_2 (OC1C) LED_3 PB7 + PE6 AREF + PF6 row_1 (SCL) I2C PD0 + + PF7 row_0 (SDA) I2C PD1 + + PB6 LED_2 (OC1B) - column_4 PD2 + + PB5 LED_1 (OC1A) - column_5 PD3 + + PB4 = Vcc - column_6 PC6 + o PD7 + column_B PD2 + + PB5 LED_1 (OC1A) + column_C PD3 + + PB4 = Vcc + column_D PC6 + o PD7 PC7 o-o-o-o-o-o-+ PD6 onboardLED = GND PD5 --/ | | | \-- PD4 Vcc ----/ | \---- RST @@ -46,10 +46,13 @@ * notes: * Row and column assignments are to matrix positions, which may or may - correspond to the physical position of the key: e.g. the key where - `row_4` and `column_2` cross will be scanned into the matrix at `[4][2]`, - wherever it happens to be located on the keyboard. Mapping from one to - the other (which only matters for defining layouts) is handled elsewhere. + or may not correspond to the physical position of the key: e.g. the key + where `row_4` and `column_2` cross will be scanned into the matrix at + `[4][2]`, wherever it happens to be located on the keyboard. Mapping + from one to the other (which only matters for defining layouts) is + handled elsewhere. + * LEDs are labeled using numbers (starting with '1') instead of letters + (starting with 'A') as on the PCB. * SCL and SDA: Need external pull-up resistors. Sometimes the Teensy internal pull-ups are enough (see datasheet section 20.5.1), but i think for this project we'll want external ones. The general recommendation @@ -76,14 +79,16 @@ * PD6 (the onboard LED) already has a defined level (low), so there's no reason to set internal pull-up enabled on it. If we do, it will source current to the LED, which is fine, but unnecessary. - * We want the columns to be hi-Z when that column's not being scanned, - drive low when it is, and the rows to be input with pull-up enabled. - We'll cycle through driving the columns low and scanning all rows. + * Initially, we want either columns or rows (see <../options.h>) set as + hi-Z without pull-ups, and the other set of pins set as input with + pull-ups. During the update function, we'll cycle through setting the + first set low and checking each pin in the second set. * To set a pin hi-Z on this board, set it as input with pull-up disabled. - * Switching the row pins between hi-Z and drive low (treating them as - if they were open drain) seems just as good as, and a little safer - than, driving them high when the row's not active. + * Switching the driving pins (the first set of pins) between hi-Z and + drive low (treating them as if they were open drain) seems just as + good as, and a little safer than, driving them high when they're not + active. * We need to delay for at least 1 μs between changing the column pins and reading the row pins. I would assume this is to allow the pins time to stabalize. diff --git a/src/keyboard/ergodox/matrix.h b/src/keyboard/ergodox/matrix.h index 2442ced..e062f47 100644 --- a/src/keyboard/ergodox/matrix.h +++ b/src/keyboard/ergodox/matrix.h @@ -12,8 +12,8 @@ // -------------------------------------------------------------------- - #define KB_ROWS 12 // must match real life - #define KB_COLUMNS 7 // must match real life + #define KB_ROWS 6 // must match real life + #define KB_COLUMNS 14 // must match real life // -------------------------------------------------------------------- @@ -27,56 +27,55 @@ * and 'column' are single digit hex numbers corresponding to the * matrix position (which also corresponds to the row and column pin * labels used in the teensy and mcp23018 files) - * - coordinates not listed are unused * - * - coordinates in the thumb group with row=1|7 are for optional keys + * - coordinates + * - optional keys + * k15, k16 (left hand thumb group) + * k17, k18 (right hand thumb group) + * - unused keys + * k36, k00 (left hand) + * k37, k0D (right hand) * * --- other info ----------------------------------------------------- * rows x columns = positions; used, unused - * per hand: 6 x 7 = 42; 40, 2 - * total: 12 x 7 = 84; 80, 4 + * per hand: 6 x 7 = 42; 40, 2 + * total: 6 x 14 = 84; 80, 4 * - * left hand : cols 0..6, rows 6..B - * right hand : cols 0..6, rows 0..5 + * left hand : rows 0..5, cols 0..6 + * right hand : rows 0..5, cols 7..D * -------------------------------------------------------------------- */ - #define KB_MATRIX_LAYER( \ - /* for unused positions */ \ - na, \ - \ - /* left hand, spatial positions */ \ - kB6,kB5,kB4,kB3,kB2,kB1,kB0, \ - kA6,kA5,kA4,kA3,kA2,kA1,kA0, \ - k96,k95,k94,k93,k92,k91, \ - k86,k85,k84,k83,k82,k81,k80, \ - k76,k75,k74,k73,k72, \ - k63,k71, \ - k64,k70,k61, \ - k65,k62,k60, \ - \ - /* right hand, spatial positions */ \ - k50,k51,k52,k53,k54,k55,k56, \ - k40,k41,k42,k43,k44,k45,k46, \ - k31,k32,k33,k34,k35,k36, \ - k20,k21,k22,k23,k24,k25,k26, \ - k12,k13,k14,k15,k16, \ - k11,k03, \ - k01,k10,k04, \ - k00,k02,k05 ) \ - \ - /* matrix positions */ \ - { { k00,k01,k02,k03,k04,k05, na,}, \ - { k10,k11,k12,k13,k14,k15,k16,}, \ - { k20,k21,k22,k23,k24,k25,k26,}, \ - { na,k31,k32,k33,k34,k35,k36,}, \ - { k40,k41,k42,k43,k44,k45,k46,}, \ - { k50,k51,k52,k53,k54,k55,k56,}, \ - { k60,k61,k62,k63,k64,k65, na,}, \ - { k70,k71,k72,k73,k74,k75,k76,}, \ - { k80,k81,k82,k83,k84,k85,k86,}, \ - { na,k91,k92,k93,k94,k95,k96,}, \ - { kA0,kA1,kA2,kA3,kA4,kA5,kA6,}, \ - { kB0,kB1,kB2,kB3,kB4,kB5,kB6 } } + #define KB_MATRIX_LAYER( \ + /* for unused positions */ \ + na, \ + \ + /* left hand, spatial positions */ \ + k50,k51,k52,k53,k54,k55,k56, \ + k40,k41,k42,k43,k44,k45,k46, \ + k30,k31,k32,k33,k34,k35, \ + k20,k21,k22,k23,k24,k25,k26, \ + k10,k11,k12,k13,k14, \ + k03,k15, \ + k02,k16,k05, \ + k01,k04,k06, \ + \ + /* right hand, spatial positions */ \ + k57,k58,k59,k5A,k5B,k5C,k5D, \ + k47,k48,k49,k4A,k4B,k4C,k4D, \ + k38,k39,k3A,k3B,k3C,k3D, \ + k27,k28,k29,k2A,k2B,k2C,k2D, \ + k19,k1A,k1B,k1C,k1D, \ + k18,k0A, \ + k08,k17,k0B, \ + k07,k09,k0C ) \ + \ + /* matrix positions */ \ + {{ na,k01,k02,k03,k04,k05,k06, k07,k08,k09,k0A,k0B,k0C, na }, \ + { k10,k11,k12,k13,k14,k15,k16, k17,k18,k19,k1A,k1B,k1C,k1D }, \ + { k20,k21,k22,k23,k24,k25,k26, k27,k28,k29,k2A,k2B,k2C,k2D }, \ + { k30,k31,k32,k33,k34,k35, na, na,k38,k39,k3A,k3B,k3C,k3D }, \ + { k40,k41,k42,k43,k44,k45,k46, k47,k48,k49,k4A,k4B,k4C,k4D }, \ + { k50,k51,k52,k53,k54,k55,k56, k57,k58,k59,k5A,k5B,k5C,k5D }} #define KB_MATRIX_LAYER_SET_ALL(na, kxx) \