/* * scan matrix */ #include #include #include #include #include "print.h" #include "util.h" #include "controller.h" #include "matrix_skel.h" // matrix is active low. (key on: 0/key off: 1) // row: Hi-Z(unselected)/low output(selected) // PD0, PC7, PD7, PF6, PD6, PD1, PD2, PC6, PF7 // col: input w/pullup // PB0-PB7 // matrix state buffer static uint8_t *matrix; static uint8_t *matrix_prev; static uint8_t _matrix0[MATRIX_ROWS]; static uint8_t _matrix1[MATRIX_ROWS]; static bool matrix_has_ghost_in_row(uint8_t row); static uint8_t read_col(void); static void unselect_rows(void); static void select_row(uint8_t row); inline int matrix_rows(void) { return MATRIX_ROWS; } inline int matrix_cols(void) { return MATRIX_COLS; } // this must be called once before matrix_scan. void matrix_init(void) { // initialize row and col unselect_rows(); DDRB = 0x00; PORTB = 0xFF; // initialize matrix state: all keys off for (int i=0; i < MATRIX_ROWS; i++) _matrix0[i] = 0x00; for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0x00; matrix = _matrix0; matrix_prev = _matrix1; } int matrix_scan(void) { uint8_t *tmp; tmp = matrix_prev; matrix_prev = matrix; matrix = tmp; for (int i = 0; i < MATRIX_ROWS; i++) { select_row(i); _delay_us(30); // without this wait read unstable value. matrix[i] = ~read_col(); unselect_rows(); } return 1; } bool matrix_is_modified(void) { for (int i = 0; i < MATRIX_ROWS; i++) { if (matrix[i] != matrix_prev[i]) return true; } return false; } bool matrix_has_ghost(void) { for (int i = 0; i < MATRIX_ROWS; i++) { if (matrix_has_ghost_in_row(i)) return true; } return false; } inline bool matrix_is_on(int row, int col) { return (matrix[row] & (1<