diff --git a/Scan/matrix/matrix.h b/Scan/matrix/matrix.h index 6ac8819..69904ee 100644 --- a/Scan/matrix/matrix.h +++ b/Scan/matrix/matrix.h @@ -30,14 +30,32 @@ // ----- Scan Mode Setting (See matrix_scan.h for more details) ----- -#define scanMode scanCol +#define scanMode scanDual // ----- Key Settings ----- + +// -- Example for scanCol -- +/* #define KEYBOARD_SIZE 16 // # of keys #define MAX_ROW_SIZE 16 // # of keys in the largest row #define MAX_COL_SIZE 1 // # of keys in the largest column +*/ + + +// -- Example for scanRow -- +/* +#define KEYBOARD_SIZE 16 // # of keys +#define MAX_ROW_SIZE 1 // # of keys in the largest row +#define MAX_COL_SIZE 16 // # of keys in the largest column +*/ + + +// -- Example for scanRow_powrCol, scanCol_powrRow, and scanDual -- +#define KEYBOARD_SIZE 69 // # of keys +#define MAX_ROW_SIZE 8 // # of keys in the largest row +#define MAX_COL_SIZE 9 // # of keys in the largest column @@ -54,7 +72,7 @@ static const uint8_t matrix_pinout[][MAX_ROW_SIZE + 1] = { // Thus if a row doesn't use all the key positions, you can denote it as 0, which will be ignored/skipped on each scan // See the keymap.h file for the various preconfigured arrays. -// Scan Mode | Col 1 | Col 2 | Col 3 | Col 4 | Col 4 | ... +// Scan Mode | Col 1 | Col 2 | Col 3 | Col 4 | Col 5 | ... // ------------------------------------------------------- // Row 1 | Key 1 Key 7 Key32 ... // Row 2 | Key 3 Key92 ... @@ -64,13 +82,63 @@ static const uint8_t matrix_pinout[][MAX_ROW_SIZE + 1] = { // ... | +// -- scanCol Example -- +/* { scanMode, pinF0, pinF4, pinB7, pinD3, pinF5, pinF1, pinD1, pinD2, pinF6, pinF7, pinB2, pinD0, pinB0, pinB6, pinB1, pinB3 }, { pinNULL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, +*/ -// Example Rows -//{ pinE0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, -//{ pinE1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0 }, +// -- scanRow Example -- +/* + { scanMode, pinNULL }, + { pinF0, 1 }, + { pinF4, 2 }, + { pinB7, 3 }, + { pinD3, 4 }, + { pinF5, 5 }, + { pinF1, 6 }, + { pinD1, 7 }, + { pinD2, 8 }, + { pinF6, 9 }, + { pinF7, 10 }, + { pinB2, 11 }, + { pinD0, 12 }, + { pinB0, 13 }, + { pinB6, 14 }, + { pinB1, 15 }, + { pinB3, 16 }, +*/ + + +// -- scanRow_powrCol Example and scanCol_powrRow Example -- +// The example is the same, as the difference is whether the row or col is powered, and the other is used to detect the signal + { scanMode, pinF0, pinF4, pinB7, pinD3, pinF5, pinF1, pinD1, pinD2 }, + { pinF6, 1, 2, 3, 4, 5, 6, 7, 8 }, + { pinF7, 9, 10, 11, 12, 13, 14, 15, 16 }, + { pinB2, 17, 20, 30, 40, 50, 60, 59, 38 }, + { pinD0, 18, 21, 31, 41, 51, 61, 67, 39 }, + { pinB0, 19, 22, 32, 42, 52, 62, 68, 47 }, + { pinB6, 27, 23, 33, 43, 53, 63, 69, 48 }, + { pinB1, 28, 24, 34, 44, 54, 64, 0, 49 }, // 0 signifies no key at that location + { pinB3, 29, 25, 35, 45, 55, 65, 0, 57 }, + { pinA0, 37, 26, 36, 46, 56, 66, 0, 58 }, + + +// -- scanDual Example -- +// The example is the same as the previous one, but uses both columns and rows to power and detect, needed for non-NKRO matrices. +/* + { scanMode, pinF0, pinF4, pinB7, pinD3, pinF5, pinF1, pinD1, pinD2 }, + { pinF6, 1, 2, 3, 4, 5, 6, 7, 8 }, + { pinF7, 9, 10, 11, 12, 13, 14, 15, 16 }, + { pinB2, 17, 20, 30, 40, 50, 60, 59, 38 }, + { pinD0, 18, 21, 31, 41, 51, 61, 67, 39 }, + { pinB0, 19, 22, 32, 42, 52, 62, 68, 47 }, + { pinB6, 27, 23, 33, 43, 53, 63, 69, 48 }, + { pinB1, 28, 24, 34, 44, 54, 64, 0, 49 }, // 0 signifies no key at that location + { pinB3, 29, 25, 35, 45, 55, 65, 0, 57 }, + { pinA0, 37, 26, 36, 46, 56, 66, 0, 58 }, +*/ }; diff --git a/Scan/matrix/matrix_scan.c b/Scan/matrix/matrix_scan.c index f8aed80..54f3b6d 100644 --- a/Scan/matrix/matrix_scan.c +++ b/Scan/matrix/matrix_scan.c @@ -37,6 +37,7 @@ // ----- Macros ----- +// -- pinSetup Macros -- #define REG_SET(reg) reg |= (1 << ( matrix[row*(MAX_ROW_SIZE+1)+col] % 10 ) ) #define PIN_SET_COL(pin) \ @@ -69,9 +70,34 @@ case pin##pinLetter##6: \ case pin##pinLetter##7 +// -- Column Scan Macros -- #define PIN_TEST_COL(pin) \ - if ( !( pin & ( 1 << ( matrix[0*(MAX_ROW_SIZE+1)+col] % 10 ) ) ) ) \ - detectArray[matrix[row*(MAX_ROW_SIZE+1)+col]]++; \ + scanCode = matrix[row*(MAX_ROW_SIZE+1)+col]; \ + if ( scanCode && !( pin & ( 1 << ( matrix[0*(MAX_ROW_SIZE+1)+col] % 10 ) ) ) ) \ + detectArray[scanCode]++; \ + break + +// -- Row Scan Macros -- +#define PIN_TEST_ROW(pin) \ + scanCode = matrix[row*(MAX_ROW_SIZE+1)+col]; \ + if ( scanCode && !( pin & ( 1 << ( matrix[row*(MAX_ROW_SIZE+1)+0] % 10 ) ) ) ) \ + detectArray[scanCode]++; \ + break + +// -- Scan Dual Macros -- +#define PIN_DUALTEST_ROW(pin) \ + scanCode = matrix[row*(MAX_ROW_SIZE+1)+col]; \ + if ( scanCode \ + && !( pin & ( 1 << ( matrix[row*(MAX_ROW_SIZE+1)+0] % 10 ) ) ) \ + && detectArray[scanCode] & 0x01 ) \ + { \ + detectArray[scanCode]++; \ + } \ + else \ + { \ + if ( detectArray[scanCode] & 0x01 ) \ + detectArray[scanCode]--; \ + } \ break @@ -193,15 +219,21 @@ inline void matrix_pinSetup( uint8_t *matrix ) PORTF = portF; } -// TODO Proper matrix scanning +// Scans the given matrix determined by the scanMode method inline void matrix_scan( uint8_t *matrix, uint8_t *detectArray ) { - // Column Scan -#if scanMode == scanCol + // Loop variables for all modes uint16_t col = 1; uint16_t row = 1; - for ( ; col < (MAX_ROW_SIZE+1) + 1; col++ ) + uint16_t scanCode = 0; + + + // Column Scan and Column Scan, Power Row +#if scanMode == scanCol || scanMode == scanCol_powrRow + for ( ; row < (MAX_COL_SIZE+1); row++ ) for ( ; col < (MAX_ROW_SIZE+1); col++ ) { + // Scan over the pins for each of the columns, and using the pin alias to determine which pin to set + // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.)) switch ( matrix[0*(MAX_ROW_SIZE+1)+col] / 10 ) { #if defined(__AVR_AT90USB1286__) @@ -220,22 +252,88 @@ inline void matrix_scan( uint8_t *matrix, uint8_t *detectArray ) PIN_TEST_COL(PINF); } } -#endif +#endif // scanMode - // Row Scan -#if scanMode == scanRow -#endif - // Column Scan, Power Row -#if scanMode == scanCol_powrRow + // Row Scan and Row Scan, Power Row +#if scanMode == scanRow || scanMode == scanRow_powrCol + for ( ; col < (MAX_ROW_SIZE+1); col++ ) for ( ; row < (MAX_COL_SIZE+1); row++ ) + { + // Scan over the pins for each of the rows, and using the pin alias to determine which pin to set + // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.)) + switch ( matrix[row*(MAX_ROW_SIZE+1)+0] / 10 ) + { +#if defined(__AVR_AT90USB1286__) + case 0: // PINA + PIN_TEST_ROW(PINA); #endif + case 1: // PINB + PIN_TEST_ROW(PINB); + case 2: // PINC + PIN_TEST_ROW(PINC); + case 3: // PIND + PIN_TEST_ROW(PIND); + case 4: // PINE + PIN_TEST_ROW(PINE); + case 5: // PINF + PIN_TEST_ROW(PINF); + } + } +#endif // scanMode - // Row Scan, Power Column -#if scanMode == scanRow_powrCol -#endif // Dual Scan #if scanMode == scanDual + // First do a scan of all of the columns, marking each one + for ( ; row < (MAX_COL_SIZE+1); row++ ) for ( ; col < (MAX_ROW_SIZE+1); col++ ) + { + // Scan over the pins for each of the columns, and using the pin alias to determine which pin to set + // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.)) + switch ( matrix[0*(MAX_ROW_SIZE+1)+col] / 10 ) + { +#if defined(__AVR_AT90USB1286__) + case 0: // PINA + PIN_TEST_COL(PINA); +#endif + case 1: // PINB + PIN_TEST_COL(PINB); + case 2: // PINC + PIN_TEST_COL(PINC); + case 3: // PIND + PIN_TEST_COL(PIND); + case 4: // PINE + PIN_TEST_COL(PINE); + case 5: // PINF + PIN_TEST_COL(PINF); + } + } + + // Next, do a scan of all of the rows, clearing any "vague" keys (only detected on row, but not column, or vice-versa) + // And marking any keys that are detected on the row and column + col = 1; + row = 1; + for ( ; col < (MAX_ROW_SIZE+1); col++ ) for ( ; row < (MAX_COL_SIZE+1); row++ ) + { + // Scan over the pins for each of the rows, and using the pin alias to determine which pin to set + // (e.g. / 10 is for the pin name (A,B,C,etc.) and % 10 is for the position of the pin (A1,A2,etc.)) + switch ( matrix[row*(MAX_ROW_SIZE+1)+0] / 10 ) + { +#if defined(__AVR_AT90USB1286__) + case 0: // PINA + PIN_DUALTEST_ROW(PINA); +#endif + case 1: // PINB + PIN_DUALTEST_ROW(PINB); + case 2: // PINC + PIN_DUALTEST_ROW(PINC); + case 3: // PIND + PIN_DUALTEST_ROW(PIND); + case 4: // PINE + PIN_DUALTEST_ROW(PINE); + case 5: // PINF + PIN_DUALTEST_ROW(PINF); + } + } #endif } - + diff --git a/Scan/matrix/scan_loop.c b/Scan/matrix/scan_loop.c index 7e0121a..731754e 100644 --- a/Scan/matrix/scan_loop.c +++ b/Scan/matrix/scan_loop.c @@ -76,10 +76,17 @@ inline void scan_setup() inline uint8_t scan_loop() { // Check count to see if the sample threshold may have been reached, otherwise collect more data - if ( scan_count++ < MAX_SAMPLES ) + if ( scan_count < MAX_SAMPLES ) { matrix_scan( (uint8_t*)matrix_pinout, KeyIndex_Array ); + // scanDual requires 2 passes, and thus needs more memory per matrix_scan pass +#if scanMode == scanDual + scan_count += 2; +#else + scan_count++; +#endif + // Signal Main Detection Loop to continue scanning return 0; }