diff options
author | tmk <nobody@nowhere> | 2010-10-14 17:36:00 +0900 |
---|---|---|
committer | tmk <nobody@nowhere> | 2010-10-15 11:09:57 +0900 |
commit | 54b5bafaacf0d7863b7bdb84dd69cbc80db77956 (patch) | |
tree | 38cf278aebedf9c35bf09c418d2b9d09bc611257 /macway/matrix.c | |
parent | 82637ded2737bfd80a2c1b85c0a9ae0b6fd33bd7 (diff) |
add directories for each keyboard: hhkb, macway
Diffstat (limited to 'macway/matrix.c')
-rw-r--r-- | macway/matrix.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/macway/matrix.c b/macway/matrix.c new file mode 100644 index 0000000000..cb52d79c30 --- /dev/null +++ b/macway/matrix.c @@ -0,0 +1,181 @@ +/* + * scan matrix + */ +#include <avr/io.h> +#include <util/delay.h> +#include "keymap.h" +#include "matrix.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 +uint8_t *matrix; +uint8_t *matrix_prev; +static uint8_t _matrix0[MATRIX_ROWS]; +static uint8_t _matrix1[MATRIX_ROWS]; + +static uint8_t read_col(void); +static void unselect_rows(void); +static void select_row(uint8_t row); + + +// 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] = 0xFF; + for (int i=0; i < MATRIX_ROWS; i++) _matrix1[i] = 0xFF; + matrix = _matrix0; + matrix_prev = _matrix1; +} + +uint8_t matrix_scan(void) +{ + uint8_t row, state; + uint8_t *tmp; + + tmp = matrix_prev; + matrix_prev = matrix; + matrix = tmp; + + for (row = 0; row < MATRIX_ROWS; row++) { + select_row(row); + _delay_us(30); // without this wait read unstable value. + state = read_col(); + unselect_rows(); + + matrix[row] = state; + } + 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; +} + +bool matrix_has_ghost_in_row(uint8_t row) { + uint8_t state = ~matrix[row]; + // no ghost exists in case less than 2 keys on + if (((state - 1) & state) == 0) + return false; + + // ghost exists in case same state as other row + for (int i=0; i < MATRIX_ROWS; i++) { + if (i == row) continue; + if ((~matrix[i] & state) == state) return true; + } + return false; +} + +static uint8_t read_col(void) +{ + return PINB; +} + +static void unselect_rows(void) { + DDRD = 0x00; + PORTD = 0x00; + DDRC = 0x00; + PORTC = 0x00; + DDRF = 0x00; + PORTF = 0x00; +} + +static void select_row(uint8_t row) +{ + switch (row) { + case 0: + DDRD = (1<<0); + PORTD = 0x00; + DDRC = 0x00; + PORTC = 0x00; + DDRF = 0x00; + PORTF = 0x00; + break; + case 1: + DDRD = 0x00; + PORTD = 0x00; + DDRC = (1<<7); + PORTC = 0x00; + DDRF = 0x00; + PORTF = 0x00; + break; + case 2: + DDRD = (1<<7); + PORTD = 0x00; + DDRC = 0x00; + PORTC = 0x00; + DDRF = 0x00; + PORTF = 0x00; + break; + case 3: + DDRD = 0x00; + PORTD = 0x00; + DDRC = 0x00; + PORTC = 0x00; + DDRF = (1<<6); + PORTF = 0x00; + break; + case 4: + DDRD = (1<<6); + PORTD = 0x00; + DDRC = 0x00; + PORTC = 0x00; + DDRF = 0x00; + PORTF = 0x00; + break; + case 5: + DDRD = (1<<1); + PORTD = 0x00; + DDRC = 0x00; + PORTC = 0x00; + DDRF = 0x00; + PORTF = 0x00; + break; + case 6: + DDRD = (1<<2); + PORTD = 0x00; + DDRC = 0x00; + PORTC = 0x00; + DDRF = 0x00; + PORTF = 0x00; + break; + case 7: + DDRD = 0x00; + PORTD = 0x00; + DDRC = (1<<6); + PORTC = 0x00; + DDRF = 0x00; + PORTF = 0x00; + break; + case 8: + DDRD = 0x00; + PORTD = 0x00; + DDRC = 0x00; + PORTC = 0x00; + DDRF = (1<<7); + PORTF = 0x00; + break; + } +} |