parent
54573a9b8c
commit
6b8355a7ba
@ -0,0 +1,146 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Atreus -- Chrysalis-enabled Sketch for the Keyboardio Atreus
|
||||||
|
* Copyright (C) 2018, 2019 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BUILD_INFORMATION
|
||||||
|
#define BUILD_INFORMATION "locally built on " __DATE__ " at " __TIME__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Kaleidoscope.h"
|
||||||
|
#include "Kaleidoscope-EEPROM-Settings.h"
|
||||||
|
#include "Kaleidoscope-EEPROM-Keymap.h"
|
||||||
|
#include "Kaleidoscope-FocusSerial.h"
|
||||||
|
#include "Kaleidoscope-Macros.h"
|
||||||
|
#include "Kaleidoscope-MouseKeys.h"
|
||||||
|
#include "Kaleidoscope-OneShot.h"
|
||||||
|
#include "Kaleidoscope-Qukeys.h"
|
||||||
|
#include "Kaleidoscope-SpaceCadet.h"
|
||||||
|
#include "Kaleidoscope-Hardware-Keyboardio-SpaceCadet.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define MO(n) ShiftToLayer(n)
|
||||||
|
#define TG(n) LockLayer(n)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MACRO_QWERTY,
|
||||||
|
MACRO_VERSION_INFO
|
||||||
|
};
|
||||||
|
|
||||||
|
#define Key_Exclamation LSHIFT(Key_1)
|
||||||
|
#define Key_At LSHIFT(Key_2)
|
||||||
|
#define Key_Hash LSHIFT(Key_3)
|
||||||
|
#define Key_Dollar LSHIFT(Key_4)
|
||||||
|
#define Key_Percent LSHIFT(Key_5)
|
||||||
|
#define Key_Caret LSHIFT(Key_6)
|
||||||
|
#define Key_And LSHIFT(Key_7)
|
||||||
|
#define Key_Star LSHIFT(Key_8)
|
||||||
|
#define Key_Plus LSHIFT(Key_Equals)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
QWERTY,
|
||||||
|
FUN,
|
||||||
|
UPPER
|
||||||
|
};
|
||||||
|
|
||||||
|
/* *INDENT-OFF* */
|
||||||
|
KEYMAPS(
|
||||||
|
[QWERTY] = KEYMAP_STACKED
|
||||||
|
(
|
||||||
|
Key_Q ,Key_W ,Key_E ,Key_R ,Key_T
|
||||||
|
,Key_A ,Key_S ,Key_D ,Key_F ,Key_G
|
||||||
|
,Key_Z ,Key_X ,Key_C ,Key_V ,Key_B, Key_Backtick
|
||||||
|
,Key_Esc ,Key_Tab ,Key_LeftGui ,Key_LeftShift ,Key_Backspace ,Key_LeftControl
|
||||||
|
|
||||||
|
,Key_Y ,Key_U ,Key_I ,Key_O ,Key_P
|
||||||
|
,Key_H ,Key_J ,Key_K ,Key_L ,Key_Semicolon
|
||||||
|
,Key_Backslash,Key_N ,Key_M ,Key_Comma ,Key_Period ,Key_Slash
|
||||||
|
,Key_LeftAlt ,Key_Space ,MO(FUN) ,Key_Minus ,Key_Quote ,Key_Enter
|
||||||
|
),
|
||||||
|
|
||||||
|
[FUN] = KEYMAP_STACKED
|
||||||
|
(
|
||||||
|
Key_Exclamation ,Key_At ,Key_UpArrow ,Key_Dollar ,Key_Percent
|
||||||
|
,Key_LeftParen ,Key_LeftArrow ,Key_DownArrow ,Key_RightArrow ,Key_RightParen
|
||||||
|
,Key_LeftBracket ,Key_RightBracket ,Key_Hash ,Key_LeftCurlyBracket ,Key_RightCurlyBracket ,Key_Caret
|
||||||
|
,TG(UPPER) ,Key_Insert ,Key_LeftGui ,Key_LeftShift ,Key_Delete ,Key_LeftControl
|
||||||
|
|
||||||
|
,Key_PageUp ,Key_7 ,Key_8 ,Key_9 ,Key_Backspace
|
||||||
|
,Key_PageDown ,Key_4 ,Key_5 ,Key_6 ,___
|
||||||
|
,Key_And ,Key_Star ,Key_1 ,Key_2 ,Key_3 ,Key_Plus
|
||||||
|
,Key_LeftAlt ,Key_Space ,___ ,Key_Period ,Key_0 ,Key_Equals
|
||||||
|
),
|
||||||
|
|
||||||
|
[UPPER] = KEYMAP_STACKED
|
||||||
|
(
|
||||||
|
Key_Insert ,Key_Home ,Key_UpArrow ,Key_End ,Key_PageUp
|
||||||
|
,Key_Delete ,Key_LeftArrow ,Key_DownArrow ,Key_RightArrow ,Key_PageDown
|
||||||
|
,M(MACRO_VERSION_INFO) ,Consumer_VolumeIncrement ,XXX ,XXX ,___ ,___
|
||||||
|
,MoveToLayer(QWERTY) ,Consumer_VolumeDecrement ,___ ,___ ,___ ,___
|
||||||
|
|
||||||
|
,Key_UpArrow ,Key_F7 ,Key_F8 ,Key_F9 ,Key_F10
|
||||||
|
,Key_DownArrow ,Key_F4 ,Key_F5 ,Key_F6 ,Key_F11
|
||||||
|
,___ ,XXX ,Key_F1 ,Key_F2 ,Key_F3 ,Key_F12
|
||||||
|
,___ ,___ ,MoveToLayer(QWERTY) ,Key_PrintScreen ,Key_ScrollLock ,Consumer_PlaySlashPause
|
||||||
|
)
|
||||||
|
)
|
||||||
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
|
KALEIDOSCOPE_INIT_PLUGINS(
|
||||||
|
EEPROMSettings,
|
||||||
|
EEPROMKeymap,
|
||||||
|
Focus,
|
||||||
|
FocusEEPROMCommand,
|
||||||
|
FocusSettingsCommand,
|
||||||
|
Qukeys,
|
||||||
|
SpaceCadet,
|
||||||
|
OneShot,
|
||||||
|
Macros,
|
||||||
|
MouseKeys
|
||||||
|
);
|
||||||
|
|
||||||
|
const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) {
|
||||||
|
if (keyToggledOn(event.state)) {
|
||||||
|
switch (macro_id) {
|
||||||
|
case MACRO_QWERTY:
|
||||||
|
// This macro is currently unused, but is kept around for compatibility
|
||||||
|
// reasons. We used to use it in place of `MoveToLayer(QWERTY)`, but no
|
||||||
|
// longer do. We keep it so that if someone still has the old layout with
|
||||||
|
// the macro in EEPROM, it will keep working after a firmware update.
|
||||||
|
Layer.move(QWERTY);
|
||||||
|
break;
|
||||||
|
case MACRO_VERSION_INFO:
|
||||||
|
Macros.type(PSTR("Keyboardio Atreus - Kaleidoscope "));
|
||||||
|
Macros.type(PSTR(BUILD_INFORMATION));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MACRO_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Kaleidoscope.setup();
|
||||||
|
SpaceCadet.disable();
|
||||||
|
EEPROMKeymap.setup(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Kaleidoscope.loop();
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
name=Kaleidoscope-Hardware-Keyboardio-Spacecadet
|
||||||
|
version=0.0.0
|
||||||
|
sentence=Keyboardio Spacecadet hardware support for Kaleidoscope
|
||||||
|
maintainer=Kaleidoscope's Developers <jesse@keyboard.io>
|
||||||
|
url=https://github.com/keyboardio/Kaleidoscope
|
||||||
|
author=Keyboardio
|
||||||
|
paragraph=
|
@ -0,0 +1,19 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Copyright (C) 2021 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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 the Free Software
|
||||||
|
* Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "kaleidoscope/device/keyboardio/Spaceadet.h"
|
@ -0,0 +1,234 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* kaleidoscope::driver::keyscanner::GD32 -- AVR GD32-based keyscanner component
|
||||||
|
* Copyright (C) 2018-2020 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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 the Free Software
|
||||||
|
* Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "kaleidoscope/macro_helpers.h"
|
||||||
|
#include "kaleidoscope/driver/keyscanner/Base.h"
|
||||||
|
#include "kaleidoscope/driver/keyscanner/None.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace kaleidoscope {
|
||||||
|
namespace driver {
|
||||||
|
namespace keyscanner {
|
||||||
|
|
||||||
|
struct GD32Props: kaleidoscope::driver::keyscanner::BaseProps {
|
||||||
|
static const uint16_t keyscan_interval = 1500;
|
||||||
|
static const uint16_t next_scan_after = 0;
|
||||||
|
typedef uint32_t RowState;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following two lines declare an empty array. Both of these must be
|
||||||
|
* shadowed by the descendant keyscanner description class.
|
||||||
|
*/
|
||||||
|
static constexpr uint8_t matrix_row_pins[] = {};
|
||||||
|
static constexpr uint8_t matrix_col_pins[] = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename _KeyScannerProps>
|
||||||
|
class GD32: public kaleidoscope::driver::keyscanner::Base<_KeyScannerProps> {
|
||||||
|
private:
|
||||||
|
typedef GD32<_KeyScannerProps> ThisType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setup() {
|
||||||
|
static_assert(
|
||||||
|
sizeof(_KeyScannerProps::matrix_row_pins) > 0,
|
||||||
|
"The key scanner description has an empty array of matrix row pins."
|
||||||
|
);
|
||||||
|
static_assert(
|
||||||
|
sizeof(_KeyScannerProps::matrix_col_pins) > 0,
|
||||||
|
"The key scanner description has an empty array of matrix column pins."
|
||||||
|
);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < _KeyScannerProps::matrix_columns; i++) {
|
||||||
|
pinmode(_KeyScannerProps::matrix_col_pins[i], INPUT_PULLUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < _KeyScannerProps::matrix_rows; i++) {
|
||||||
|
pinMode(_KeyScannerProps::matrix_row_pins[i], OUTPUT);
|
||||||
|
digitalWrite(_KeyScannerProps::matrix_row_pins[i], HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
setScanCycleTime(_KeyScannerProps::keyscan_interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* setScanCycleTime takes a value of between 0 and 8192. This corresponds (roughly) to the number of microseconds to wait between scanning the key matrix. Our debouncing algorithm does four checks before deciding that a result is valid. Most normal mechanical switches specify a 5ms debounce period. On an ATMega32U4, 1700 gets you about 5ms of debouncing.
|
||||||
|
|
||||||
|
Because keycanning is triggered by an interrupt but not run in that interrupt, the actual amount of time between scans is prone to a little bit of jitter.
|
||||||
|
|
||||||
|
*/
|
||||||
|
void setScanCycleTime(uint16_t c) {
|
||||||
|
TCCR1B = _BV(WGM13);
|
||||||
|
TCCR1A = 0;
|
||||||
|
|
||||||
|
const uint32_t cycles = (F_CPU / 2000000) * c;
|
||||||
|
|
||||||
|
ICR1 = cycles;
|
||||||
|
TCCR1B = _BV(WGM13) | _BV(CS10);
|
||||||
|
TIMSK1 = _BV(TOIE1);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((optimize(3)))
|
||||||
|
void readMatrix(void) {
|
||||||
|
typename _KeyScannerProps::RowState any_debounced_changes = 0;
|
||||||
|
|
||||||
|
for (uint8_t current_row = 0; current_row < _KeyScannerProps::matrix_rows; current_row++) {
|
||||||
|
digitalWrite(_KeyScannerProps::matrix_row_pins[current_row], LOW);
|
||||||
|
typename _KeyScannerProps::RowState hot_pins = readCols();
|
||||||
|
|
||||||
|
digitalWrite(_KeyScannerProps::matrix_row_pins[current_row], HIGH);
|
||||||
|
|
||||||
|
any_debounced_changes |= debounce(hot_pins, &matrix_state_[current_row].debouncer);
|
||||||
|
|
||||||
|
if (any_debounced_changes) {
|
||||||
|
for (uint8_t current_row = 0; current_row < _KeyScannerProps::matrix_rows; current_row++) {
|
||||||
|
matrix_state_[current_row].current = matrix_state_[current_row].debouncer.debounced_state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void scanMatrix() {
|
||||||
|
|
||||||
|
if (micros() > _KeyScannerProps::next_scan_after || micros < _KeyScannerProps::keyscan_interval) {
|
||||||
|
_KeyScannerProps::next_scan_after = micros() + _KeyScannerProps::keyscan_interval;
|
||||||
|
readMatrix();
|
||||||
|
}
|
||||||
|
actOnMatrixScan();
|
||||||
|
}
|
||||||
|
|
||||||
|
void __attribute__((optimize(3))) actOnMatrixScan() {
|
||||||
|
for (byte row = 0; row < _KeyScannerProps::matrix_rows; row++) {
|
||||||
|
for (byte col = 0; col < _KeyScannerProps::matrix_columns; col++) {
|
||||||
|
uint8_t keyState = (bitRead(matrix_state_[row].previous, col) << 0) | (bitRead(matrix_state_[row].current, col) << 1);
|
||||||
|
if (keyState) {
|
||||||
|
ThisType::handleKeyswitchEvent(Key_NoKey, typename _KeyScannerProps::KeyAddr(row, col), keyState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matrix_state_[row].previous = matrix_state_[row].current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t pressedKeyswitchCount() {
|
||||||
|
uint8_t count = 0;
|
||||||
|
|
||||||
|
for (int8_t r = 0; r < _KeyScannerProps::matrix_rows; r++) {
|
||||||
|
count += __builtin_popcount(matrix_state_[r].current);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
bool isKeyswitchPressed(typename _KeyScannerProps::KeyAddr key_addr) {
|
||||||
|
return (bitRead(matrix_state_[key_addr.row()].current, key_addr.col()) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t previousPressedKeyswitchCount() {
|
||||||
|
uint8_t count = 0;
|
||||||
|
|
||||||
|
for (int8_t r = 0; r < _KeyScannerProps::matrix_rows; r++) {
|
||||||
|
count += __builtin_popcount(matrix_state_[r].previous);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
bool wasKeyswitchPressed(typename _KeyScannerProps::KeyAddr key_addr) {
|
||||||
|
return (bitRead(matrix_state_[key_addr.row()].previous,
|
||||||
|
key_addr.col()) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool do_scan_;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/*
|
||||||
|
each of these variables are storing the state for a row of keys
|
||||||
|
|
||||||
|
so for key 0, the counter is represented by db0[0] and db1[0]
|
||||||
|
and the state in debounced_state[0].
|
||||||
|
*/
|
||||||
|
struct debounce_t {
|
||||||
|
typename _KeyScannerProps::RowState db0; // counter bit 0
|
||||||
|
typename _KeyScannerProps::RowState db1; // counter bit 1
|
||||||
|
typename _KeyScannerProps::RowState debounced_state; // debounced state
|
||||||
|
};
|
||||||
|
|
||||||
|
struct row_state_t {
|
||||||
|
typename _KeyScannerProps::RowState previous;
|
||||||
|
typename _KeyScannerProps::RowState current;
|
||||||
|
debounce_t debouncer;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef _KeyScannerProps KeyScannerProps_;
|
||||||
|
static row_state_t matrix_state_[_KeyScannerProps::matrix_rows];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function has loop unrolling disabled on purpose: we want to give the
|
||||||
|
* hardware enough time to produce stable PIN reads for us. If we unroll the
|
||||||
|
* loop, we will not have that, because even with the NOP, the codepath is too
|
||||||
|
* fast. If we don't have stable reads, then entire rows or columns will behave
|
||||||
|
* erratically.
|
||||||
|
*
|
||||||
|
* For this reason, we ask the compiler to not unroll our loop, which in turn,
|
||||||
|
* gives hardware enough time to produce stable reads, at the cost of a little
|
||||||
|
* bit of speed.
|
||||||
|
*
|
||||||
|
* Do not remove the attribute!
|
||||||
|
*/
|
||||||
|
__attribute__((optimize("no-unroll-loops")))
|
||||||
|
typename _KeyScannerProps::RowState readCols() {
|
||||||
|
typename _KeyScannerProps::RowState hot_pins = 0;
|
||||||
|
for (uint8_t i = 0; i < _KeyScannerProps::matrix_columns; i++) {
|
||||||
|
// TODO - do we need this on gd32?
|
||||||
|
asm("NOP"); // We need to pause a beat before reading or we may read before the pin is hot
|
||||||
|
hot_pins |= (!READ_PIN(_KeyScannerProps::matrix_col_pins[i]) << i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hot_pins;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline typename _KeyScannerProps::RowState debounce(
|
||||||
|
typename _KeyScannerProps::RowState sample, debounce_t *debouncer
|
||||||
|
) {
|
||||||
|
typename _KeyScannerProps::RowState delta, changes;
|
||||||
|
|
||||||
|
// Use xor to detect changes from last stable state:
|
||||||
|
// if a key has changed, it's bit will be 1, otherwise 0
|
||||||
|
delta = sample ^ debouncer->debounced_state;
|
||||||
|
|
||||||
|
// Increment counters and reset any unchanged bits:
|
||||||
|
// increment bit 1 for all changed keys
|
||||||
|
debouncer->db1 = ((debouncer->db1) ^ (debouncer->db0)) & delta;
|
||||||
|
// increment bit 0 for all changed keys
|
||||||
|
debouncer->db0 = ~(debouncer->db0) & delta;
|
||||||
|
|
||||||
|
// Calculate returned change set: if delta is still true
|
||||||
|
// and the counter has wrapped back to 0, the key is changed.
|
||||||
|
|
||||||
|
changes = ~(~delta | (debouncer->db0) | (debouncer->db1));
|
||||||
|
// Update state: in this case use xor to flip any bit that is true in changes.
|
||||||
|
debouncer->debounced_state ^= changes;
|
||||||
|
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Kaleidoscope-Hardware-Spacecadet -- Keyboardio Model 100 hardware support for Kaleidoscope
|
||||||
|
* Copyright (C) 2021 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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 the Free Software
|
||||||
|
* Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ARDUINO_keyboardio_spacecadet
|
||||||
|
|
||||||
|
#include "Arduino.h" // for PROGMEM
|
||||||
|
#include "kaleidoscope/device/keyboardio/Spacecadet.h"
|
||||||
|
#include "kaleidoscope/device/keyboardio/GD32Keyscanner.h"
|
||||||
|
|
||||||
|
#include "kaleidoscope/key_events.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::keyboardio::AtreusProps::KeyScannerProps;
|
||||||
|
using KeyScanner = typename kaleidoscope::device::keyboardio::AtreusProps::KeyScanner;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace kaleidoscope {
|
||||||
|
namespace device {
|
||||||
|
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_columns;
|
||||||
|
constexpr uint8_t KeyScannerProps::matrix_row_pins[matrix_rows];
|
||||||
|
constexpr uint8_t KeyScannerProps::matrix_col_pins[matrix_columns];
|
||||||
|
|
||||||
|
// `KeyScanner` here refers to the alias set up above, just like in the
|
||||||
|
// `KeyScannerProps` case above.
|
||||||
|
template<> KeyScanner::row_state_t KeyScanner::matrix_state_[KeyScannerProps::matrix_rows] = {};
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/********* Hardware plugin *********/
|
||||||
|
|
||||||
|
void Spacecadet::setup() {
|
||||||
|
SpacecadetKeyScanner::setup();
|
||||||
|
kaleidoscope::device::Base<SpacecadetProps>::setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,106 @@
|
|||||||
|
/* -*- mode: c++ -*-
|
||||||
|
* Kaleidoscope-Hardware-Model100 -- Keyboardio Model100 hardware support for Kaleidoscope
|
||||||
|
* Copyright (C) 2017-2021 Keyboard.io, Inc
|
||||||
|
*
|
||||||
|
* 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 the Free Software
|
||||||
|
* Foundation, version 3.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef ARDUINO_keyboardio_spacecadet
|
||||||
|
|
||||||
|
#ifndef EEPROM_EMULATION_SIZE
|
||||||
|
#define EEPROM_EMULATION_SIZE 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "kaleidoscope/driver/keyscanner/Base.h"
|
||||||
|
#include "kaleidoscope/driver/storage/GD32Flash.h"
|
||||||
|
#include "kaleidoscope/driver/keyboardio/Model100Side.h"
|
||||||
|
#include "kaleidoscope/driver/led/Base.h"
|
||||||
|
#include "kaleidoscope/device/Base.h"
|
||||||
|
#include "kaleidoscope/driver/hid/Keyboardio.h"
|
||||||
|
#include "kaleidoscope/driver/bootloader/gd32/Base.h"
|
||||||
|
|
||||||
|
namespace kaleidoscope {
|
||||||
|
namespace device {
|
||||||
|
namespace keyboardio {
|
||||||
|
|
||||||
|
struct Model100StorageProps: public kaleidoscope::driver::storage::GD32FlashProps {
|
||||||
|
static constexpr uint16_t length = EEPROM_EMULATION_SIZE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Model100LEDDriver;
|
||||||
|
|
||||||
|
struct Model100Props : public kaleidoscope::device::BaseProps {
|
||||||
|
typedef kaleidoscope::driver::hid::KeyboardioProps HIDProps;
|
||||||
|
typedef kaleidoscope::driver::hid::Keyboardio<HIDProps> HID;
|
||||||
|
|
||||||
|
struct KeyScannerProps : public kaleidoscope::driver::keyscanner::GD32Props {
|
||||||
|
|
||||||
|
|
||||||
|
static constexpr uint8_t matrix_rows = 6;
|
||||||
|
static constexpr uint8_t matrix_columns = 21;
|
||||||
|
typedef MatrixAddr<matrix_rows, matrix_columns> KeyAddr;
|
||||||
|
static constexpr uint8_t matrix_row_pins[matrix_rows] = {PB15, PB14, PB13, PB12, PB11, PB10};
|
||||||
|
static constexpr uint8_t matrix_col_pins[matrix_columns] = {PB1, PB0,PA7,PA6,PA5,PA4,PA3,PA2,PA1,PA0,PD1,PD0,PC15,PC14,PC13, PA9,PA10, PB8, PB7, PB6,PB5, PB9};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef kaleidoscope::driver::keyscanner::GD32<KeyScannerProps> KeyScanner;
|
||||||
|
|
||||||
|
|
||||||
|
typedef Model100StorageProps StorageProps;
|
||||||
|
typedef kaleidoscope::driver::storage::GD32Flash<StorageProps> Storage;
|
||||||
|
|
||||||
|
typedef kaleidoscope::driver::bootloader::gd32::Base BootLoader;
|
||||||
|
static constexpr const char *short_name = "spacecadet";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Model100 : public kaleidoscope::device::Base<Model100Props> {
|
||||||
|
public:
|
||||||
|
void setup();
|
||||||
|
|
||||||
|
static void enableHardwareTestMode();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace keyboardio
|
||||||
|
} // namespace device
|
||||||
|
|
||||||
|
EXPORT_DEVICE(kaleidoscope::device::keyboardio::Model100)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define PER_KEY_DATA(dflt, \
|
||||||
|
r0c0, r0c2, r0c3, r0c5, r0c7, r0c9, r0c11, r0c13, r0c15, r0c17, r0c18, r0c19, \
|
||||||
|
r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15, r1c16, r1c17, r1c18, r1c19, r1c20, \
|
||||||
|
r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, r2c16, r2c17, r2c18, r2c19, \
|
||||||
|
r3c0, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, r3c17, r3c18, r3c20, \
|
||||||
|
r4c0, r4c1, r4c2, r4c3, r4c5, r4c6, r4c7, r4c8, r4c9, r4c10, r4c11, r4c12, r4c13, r4c14, r4c15, r4c17, r4c18, r4c19, r4c20, \
|
||||||
|
r5c0, r5c1, r5c2, r5c3, r5c9, r5c15, r5c17, r5c18, r5c19, ...) \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
r0c0, xxx, r0c2, r0c3, xxx, r0c5, xxx, r0c7, xxx, r0c9, xxx, r0c11, xxx, r0c13, xxx, r0c15, xxx, r0c17, r0c18, r0c19, xxx, \
|
||||||
|
r1c0, r1c1, r1c2, r1c3, r1c4, r1c5, r1c6, r1c7, r1c8, r1c9, r1c10, r1c11, r1c12, r1c13, r1c14, r1c15, r1c16, r1c17, r1c18, r1c19, r1c20, \
|
||||||
|
r2c0, r2c1, r2c2, r2c3, r2c4, r2c5, r2c6, r2c7, r2c8, r2c9, r2c10, r2c11, r2c12, r2c13, r2c14, r2c15, r2c16, r2c17, r2c18, r2c19, xxx, \
|
||||||
|
r3c0, xxx, r3c2, r3c3, r3c4, r3c5, r3c6, r3c7, r3c8, r3c9, r3c10, r3c11, r3c12, r3c13, r3c14, r3c15, xxx, r3c17, r3c18, xxx, r3c20, \
|
||||||
|
r4c0, r4c1, r4c2, r4c3, xxx, r4c5, r4c6, r4c7, r4c8, r4c9, r4c10, r4c11, r4c12, r4c13, r4c14, r4c15, xxx, r4c17, r4c18, r4c19, r4c20, \
|
||||||
|
r5c0, r5c1, r5c2, r5c3, xxx, xxx, xxx, xxx, xxx, r5c9, xxx, xxx, xxx, xxx, xxx, xxx, r5c15, xxx, r5c17, r5c18, RESTRICT_ARGS_COUNT((r5c19), 99, KEYMAP, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in new issue