diff --git a/docs/api-reference/device-apis.md b/docs/api-reference/device-apis.md index 1ed9c076..78c0a229 100644 --- a/docs/api-reference/device-apis.md +++ b/docs/api-reference/device-apis.md @@ -165,11 +165,21 @@ namespace kaleidoscope { namespace device { namespace imaginary { -ATMEGA32U4_KEYBOARD( - Keypad, Caterina, - ROW_PIN_LIST({ PIN_D0, PIN_D1 }), - COL_PIN_LIST({ PIN_C0, PIN_C1 }) -); +struct KeypadProps : kaleidoscope::device::ATmega32U4KeyboardProps { + struct KeyScannerProps : public kaleidoscope::driver::keyscanner::ATmegaProps { + static constexpr uint8_t matrix_rows = 2; + static constexpr uint8_t matrix_columns = 2; + typedef MatrixAddr KeyAddr; + static constexpr uint8_t matrix_row_pins[matrix_rows] = {PIN_D0, PIN_D1}; + static constexpr uint8_t matrix_col_pins[matrix_columns] = {PIN_C0, PIN_C1}; + }; + + typedef kaleidoscope::driver::keyscanner::ATmega KeyScanner; + typedef kaleidoscope::driver::bootloader::avr::Caterina BootLoader; + static constexpr const char *short_name = "imaginary-keypad"; +}; + +class Keypad: public kaleidoscope::device::ATmega32U4Keyboard {}; #define PER_KEY_DATA(dflt, \ R0C0, R0C1, \ @@ -180,7 +190,7 @@ ATMEGA32U4_KEYBOARD( } } -typedef kaleidoscope::device::imaginary::Keypad Device; +EXPORT_DEVICE(kaleidoscope::device::imaginary::Keypad); } #endif @@ -193,11 +203,47 @@ typedef kaleidoscope::device::imaginary::Keypad Device; #include +// 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::imaginary::KeypadProps::KeyScannerProps; +using KeyScanner = typename kaleidoscope::device::imaginary::KeypadProps::KeyScanner; + namespace kaleidoscope { namespace device { namespace imaginary { -AVR_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; +} } } diff --git a/src/kaleidoscope/device/ATmega32U4Keyboard.h b/src/kaleidoscope/device/ATmega32U4Keyboard.h index a58146c0..b9ae02ff 100644 --- a/src/kaleidoscope/device/ATmega32U4Keyboard.h +++ b/src/kaleidoscope/device/ATmega32U4Keyboard.h @@ -27,45 +27,6 @@ #include "kaleidoscope/driver/storage/ATmega32U4EEPROMProps.h" #include "kaleidoscope/driver/storage/AVREEPROM.h" -#define ATMEGA32U4_DEVICE_PROPS(BOARD_, BOOTLOADER_, NAME_, ROW_PINS_, COL_PINS_) \ - struct BOARD_##Props : kaleidoscope::device::ATmega32U4KeyboardProps { \ - struct KeyScannerProps \ - : public kaleidoscope::driver::keyscanner::ATmegaProps \ - { \ - ATMEGA_KEYSCANNER_PROPS(ROW_PIN_LIST(ROW_PINS_), \ - COL_PIN_LIST(COL_PINS_)); \ - }; \ - typedef kaleidoscope::driver::keyscanner::ATmega KeyScanner; \ - typedef kaleidoscope::driver::bootloader::avr::BOOTLOADER_ BootLoader; \ - static constexpr const char *short_name = NAME_; \ - }; - -#define ATMEGA32U4_DEVICE(BOARD_) \ - class BOARD_: public kaleidoscope::device::ATmega32U4Keyboard {}; - -#define FORWARD(...) __VA_ARGS__ - -#ifndef KALEIDOSCOPE_VIRTUAL_BUILD - -#define ATMEGA32U4_KEYBOARD(BOARD_, BOOTLOADER_, NAME_, ROW_PINS_, COL_PINS_) \ - ATMEGA32U4_DEVICE_PROPS(BOARD_, BOOTLOADER_, NAME_, \ - FORWARD(ROW_PINS_), FORWARD(COL_PINS_)) \ - ATMEGA32U4_DEVICE(BOARD_) - -#else // ifndef KALEIDOSCOPE_VIRTUAL_BUILD - -#define ATMEGA32U4_KEYBOARD(BOARD_, BOOTLOADER_, NAME_, ROW_PINS_, COL_PINS_) \ - ATMEGA32U4_DEVICE_PROPS(BOARD_, BOOTLOADER_, NAME_, \ - FORWARD(ROW_PINS_), FORWARD(COL_PINS_)) \ - /* 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 BOARD_; - -#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD - namespace kaleidoscope { namespace device { diff --git a/src/kaleidoscope/device/kbdfans/KBD4x.cpp b/src/kaleidoscope/device/kbdfans/KBD4x.cpp index 963cbd67..6dddcbfd 100644 --- a/src/kaleidoscope/device/kbdfans/KBD4x.cpp +++ b/src/kaleidoscope/device/kbdfans/KBD4x.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Hardware-KBDFans-KBD4x -- KBD4x 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 * it under the terms of version 3 of the GNU General Public License as @@ -18,20 +18,55 @@ #ifndef KALEIDOSCOPE_VIRTUAL_BUILD #ifdef ARDUINO_AVR_KBD4X -#include "kaleidoscope/key_events.h" -#include "kaleidoscope/driver/keyscanner/ATmega.h" -#include "kaleidoscope/driver/keyscanner/Base_Impl.h" #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::kbdfans::KBD4xProps::KeyScannerProps; +using KeyScanner = typename kaleidoscope::device::kbdfans::KBD4xProps::KeyScanner; namespace kaleidoscope { namespace device { namespace kbdfans { -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 kbdfans +} // namespace device +} // namespace kaleidoscope #endif #endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD diff --git a/src/kaleidoscope/device/kbdfans/KBD4x.h b/src/kaleidoscope/device/kbdfans/KBD4x.h index ba1da85f..5a58bc39 100644 --- a/src/kaleidoscope/device/kbdfans/KBD4x.h +++ b/src/kaleidoscope/device/kbdfans/KBD4x.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Hardware-KBDFans-KBD4x -- KBD4x 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 * it under the terms of version 3 of the GNU General Public License as @@ -38,10 +38,13 @@ struct KBD4xProps : kaleidoscope::device::ATmega32U4KeyboardProps { }; typedef kaleidoscope::driver::mcu::ATmega32U4 MCU; struct KeyScannerProps : public kaleidoscope::driver::keyscanner::ATmegaProps { - ATMEGA_KEYSCANNER_PROPS( - ROW_PIN_LIST({ PIN_D0, PIN_D1, PIN_D2, PIN_D3 }), - COL_PIN_LIST({ PIN_F0, PIN_F1, PIN_F4, PIN_F5, PIN_F6, PIN_F7, PIN_B3, PIN_B1, PIN_B0, PIN_D5, PIN_B7, PIN_C7 }) - ); + static constexpr uint8_t matrix_rows = 4; + static constexpr uint8_t matrix_columns = 12; + typedef MatrixAddr KeyAddr; +#ifndef KALEIDOSCOPE_VIRTUAL_BUILD + 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_F0, PIN_F1, PIN_F4, PIN_F5, PIN_F6, PIN_F7, PIN_B3, PIN_B1, PIN_B0, PIN_D5, PIN_B7, PIN_C7 }; +#endif // KALEIDOSCOPE_VIRTUAL_BUILD }; typedef kaleidoscope::driver::keyscanner::ATmega KeyScanner; typedef kaleidoscope::driver::bootloader::avr::FLIP Bootloader; @@ -49,9 +52,15 @@ struct KBD4xProps : kaleidoscope::device::ATmega32U4KeyboardProps { }; #ifndef KALEIDOSCOPE_VIRTUAL_BUILD -ATMEGA32U4_DEVICE(KBD4x); +class KBD4x: 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 KBD4x; + #endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD #define PER_KEY_DATA(dflt, \ diff --git a/src/kaleidoscope/device/keyboardio/Atreus2.cpp b/src/kaleidoscope/device/keyboardio/Atreus2.cpp index d5eb707f..d741da2e 100644 --- a/src/kaleidoscope/device/keyboardio/Atreus2.cpp +++ b/src/kaleidoscope/device/keyboardio/Atreus2.cpp @@ -22,13 +22,12 @@ #include "kaleidoscope/Runtime.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; + +// 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::keyboardio::AtreusProps::KeyScannerProps; +using KeyScanner = typename kaleidoscope::device::keyboardio::AtreusProps::KeyScanner; namespace kaleidoscope { namespace device { diff --git a/src/kaleidoscope/device/keyboardio/Imago.cpp b/src/kaleidoscope/device/keyboardio/Imago.cpp index 35d1c019..6792433e 100644 --- a/src/kaleidoscope/device/keyboardio/Imago.cpp +++ b/src/kaleidoscope/device/keyboardio/Imago.cpp @@ -28,6 +28,12 @@ extern "C" { #define LED_DRIVER_ADDR 0x30 +// 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::keyboardio::ImagoProps::KeyScannerProps; +using KeyScanner = typename kaleidoscope::device::keyboardio::ImagoProps::KeyScanner; + namespace kaleidoscope { namespace device { namespace keyboardio { @@ -53,7 +59,37 @@ static constexpr uint8_t LED_REGISTER_DATA1_SIZE = 0xAB; static constexpr uint8_t LED_REGISTER_DATA_LARGEST = LED_REGISTER_DATA0_SIZE; -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; +} bool ImagoLEDDriver::isLEDChanged = true; cRGB ImagoLEDDriver::led_data[]; diff --git a/src/kaleidoscope/device/keyboardio/Imago.h b/src/kaleidoscope/device/keyboardio/Imago.h index ccf45943..99841fb2 100644 --- a/src/kaleidoscope/device/keyboardio/Imago.h +++ b/src/kaleidoscope/device/keyboardio/Imago.h @@ -85,10 +85,13 @@ class ImagoLEDDriver; struct ImagoProps : kaleidoscope::device::ATmega32U4KeyboardProps { struct KeyScannerProps : public kaleidoscope::driver::keyscanner::ATmegaProps { - ATMEGA_KEYSCANNER_PROPS( - ROW_PIN_LIST({ PIN_F6, PIN_F5, PIN_F4, PIN_F1, PIN_F0}), - COL_PIN_LIST({ PIN_B2, PIN_B7, PIN_E2, PIN_C7, PIN_C6, PIN_B6, PIN_B5, PIN_B4, PIN_D7, PIN_D6, PIN_D4, PIN_D5, PIN_D3, PIN_D2, PIN_E6, PIN_F7}) - ); + static constexpr uint8_t matrix_rows = 5; + static constexpr uint8_t matrix_columns = 16; + typedef MatrixAddr KeyAddr; +#ifndef KALEIDOSCOPE_VIRTUAL_BUILD + static constexpr uint8_t matrix_row_pins[matrix_rows] = {PIN_F6, PIN_F5, PIN_F4, PIN_F1, PIN_F0}; + static constexpr uint8_t matrix_col_pins[matrix_columns] = {PIN_B2, PIN_B7, PIN_E2, PIN_C7, PIN_C6, PIN_B6, PIN_B5, PIN_B4, PIN_D7, PIN_D6, PIN_D4, PIN_D5, PIN_D3, PIN_D2, PIN_E6, PIN_F7}; +#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD }; typedef kaleidoscope::driver::keyscanner::ATmega KeyScanner; typedef ImagoLEDDriverProps LEDDriverProps; diff --git a/src/kaleidoscope/device/olkb/Planck.cpp b/src/kaleidoscope/device/olkb/Planck.cpp index 94b50c48..10e1c690 100644 --- a/src/kaleidoscope/device/olkb/Planck.cpp +++ b/src/kaleidoscope/device/olkb/Planck.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Hardware-OLKB-Planck -- Planck hardware support for Kaleidoscope - * Copyright (C) 2018, 2019 Keyboard.io, Inc + * Copyright (C) 2018, 2019, 2020 Keyboard.io, Inc * * This program is free software: you can redistribute it and/or modify * it under the terms of version 3 of the GNU General Public License as @@ -21,15 +21,51 @@ #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::olkb::PlanckProps::KeyScannerProps; +using KeyScanner = typename kaleidoscope::device::olkb::PlanckProps::KeyScanner; + namespace kaleidoscope { namespace device { namespace olkb { -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 olkb +} // namespace device +} // namespace kaleidoscope #endif #endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD diff --git a/src/kaleidoscope/device/olkb/Planck.h b/src/kaleidoscope/device/olkb/Planck.h index 20806af0..9fc13c51 100644 --- a/src/kaleidoscope/device/olkb/Planck.h +++ b/src/kaleidoscope/device/olkb/Planck.h @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Hardware-OLKB-Planck -- Planck hardware support for Kaleidoscope - * Copyright (C) 2018, 2019 Keyboard.io, Inc + * Copyright (C) 2018, 2019, 2020 Keyboard.io, Inc * * This program is free software: you can redistribute it and/or modify * it under the terms of version 3 of the GNU General Public License as @@ -28,11 +28,32 @@ namespace kaleidoscope { namespace device { namespace olkb { -ATMEGA32U4_KEYBOARD( - Planck, HalfKay, "planck", - ROW_PIN_LIST({ PIN_D0, PIN_D5, PIN_B5, PIN_B6 }), - COL_PIN_LIST({ PIN_F1, PIN_F0, PIN_B0, PIN_C7, PIN_F4, PIN_F5, PIN_F6, PIN_F7, PIN_D4, PIN_D6, PIN_B4, PIN_D7 }) -); +struct PlanckProps : 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 + static constexpr uint8_t matrix_row_pins[matrix_rows] = {PIN_D0, PIN_D5, PIN_B5, PIN_B6}; + static constexpr uint8_t matrix_col_pins[matrix_columns] = {PIN_F0, PIN_F1, PIN_F4, PIN_F5, PIN_F6, PIN_F7, PIN_B3, PIN_B1, PIN_B0, PIN_D5, PIN_B7, PIN_C7}; +#endif // KALEIDOSCOPE_VIRTUAL_BUILD + }; + typedef kaleidoscope::driver::keyscanner::ATmega KeyScanner; + typedef kaleidoscope::driver::bootloader::avr::HalfKay Bootloader; + static constexpr const char *short_name = "planck"; +}; + +#ifndef KALEIDOSCOPE_VIRTUAL_BUILD +class Planck: 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 Planck; + +#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD #define PER_KEY_DATA(dflt, \ R0C0, R0C1, R0C2, R0C3, R0C4, R0C5, R0C6, R0C7, R0C8, R0C9, R0C10, R0C11, \ diff --git a/src/kaleidoscope/device/softhruf/Splitography.cpp b/src/kaleidoscope/device/softhruf/Splitography.cpp index 53bb0b05..bbec531d 100644 --- a/src/kaleidoscope/device/softhruf/Splitography.cpp +++ b/src/kaleidoscope/device/softhruf/Splitography.cpp @@ -1,6 +1,6 @@ /* -*- mode: c++ -*- * Kaleidoscope-Hardware-SOFTHRUF-Splitography -- Splitography hardware support for Kaleidoscope - * Copyright (C) 2018, 2019 Keyboard.io, Inc + * Copyright (C) 2018, 2019, 2020 Keyboard.io, Inc * * Based on QMK (commit e9a67f8fd) and sdothum's fork (commit 8616b44) * (C) Jack Humbert, Jun Wako, Steven Hum, and others @@ -28,15 +28,51 @@ #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::softhruf::SplitographyProps::KeyScannerProps; +using KeyScanner = typename kaleidoscope::device::softhruf::SplitographyProps::KeyScanner; + namespace kaleidoscope { namespace device { namespace softhruf { -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 softhruf +} // namespace device +} // namespace kaleidoscope #endif #endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD diff --git a/src/kaleidoscope/device/softhruf/Splitography.h b/src/kaleidoscope/device/softhruf/Splitography.h index a7a846b2..bdc4fac2 100644 --- a/src/kaleidoscope/device/softhruf/Splitography.h +++ b/src/kaleidoscope/device/softhruf/Splitography.h @@ -44,10 +44,13 @@ struct SplitographyProps : kaleidoscope::device::ATmega32U4KeyboardProps { }; typedef kaleidoscope::driver::mcu::ATmega32U4 MCU; struct KeyScannerProps : public kaleidoscope::driver::keyscanner::ATmegaProps { - ATMEGA_KEYSCANNER_PROPS( - ROW_PIN_LIST({ PIN_D0, PIN_D1, PIN_D2, PIN_D3 }), - COL_PIN_LIST({ PIN_F0, PIN_F1, PIN_F4, PIN_F5, PIN_F6, PIN_F7, PIN_C7, PIN_C6, PIN_B6, PIN_B5, PIN_B4, PIN_D7 }) - ); + static constexpr uint8_t matrix_rows = 4; + static constexpr uint8_t matrix_columns = 12; + typedef MatrixAddr KeyAddr; +#ifndef KALEIDOSCOPE_VIRTUAL_BUILD + 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_F0, PIN_F1, PIN_F4, PIN_F5, PIN_F6, PIN_F7, PIN_C7, PIN_C6, PIN_B6, PIN_B5, PIN_B4, PIN_D7 }; +#endif // KALEIDOSCOPE_VIRTUAL_BUILD }; typedef kaleidoscope::driver::keyscanner::ATmega KeyScanner; typedef kaleidoscope::driver::bootloader::avr::FLIP BootLoader; @@ -55,8 +58,13 @@ struct SplitographyProps : kaleidoscope::device::ATmega32U4KeyboardProps { }; #ifndef KALEIDOSCOPE_VIRTUAL_BUILD -ATMEGA32U4_DEVICE(Splitography); +class Splitography: 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 Splitography; #endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD diff --git a/src/kaleidoscope/device/technomancy/Atreus.cpp b/src/kaleidoscope/device/technomancy/Atreus.cpp index 27d325d2..7a34e66f 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, \ diff --git a/src/kaleidoscope/driver/keyscanner/ATmega.h b/src/kaleidoscope/driver/keyscanner/ATmega.h index 3a5bb5c6..6ffd36fc 100644 --- a/src/kaleidoscope/driver/keyscanner/ATmega.h +++ b/src/kaleidoscope/driver/keyscanner/ATmega.h @@ -29,42 +29,6 @@ #include #endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD -#define ROW_PIN_LIST(...) __VA_ARGS__ -#define COL_PIN_LIST(...) __VA_ARGS__ - -#ifndef KALEIDOSCOPE_VIRTUAL_BUILD -#define ATMEGA_KEYSCANNER_PROPS(ROW_PINS_, COL_PINS_) \ - static constexpr uint8_t matrix_rows = NUM_ARGS(ROW_PINS_); \ - static constexpr uint8_t matrix_columns = NUM_ARGS(COL_PINS_); \ - typedef MatrixAddr KeyAddr; \ - \ - static constexpr uint8_t matrix_row_pins[matrix_rows] = ROW_PINS_; \ - static constexpr uint8_t matrix_col_pins[matrix_columns] = COL_PINS_; -#else // ifndef KALEIDOSCOPE_VIRTUAL_BUILD -#define ATMEGA_KEYSCANNER_PROPS(ROW_PINS_, COL_PINS_) \ - static constexpr uint8_t matrix_rows = NUM_ARGS(ROW_PINS_); \ - static constexpr uint8_t matrix_columns = NUM_ARGS(COL_PINS_); \ - typedef MatrixAddr KeyAddr; -#endif // ifndef KALEIDOSCOPE_VIRTUAL_BUILD - -#define ATMEGA_KEYSCANNER_BOILERPLATE \ - const uint8_t kaleidoscope::Device::KeyScannerProps::matrix_rows; \ - const uint8_t kaleidoscope::Device::KeyScannerProps::matrix_columns; \ - constexpr uint8_t kaleidoscope::Device::KeyScannerProps::matrix_row_pins[matrix_rows]; \ - constexpr uint8_t kaleidoscope::Device::KeyScannerProps::matrix_col_pins[matrix_columns]; \ - template<> \ - uint16_t kaleidoscope::Device::KeyScanner::previousKeyState_[kaleidoscope::Device::KeyScannerProps::matrix_rows] = {}; \ - template<> \ - uint16_t kaleidoscope::Device::KeyScanner::keyState_[kaleidoscope::Device::KeyScannerProps::matrix_rows] = {}; \ - template<> \ - uint16_t kaleidoscope::Device::KeyScanner::masks_[kaleidoscope::Device::KeyScannerProps::matrix_rows] = {}; \ - template<> \ - uint8_t kaleidoscope::Device::KeyScanner::debounce_matrix_[kaleidoscope::Device::KeyScannerProps::matrix_rows][kaleidoscope::Device::KeyScannerProps::matrix_columns] = {}; \ - \ - ISR(TIMER1_OVF_vect) { \ - Runtime.device().keyScanner().do_scan_ = true; \ - } - namespace kaleidoscope { namespace driver { namespace keyscanner {