|  |  |  | @ -28,29 +28,19 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
			
		
	
		
			
				
					|  |  |  |  | #include "matrix.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #if (MATRIX_COLS > 16) | 
			
		
	
		
			
				
					|  |  |  |  | #   error "MATRIX_COLS must not exceed 16" | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | #if (MATRIX_ROWS > 255) | 
			
		
	
		
			
				
					|  |  |  |  | #   error "MATRIX_ROWS must not exceed 255" | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #ifndef DEBOUNCE | 
			
		
	
		
			
				
					|  |  |  |  | #   define DEBOUNCE	5 | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | static uint8_t debouncing = DEBOUNCE; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // matrix state buffer(1:on, 0:off)
 | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t *matrix; | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t *matrix_debouncing; | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t matrix0[MATRIX_ROWS]; | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t matrix1[MATRIX_ROWS]; | 
			
		
	
		
			
				
					|  |  |  |  | /* matrix state(1:on, 0:off) */ | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t matrix[MATRIX_ROWS]; | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t matrix_debouncing[MATRIX_ROWS]; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #ifdef MATRIX_HAS_GHOST | 
			
		
	
		
			
				
					|  |  |  |  | static bool matrix_has_ghost_in_row(uint8_t row); | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t read_col(void); | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t read_cols(void); | 
			
		
	
		
			
				
					|  |  |  |  | static void unselect_rows(void); | 
			
		
	
		
			
				
					|  |  |  |  | static void select_row(uint8_t row); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -77,36 +67,34 @@ void matrix_init(void) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // initialize matrix state: all keys off
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (uint8_t i=0; i < MATRIX_ROWS; i++) { | 
			
		
	
		
			
				
					|  |  |  |  |         matrix0[i] = 0; | 
			
		
	
		
			
				
					|  |  |  |  |         matrix1[i] = 0; | 
			
		
	
		
			
				
					|  |  |  |  |         matrix[i] = 0; | 
			
		
	
		
			
				
					|  |  |  |  |         matrix_debouncing[i] = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     matrix = matrix0; | 
			
		
	
		
			
				
					|  |  |  |  |     matrix_debouncing = matrix1; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | uint8_t matrix_scan(void) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | 
			
		
	
		
			
				
					|  |  |  |  |         unselect_rows(); | 
			
		
	
		
			
				
					|  |  |  |  |         select_row(i); | 
			
		
	
		
			
				
					|  |  |  |  |         _delay_us(30);  // without this wait read unstable value.
 | 
			
		
	
		
			
				
					|  |  |  |  |         if (matrix[i] != read_col()) { | 
			
		
	
		
			
				
					|  |  |  |  |             matrix[i] = read_col(); | 
			
		
	
		
			
				
					|  |  |  |  |         matrix_row_t cols = read_cols(); | 
			
		
	
		
			
				
					|  |  |  |  |         if (matrix_debouncing[i] != cols) { | 
			
		
	
		
			
				
					|  |  |  |  |             matrix_debouncing[i] = cols; | 
			
		
	
		
			
				
					|  |  |  |  |             if (debouncing) { | 
			
		
	
		
			
				
					|  |  |  |  |                 debug("bounce!: "); debug_hex(debouncing); print("\n"); | 
			
		
	
		
			
				
					|  |  |  |  |                 debug("bounce!: "); debug_hex(debouncing); debug("\n"); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             debouncing = DEBOUNCE; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |         unselect_rows(); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (debouncing) { | 
			
		
	
		
			
				
					|  |  |  |  |         if (--debouncing) { | 
			
		
	
		
			
				
					|  |  |  |  |             _delay_ms(1); | 
			
		
	
		
			
				
					|  |  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  |  |             matrix_row_t *tmp = matrix; | 
			
		
	
		
			
				
					|  |  |  |  |             matrix = matrix_debouncing; | 
			
		
	
		
			
				
					|  |  |  |  |             matrix_debouncing = tmp; | 
			
		
	
		
			
				
					|  |  |  |  |             for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | 
			
		
	
		
			
				
					|  |  |  |  |                 matrix[i] = matrix_debouncing[i]; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
	
		
			
				
					|  |  |  | @ -123,7 +111,7 @@ bool matrix_is_modified(void) | 
			
		
	
		
			
				
					|  |  |  |  | inline | 
			
		
	
		
			
				
					|  |  |  |  | bool matrix_is_on(uint8_t row, uint8_t col) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     return (matrix[row] & (1<<col)); | 
			
		
	
		
			
				
					|  |  |  |  |     return (matrix[row] & ((matrix_row_t)1<<col)); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | inline | 
			
		
	
	
		
			
				
					|  |  |  | @ -137,11 +125,7 @@ void matrix_print(void) | 
			
		
	
		
			
				
					|  |  |  |  |     print("\nr/c 01234567\n"); | 
			
		
	
		
			
				
					|  |  |  |  |     for (uint8_t row = 0; row < matrix_rows(); row++) { | 
			
		
	
		
			
				
					|  |  |  |  |         phex(row); print(": "); | 
			
		
	
		
			
				
					|  |  |  |  | #if (MATRIX_COLS <= 8) | 
			
		
	
		
			
				
					|  |  |  |  |         pbin_reverse(matrix_get_row(row)); | 
			
		
	
		
			
				
					|  |  |  |  | #else | 
			
		
	
		
			
				
					|  |  |  |  |         pbin_reverse16(matrix_get_row(row)); | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | #ifdef MATRIX_HAS_GHOST | 
			
		
	
		
			
				
					|  |  |  |  |         if (matrix_has_ghost_in_row(row)) { | 
			
		
	
		
			
				
					|  |  |  |  |             print(" <ghost"); | 
			
		
	
	
		
			
				
					|  |  |  | @ -151,19 +135,6 @@ void matrix_print(void) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | uint8_t matrix_key_count(void) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     uint8_t count = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | 
			
		
	
		
			
				
					|  |  |  |  | #if (MATRIX_COLS <= 8) | 
			
		
	
		
			
				
					|  |  |  |  |         count += bitpop(matrix[i]); | 
			
		
	
		
			
				
					|  |  |  |  | #else | 
			
		
	
		
			
				
					|  |  |  |  |         count += bitpop16(matrix[i]); | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     return count; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #ifdef MATRIX_HAS_GHOST | 
			
		
	
		
			
				
					|  |  |  |  | inline | 
			
		
	
		
			
				
					|  |  |  |  | static bool matrix_has_ghost_in_row(uint8_t row) | 
			
		
	
	
		
			
				
					|  |  |  | @ -174,7 +145,7 @@ static bool matrix_has_ghost_in_row(uint8_t row) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     // ghost exists in case same state as other row
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (uint8_t i=0; i < MATRIX_ROWS; i++) { | 
			
		
	
		
			
				
					|  |  |  |  |         if (i != row && (matrix[i] & matrix[row]) == matrix[row]) | 
			
		
	
		
			
				
					|  |  |  |  |         if (i != row && (matrix[i] & matrix[row])) | 
			
		
	
		
			
				
					|  |  |  |  |             return true; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  |     return false; | 
			
		
	
	
		
			
				
					|  |  |  | @ -182,7 +153,7 @@ static bool matrix_has_ghost_in_row(uint8_t row) | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | inline | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t read_col(void) | 
			
		
	
		
			
				
					|  |  |  |  | static matrix_row_t read_cols(void) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     return ~PINB; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |