|
|
@ -1,6 +1,6 @@
|
|
|
|
/* -*- mode: c++ -*-
|
|
|
|
/* -*- mode: c++ -*-
|
|
|
|
* Keyboardio Atreus hardware support for Kaleidoscope
|
|
|
|
* Keyboardio Atreus hardware support for Kaleidoscope
|
|
|
|
* Copyright (C) 2019 Keyboard.io, Inc
|
|
|
|
* Copyright (C) 2019, 2020 Keyboard.io, Inc
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* 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
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
@ -22,11 +22,49 @@
|
|
|
|
#include "kaleidoscope/Runtime.h"
|
|
|
|
#include "kaleidoscope/Runtime.h"
|
|
|
|
#include "kaleidoscope/driver/keyscanner/Base_Impl.h"
|
|
|
|
#include "kaleidoscope/driver/keyscanner/Base_Impl.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// We're using the `kaleidoscope::device::keyboardio` namespace, and set up the
|
|
|
|
|
|
|
|
// aliases here, so that they're in the global namespace, within the scope of
|
|
|
|
|
|
|
|
// this file. We do that, because of how templates are resolved and evaluated,
|
|
|
|
|
|
|
|
// see more just down below!
|
|
|
|
|
|
|
|
using namespace kaleidoscope::device::keyboardio;
|
|
|
|
|
|
|
|
using KeyScannerProps = typename AtreusProps::KeyScannerProps;
|
|
|
|
|
|
|
|
using KeyScanner = typename AtreusProps::KeyScanner;
|
|
|
|
|
|
|
|
|
|
|
|
namespace kaleidoscope {
|
|
|
|
namespace kaleidoscope {
|
|
|
|
namespace device {
|
|
|
|
namespace device {
|
|
|
|
namespace keyboardio {
|
|
|
|
namespace keyboardio {
|
|
|
|
|
|
|
|
|
|
|
|
ATMEGA_KEYSCANNER_BOILERPLATE
|
|
|
|
// `KeyScannerProps` here refers to the alias set up above. We do not need to
|
|
|
|
|
|
|
|
// prefix the `matrix_rows` and `matrix_columns` names within the array
|
|
|
|
|
|
|
|
// declaration, because those are resolved within the context of the class, so
|
|
|
|
|
|
|
|
// the `matrix_rows` in `KeyScannerProps::matrix_row_pins[matrix_rows]` gets
|
|
|
|
|
|
|
|
// resolved as `KeyScannerProps::matrix_rows`.
|
|
|
|
|
|
|
|
const uint8_t KeyScannerProps::matrix_rows;
|
|
|
|
|
|
|
|
const uint8_t KeyScannerProps::matrix_columns;
|
|
|
|
|
|
|
|
constexpr uint8_t KeyScannerProps::matrix_row_pins[matrix_rows];
|
|
|
|
|
|
|
|
constexpr uint8_t KeyScannerProps::matrix_col_pins[matrix_columns];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Resolving is a bit different in case of templates, however: the name of the
|
|
|
|
|
|
|
|
// array is resolved within the scope of the namespace and the class, but the
|
|
|
|
|
|
|
|
// array size is not - because it is a template. Therefore, we need a fully
|
|
|
|
|
|
|
|
// qualified name there - or an alias in the global scope, which we set up just
|
|
|
|
|
|
|
|
// above.
|
|
|
|
|
|
|
|
template<> uint16_t KeyScanner::previousKeyState_[KeyScannerProps::matrix_rows] = {};
|
|
|
|
|
|
|
|
template<> uint16_t KeyScanner::keyState_[KeyScannerProps::matrix_rows] = {};
|
|
|
|
|
|
|
|
template<> uint16_t KeyScanner::masks_[KeyScannerProps::matrix_rows] = {};
|
|
|
|
|
|
|
|
template<> uint8_t KeyScanner::debounce_matrix_[KeyScannerProps::matrix_rows][KeyScannerProps::matrix_columns] = {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// We set up the TIMER1 interrupt vector here. Due to dependency reasons, this
|
|
|
|
|
|
|
|
// cannot be in a header-only driver, and must be placed here.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// Timer1 is responsible for setting a property on the KeyScanner, which will
|
|
|
|
|
|
|
|
// tell it to do a scan. We use this to make sure that scans happen at roughly
|
|
|
|
|
|
|
|
// the intervals we want. We do the scan outside of the interrupt scope for
|
|
|
|
|
|
|
|
// practical reasons: guarding every codepath against interrupts that can be
|
|
|
|
|
|
|
|
// reached from the scan is far too tedious, for very little gain.
|
|
|
|
|
|
|
|
ISR(TIMER1_OVF_vect) {
|
|
|
|
|
|
|
|
Runtime.device().keyScanner().do_scan_ = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|