Merge pull request #473 from keyboardio/f/optimize-avr-keyboards

Optimize keyscanner for 'avr' native keyboards
pull/474/head
Gergely Nagy 6 years ago committed by GitHub
commit 873968404c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -40,11 +40,11 @@ void ATMegaKeyboard::setup(void) {
OUTPUT_HIGH(KeyboardHardware.matrix_row_pins[i]); OUTPUT_HIGH(KeyboardHardware.matrix_row_pins[i]);
} }
/* Set up Timer1 for 500usec */ /* Set up Timer1 for 1700usec */
TCCR1B = _BV(WGM13); TCCR1B = _BV(WGM13);
TCCR1A = 0; TCCR1A = 0;
const uint32_t cycles = (F_CPU / 2000000) * 500; const uint32_t cycles = (F_CPU / 2000000) * 1700;
ICR1 = cycles; ICR1 = cycles;
TCCR1B = _BV(WGM13) | _BV(CS10); TCCR1B = _BV(WGM13) | _BV(CS10);
@ -59,12 +59,10 @@ void ATMegaKeyboard::attachToHost() {
UDCON &= ~_BV(DETACH); UDCON &= ~_BV(DETACH);
} }
void ATMegaKeyboard::readMatrix(void) { void __attribute__((optimize(3))) ATMegaKeyboard::readMatrix(void) {
for (uint8_t current_row = 0; current_row < KeyboardHardware.matrix_rows; current_row++) { for (uint8_t current_row = 0; current_row < KeyboardHardware.matrix_rows; current_row++) {
uint16_t mask, cols; uint16_t mask, cols;
KeyboardHardware.previousKeyState_[current_row] = KeyboardHardware.keyState_[current_row];
mask = KeyboardHardware.debounceMaskForRow(current_row); mask = KeyboardHardware.debounceMaskForRow(current_row);
OUTPUT_TOGGLE(KeyboardHardware.matrix_row_pins[current_row]); OUTPUT_TOGGLE(KeyboardHardware.matrix_row_pins[current_row]);
@ -95,7 +93,7 @@ bool ATMegaKeyboard::isKeyswitchPressed(uint8_t keyIndex) {
keyIndex % KeyboardHardware.matrix_columns); keyIndex % KeyboardHardware.matrix_columns);
} }
void ATMegaKeyboard::actOnMatrixScan() { void __attribute__((optimize(3))) ATMegaKeyboard::actOnMatrixScan() {
for (byte row = 0; row < KeyboardHardware.matrix_rows; row++) { for (byte row = 0; row < KeyboardHardware.matrix_rows; row++) {
for (byte col = 0; col < KeyboardHardware.matrix_columns; col++) { for (byte col = 0; col < KeyboardHardware.matrix_columns; col++) {
uint8_t keyState = (bitRead(KeyboardHardware.previousKeyState_[row], col) << 0) | uint8_t keyState = (bitRead(KeyboardHardware.previousKeyState_[row], col) << 0) |
@ -109,12 +107,12 @@ void ATMegaKeyboard::actOnMatrixScan() {
} }
void ATMegaKeyboard::scanMatrix() { void ATMegaKeyboard::scanMatrix() {
if (!do_scan_) if (do_scan_) {
return; do_scan_ = false;
// We only want to update our matrix if the timer has expired.
do_scan_ = false; KeyboardHardware.readMatrix();
}
KeyboardHardware.readMatrix(); // We ALWAYS want to tell Kaleidoscope about the state of the matrix
KeyboardHardware.actOnMatrixScan(); KeyboardHardware.actOnMatrixScan();
} }
@ -142,6 +140,7 @@ bool ATMegaKeyboard::isKeyMasked(byte row, byte col) {
uint16_t ATMegaKeyboard::readCols() { uint16_t ATMegaKeyboard::readCols() {
uint16_t results = 0x00 ; uint16_t results = 0x00 ;
for (uint8_t i = 0; i < KeyboardHardware.matrix_columns; i++) { for (uint8_t i = 0; i < KeyboardHardware.matrix_columns; i++) {
asm("NOP"); // We need to pause a beat before reading or we may read before the pin is hot
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[i]) << i); results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[i]) << i);
} }
return results; return results;

@ -67,11 +67,11 @@ void ErgoDox::setup(void) {
setStatusLEDBrightness(2, 15); setStatusLEDBrightness(2, 15);
setStatusLEDBrightness(3, 15); setStatusLEDBrightness(3, 15);
/* Set up Timer1 for 500usec */ /* Set up Timer1 for 1700usec */
TCCR1B = _BV(WGM13); TCCR1B = _BV(WGM13);
TCCR1A = 0; TCCR1A = 0;
const uint32_t cycles = (F_CPU / 2000000) * 500; const uint32_t cycles = (F_CPU / 2000000) * 1700;
ICR1 = cycles; ICR1 = cycles;
TCCR1B = _BV(WGM13) | _BV(CS10); TCCR1B = _BV(WGM13) | _BV(CS10);
@ -82,17 +82,16 @@ ISR(TIMER1_OVF_vect) {
do_scan_ = true; do_scan_ = true;
} }
void ErgoDox::readMatrixRow(uint8_t row) { void __attribute__((optimize(3))) ErgoDox::readMatrixRow(uint8_t row) {
uint8_t mask, cols; uint8_t mask, cols;
previousKeyState_[row] = keyState_[row];
mask = debounceMaskForRow(row); mask = debounceMaskForRow(row);
cols = (scanner_.readCols(row) & mask) | (keyState_[row] & ~mask); cols = (scanner_.readCols(row) & mask) | (keyState_[row] & ~mask);
debounceRow(cols ^ keyState_[row], row); debounceRow(cols ^ keyState_[row], row);
keyState_[row] = cols; keyState_[row] = cols;
} }
void ErgoDox::readMatrix() { void __attribute__((optimize(3))) ErgoDox::readMatrix() {
do_scan_ = false; do_scan_ = false;
scanner_.reattachExpanderOnError(); scanner_.reattachExpanderOnError();
@ -108,7 +107,7 @@ void ErgoDox::readMatrix() {
} }
} }
void ErgoDox::actOnMatrixScan() { void __attribute__((optimize(3))) ErgoDox::actOnMatrixScan() {
for (byte row = 0; row < ROWS; row++) { for (byte row = 0; row < ROWS; row++) {
for (byte col = 0; col < COLS; col++) { for (byte col = 0; col < COLS; col++) {
uint8_t keyState = (bitRead(previousKeyState_[row], col) << 0) | uint8_t keyState = (bitRead(previousKeyState_[row], col) << 0) |
@ -116,14 +115,18 @@ void ErgoDox::actOnMatrixScan() {
if (keyState) if (keyState)
handleKeyswitchEvent(Key_NoKey, row, col, keyState); handleKeyswitchEvent(Key_NoKey, row, col, keyState);
} }
previousKeyState_[row] = keyState_[row];
} }
} }
void ErgoDox::scanMatrix() { void ErgoDox::scanMatrix() {
if (!do_scan_) if (do_scan_) {
return; do_scan_ = false;
// We only want to update our matrix if the timer has expired.
readMatrix();
}
readMatrix(); // We ALWAYS want to tell Kaleidoscope about the state of the matrix
actOnMatrixScan(); actOnMatrixScan();
} }

@ -99,7 +99,7 @@ ErgoDoxScanner::begin() {
initCols(); initCols();
} }
void void __attribute__((optimize(3)))
ErgoDoxScanner::selectRow(int row) { ErgoDoxScanner::selectRow(int row) {
if (row < 7) { if (row < 7) {
if (!expander_error_) { if (!expander_error_) {
@ -149,7 +149,7 @@ out:
} }
} }
void void __attribute__((optimize(3)))
ErgoDoxScanner::unselectRows() { ErgoDoxScanner::unselectRows() {
DDRB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3); DDRB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3);
PORTB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3); PORTB &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3);
@ -159,7 +159,7 @@ ErgoDoxScanner::unselectRows() {
PORTC &= ~(1 << 6); PORTC &= ~(1 << 6);
} }
uint8_t uint8_t __attribute__((optimize(3)))
ErgoDoxScanner::readCols(int row) { ErgoDoxScanner::readCols(int row) {
if (row < 7) { if (row < 7) {
if (expander_error_) { if (expander_error_) {

@ -18,6 +18,7 @@
#ifdef ARDUINO_AVR_PLANCK #ifdef ARDUINO_AVR_PLANCK
#include <Kaleidoscope.h> #include <Kaleidoscope.h>
#include <avr/wdt.h>
namespace kaleidoscope { namespace kaleidoscope {
namespace hardware { namespace hardware {

@ -27,6 +27,7 @@
#ifdef ARDUINO_AVR_ATREUS #ifdef ARDUINO_AVR_ATREUS
#include <Kaleidoscope.h> #include <Kaleidoscope.h>
#include <avr/wdt.h>
namespace kaleidoscope { namespace kaleidoscope {
namespace hardware { namespace hardware {
@ -70,22 +71,6 @@ void Atreus::resetDevice() {
asm volatile("jmp 0x7E00"); asm volatile("jmp 0x7E00");
} }
uint16_t Atreus::readCols() {
uint16_t results = 0;
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[0]) << 0);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[1]) << 1);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[2]) << 2);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[3]) << 3);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[4]) << 4);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[5]) << 5);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[6]) << 6);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[7]) << 7);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[8]) << 8);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[9]) << 9);
results |= (!READ_PIN(KeyboardHardware.matrix_col_pins[10]) << 10);
return results;
}
} }
} }

@ -52,7 +52,6 @@ class Atreus: public kaleidoscope::hardware::ATMegaKeyboard {
void resetDevice(); void resetDevice();
protected: protected:
uint16_t readCols();
}; };
#define KEYMAP( \ #define KEYMAP( \

Loading…
Cancel
Save