/* Copyright 2017 Luiz Ribeiro 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 . */ #include #include #include #include "matrix.h" #ifndef DEBOUNCE # define DEBOUNCE 5 #endif // #define MATRIX_ROW_PINS { A7, A6, A5, A4 } // #define MATRIX_COL_PINS { D7, C2, C3, C4, C5, C6, C7, A3, A2, A1, A0, B0 } static uint8_t debouncing = DEBOUNCE; static matrix_row_t matrix[MATRIX_ROWS]; static matrix_row_t matrix_debouncing[MATRIX_ROWS]; static uint8_t encoder_state[2] = {0}; static int8_t encoder_value[2] = {0}; static int8_t encoder_LUT[] = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 }; static bool dip_switch[4] = {0, 0, 0, 0}; __attribute__ ((weak)) void dip_update(uint8_t index, bool active) { } __attribute__ ((weak)) void encoder_update(uint8_t index, bool clockwise) { } bool last_dip_switch[4] = {0}; #ifndef ENCODER_RESOLUTION #define ENCODER_RESOLUTION 4 #endif #define NUMBER_OF_ENCODERS 2 uint8_t read_encoder_state(uint8_t index) { switch (index) { case 0: return (((PINB & (1 << 4)) << 0) ? 1 : 0) | ((((PINB & (1 << 3)) << 0) ? 1 : 0) << 1); break; case 1: return (((PINB & (1 << 2)) << 0) ? 1 : 0) | ((((PINB & (1 << 1)) << 0) ? 1 : 0) << 1); break; } return 0; } void matrix_init(void) { // disables JTAG so we can use them as columns MCUCSR = (1<= ENCODER_RESOLUTION) { encoder_update(i, 0); } if (encoder_value[i] <= -ENCODER_RESOLUTION) { // direction is arbitrary here, but this clockwise encoder_update(i, 1); } encoder_value[i] %= ENCODER_RESOLUTION; } // actual matrix scan for (uint8_t c = 0; c < MATRIX_ROWS; c++) { switch (c) { case 0: PORTA &= ~(1 << 7); break; case 1: PORTA &= ~(1 << 6); break; case 2: PORTA &= ~(1 << 5); break; case 3: PORTA &= ~(1 << 4); break; } _delay_us(5); matrix_row_t current_row = ( (((PIND & (1 << 7)) ? 0 : 1 ) << 0) | (((PINC & (1 << 2)) ? 0 : 1 ) << 1) | (((PINC & (1 << 3)) ? 0 : 1 ) << 2) | (((PINC & (1 << 4)) ? 0 : 1 ) << 3) | (((PINC & (1 << 5)) ? 0 : 1 ) << 4) | (((PINC & (1 << 6)) ? 0 : 1 ) << 5) | (((PINC & (1 << 7)) ? 0 : 1 ) << 6) | (((PINA & (1 << 3)) ? 0 : 1 ) << 7) | (((PINA & (1 << 2)) ? 0 : 1 ) << 8) | (((PINA & (1 << 1)) ? 0 : 1 ) << 9) | (((PINA & (1 << 0)) ? 0 : 1 ) << 10) | (((PINB & (1 << 0)) ? 0 : 1 ) << 11) ); switch (c) { case 0: PORTA |= (1 << 7); break; case 1: PORTA |= (1 << 6); break; case 2: PORTA |= (1 << 5); break; case 3: PORTA |= (1 << 4); break; } if (matrix_debouncing[c] != current_row) { matrix_debouncing[c] = current_row; debouncing = DEBOUNCE; } } if (debouncing) { if (--debouncing) { _delay_ms(1); } else { for (uint8_t i = 0; i < MATRIX_ROWS; i++) { matrix[i] = matrix_debouncing[i]; } } } matrix_scan_quantum(); return 1; } inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; } void matrix_print(void) { } __attribute__ ((weak)) void matrix_init_user(void) { } __attribute__ ((weak)) void matrix_scan_user(void) { }