@ -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,8 +22,11 @@
# 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 namespace kaleidoscope : : device : : keyboardio ;
using KeyScannerProps = typename AtreusProps : : KeyScannerProps ;
using KeyScannerProps = typename AtreusProps : : KeyScannerProps ;
using KeyScanner = typename AtreusProps : : KeyScanner ;
using KeyScanner = typename AtreusProps : : KeyScanner ;
@ -31,17 +34,34 @@ namespace kaleidoscope {
namespace device {
namespace device {
namespace keyboardio {
namespace keyboardio {
// `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_rows ;
const uint8_t KeyScannerProps : : matrix_columns ;
const uint8_t KeyScannerProps : : matrix_columns ;
constexpr uint8_t KeyScannerProps : : matrix_row_pins [ matrix_rows ] ;
constexpr uint8_t KeyScannerProps : : matrix_row_pins [ matrix_rows ] ;
constexpr uint8_t KeyScannerProps : : matrix_col_pins [ matrix_columns ] ;
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 : : previousKeyState_ [ KeyScannerProps : : matrix_rows ] = { } ;
template < > uint16_t KeyScanner : : keyState_ [ KeyScannerProps : : matrix_rows ] = { } ;
template < > uint16_t KeyScanner : : keyState_ [ KeyScannerProps : : matrix_rows ] = { } ;
template < > uint16_t KeyScanner : : masks_ [ KeyScannerProps : : matrix_rows ] = { } ;
template < > uint16_t KeyScanner : : masks_ [ KeyScannerProps : : matrix_rows ] = { } ;
template < > uint8_t KeyScanner : : debounce_matrix_ [ KeyScannerProps : : matrix_rows ] [ KeyScannerProps : : matrix_columns ] = { } ;
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 ) {
ISR ( TIMER1_OVF_vect ) {
Runtime . device ( ) . keyScanner ( ) . do_scan_ = true ;
Runtime . device ( ) . keyScanner ( ) . do_scan_ = true ;
}
}