diff --git a/src/kaleidoscope/device/technomancy/Atreus.cpp b/src/kaleidoscope/device/technomancy/Atreus.cpp index 27d325d2..4255534e 100644 --- a/src/kaleidoscope/device/technomancy/Atreus.cpp +++ b/src/kaleidoscope/device/technomancy/Atreus.cpp @@ -30,15 +30,52 @@ #include "kaleidoscope/Runtime.h" #include "kaleidoscope/driver/keyscanner/Base_Impl.h" +// Here, we set up aliases to the device's KeyScanner and KeyScannerProps +// in the global namespace within the scope of this file. We'll use these +// aliases to simplify some template initialization code below. +using KeyScannerProps = typename kaleidoscope::device::technomancy::AtreusProps::KeyScannerProps; +using KeyScanner = typename kaleidoscope::device::technomancy::AtreusProps::KeyScanner; + + namespace kaleidoscope { namespace device { namespace technomancy { -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; } -} -} + +} // namespace technomancy +} // namespace device +} // namespace kaleidoscope #endif #endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD diff --git a/src/kaleidoscope/device/technomancy/Atreus.h b/src/kaleidoscope/device/technomancy/Atreus.h index 555bca27..ffd0fe3a 100644 --- a/src/kaleidoscope/device/technomancy/Atreus.h +++ b/src/kaleidoscope/device/technomancy/Atreus.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Hardware-Technomancy-Atreus -- Atreus hardware support for Kaleidoscope - * Copyright (C) 2018, 2019 Keyboard.io, Inc + * Copyright (C) 2018, 2019, 2020 Keyboard.io, Inc * * Based on QMK (commit e9a67f8fd) * (C) Jack Humbert, Jun Wako, Phil Hagelberg, and others @@ -35,21 +35,48 @@ namespace kaleidoscope { namespace device { namespace technomancy { -ATMEGA32U4_KEYBOARD( - Atreus, HalfKay, "atreus", +struct AtreusProps : kaleidoscope::device::ATmega32U4KeyboardProps { + struct KeyScannerProps : public kaleidoscope::driver::keyscanner::ATmegaProps { + + static constexpr uint8_t matrix_rows = 4; + static constexpr uint8_t matrix_columns = 12; + typedef MatrixAddr KeyAddr; + +#ifndef KALEIDOSCOPE_VIRTUAL_BUILD + #ifdef KALEIDOSCOPE_HARDWARE_ATREUS_PINOUT_ASTAR - ROW_PIN_LIST({PIN_D0, PIN_D1, PIN_D3, PIN_D2}), - COL_PIN_LIST({PIN_D7, PIN_C6, PIN_B5, PIN_B4, PIN_E6, PIN_D4, PIN_B6, PIN_F6, PIN_F7, PIN_D6, PIN_B7}) + static constexpr uint8_t matrix_row_pins[matrix_rows] = {PIN_D0, PIN_D1, PIN_D3, PIN_D2}; + static constexpr uint8_t matrix_col_pins[matrix_columns] = {PIN_D7, PIN_C6, PIN_B5, PIN_B4, PIN_E6, PIN_D4, PIN_B6, PIN_F6, PIN_F7, PIN_D6, PIN_B7}; #endif + #ifdef KALEIDOSCOPE_HARDWARE_ATREUS_PINOUT_ASTAR_DOWN - ROW_PIN_LIST({PIN_D0, PIN_D1, PIN_D3, PIN_D2}), - COL_PIN_LIST({PIN_B7, PIN_D6, PIN_F7, PIN_F6, PIN_B6, PIN_D4, PIN_E6, PIN_B4, PIN_B5, PIN_C6, PIN_D7}) + static constexpr uint8_t matrix_row_pins[matrix_rows] = {PIN_D0, PIN_D1, PIN_D3, PIN_D2}; + static constexpr uint8_t matrix_col_pins[matrix_columns] = {PIN_B7, PIN_D6, PIN_F7, PIN_F6, PIN_B6, PIN_D4, PIN_E6, PIN_B4, PIN_B5, PIN_C6, PIN_D7}; #endif + #ifdef KALEIDOSCOPE_HARDWARE_ATREUS_PINOUT_LEGACY_TEENSY2 - ROW_PIN_LIST({PIN_D0, PIN_D1, PIN_D2, PIN_D3}), - COL_PIN_LIST({PIN_F6, PIN_F5, PIN_F4, PIN_B7, PIN_B6, PIN_B5, PIN_B4, PIN_B3, PIN_B2, PIN_B1, PIN_B0}) + static constexpr uint8_t matrix_row_pins[matrix_rows] = {PIN_D0, PIN_D1, PIN_D2, PIN_D3}; + static constexpr uint8_t matrix_col_pins[matrix_columns] = {PIN_F6, PIN_F5, PIN_F4, PIN_B7, PIN_B6, PIN_B5, PIN_B4, PIN_B3, PIN_B2, PIN_B1, PIN_B0}; #endif -); + +#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD + }; + + typedef kaleidoscope::driver::keyscanner::ATmega KeyScanner; + typedef kaleidoscope::driver::bootloader::avr::HalfKay BootLoader; + static constexpr const char *short_name = "atreus"; +}; + +#ifndef KALEIDOSCOPE_VIRTUAL_BUILD +class Atreus: public kaleidoscope::device::ATmega32U4Keyboard {}; +#else // ifndef KALEIDOSCOPE_VIRTUAL_BUILD +/* Device definition omitted for virtual device builds. + * We need to forward declare the device name, though, as there are + * some legacy extern references to boards whose definition + * depends on this. + */ +class Atreus; +#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD #define PER_KEY_DATA(dflt, \ R0C0, R0C1, R0C2, R0C3, R0C4, R0C7, R0C8, R0C9, R0C10, R0C11, \