/* Copyright 2012 Jun Wako This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * scan matrix */ #include #include #include #include #include #include #include "print.h" #include "debug.h" #include "util.h" #include "timer.h" #include "matrix.h" #include "i2c.h" #include "serial.h" #include "split-util.h" #include "pro-micro.h" #include "config.h" #include "pin_defs.h" #ifndef DEBOUNCE # define DEBOUNCE 5 #endif #define ERROR_DISCONNECT_COUNT 5 #define I2C_MATRIX_ADDR 0x00 #define I2C_LED_ADDR ROWS_PER_HAND static uint8_t debouncing = DEBOUNCE; static uint8_t error_count = 0; /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; static matrix_row_t matrix_debouncing[MATRIX_ROWS]; static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; static matrix_row_t read_cols(void); static void init_cols(void); static void unselect_rows(void); static void select_row(uint8_t row); inline uint8_t matrix_rows(void) { return MATRIX_ROWS; } inline uint8_t matrix_cols(void) { return MATRIX_COLS; } void matrix_init(void) { // To use PORTF disable JTAG with writing JTD bit twice within four cycles. MCUCR |= (1< ERROR_DISCONNECT_COUNT) { // reset other half if disconnected int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0; for (int i = 0; i < ROWS_PER_HAND; ++i) { matrix[slaveOffset+i] = 0; } } } else { // turn off the indicator led on no error TXLED0; error_count = 0; } return ret; } void matrix_slave_scan(void) { _matrix_scan(); int offset = (isLeftHand) ? 0 : (MATRIX_ROWS / 2); #ifdef USE_I2C for (int i = 0; i < ROWS_PER_HAND; ++i) { i2c_slave_write(I2C_MATRIX_ADDR+i, matrix[offset+i]); } #ifdef I2C_WRITE_TEST_CODE // control the pro micro RX LED based on what the // i2c master has sent us uint8_t led_state = i2c_slave_read(I2C_LED_ADDR); if (led_state == 1) { RXLED1; } else if(led_state == 0) { RXLED0; } #endif #else for (int i = 0; i < ROWS_PER_HAND; ++i) { serial_slave_buffer[i] = matrix[offset+i]; } #endif } bool matrix_is_modified(void) { if (debouncing) return false; return true; } inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1<> 4) + 1) &= ~_BV(col_pins[x] & 0xF); _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF); } } static matrix_row_t read_cols(void) { matrix_row_t result = 0; for(int x = 0; x < MATRIX_COLS; x++) { result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x); } return result; } static void unselect_rows(void) { for(int x = 0; x < ROWS_PER_HAND; x++) { _SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF); _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF); } } static void select_row(uint8_t row) { _SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF); _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF); }