Merge pull request #1149 from keyboardio/gd32/eval-fixups

hardware/gd32/Eval: Update and simplify the evaluation board plugin
pull/1150/head
Jesse Vincent 3 years ago committed by GitHub
commit c978eb8133
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,6 +1,6 @@
/* -*- mode: c++ -*-
* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2021 Keyboard.io, Inc.
* Copyright (C) 2021-2022 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
@ -15,17 +15,21 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef ARDUINO_GD32F303ZE_EVAL
#ifdef ARDUINO_GD32F303CC_GENERIC
#include "kaleidoscope/Runtime.h"
#include "kaleidoscope/driver/keyscanner/Base_Impl.h"
namespace kaleidoscope {
namespace device {
namespace gd32 {
void Eval::rebootBootloader() {
USBCore().disconnect();
NVIC_SystemReset();
}
} // namespace gd32
} // namespace device
} // namespace kaleidoscope
#endif // ifdef ARDUINO_GD32F303ZE_EVAL
#endif // ifdef ARDUINO_GD32F303CC_GENERIC

@ -1,6 +1,6 @@
/* -*- mode: c++ -*-
* Kaleidoscope - Firmware for computer input devices
* Copyright (C) 2021 Keyboard.io, Inc.
* Copyright (C) 2021-2022 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
@ -17,14 +17,15 @@
#pragma once
#ifdef ARDUINO_GD32F303ZE_EVAL
#ifdef ARDUINO_GD32F303CC_GENERIC
#include <Arduino.h>
#include "kaleidoscope/device/Base.h"
#include "kaleidoscope/device/gd32/eval/KeyScanner.h"
#include "kaleidoscope/driver/bootloader/gd32/Base.h"
#include "kaleidoscope/driver/hid/Keyboardio.h"
#include "kaleidoscope/driver/storage/GD32Flash.h"
#include "kaleidoscope/driver/bootloader/gd32/Base.h"
#include "kaleidoscope/driver/mcu/GD32.h"
namespace kaleidoscope {
namespace device {
@ -33,15 +34,26 @@ namespace gd32 {
struct EvalStorageProps : kaleidoscope::driver::storage::GD32FlashProps {};
struct EvalProps : kaleidoscope::device::BaseProps {
typedef kaleidoscope::driver::hid::KeyboardioProps HIDProps;
typedef kaleidoscope::driver::hid::Keyboardio<HIDProps> HID;
typedef kaleidoscope::driver::bootloader::gd32::Base BootLoader;
typedef eval::KeyScannerProps KeyScannerProps;
typedef eval::KeyScanner KeyScanner;
typedef EvalStorageProps StorageProps;
typedef kaleidoscope::driver::storage::GD32Flash<StorageProps> Storage;
typedef kaleidoscope::driver::mcu::GD32Props MCUProps;
typedef kaleidoscope::driver::mcu::GD32<MCUProps> MCU;
static constexpr const char *short_name = "GD32Eval";
};
class Eval : public kaleidoscope::device::Base<EvalProps> {};
class Eval : public kaleidoscope::device::Base<EvalProps> {
public:
auto serialPort() -> decltype(Serial) & {
return Serial;
}
static void rebootBootloader();
};
// clang-format off
#define PER_KEY_DATA(dflt, \
@ -57,4 +69,4 @@ EXPORT_DEVICE(kaleidoscope::device::gd32::Eval)
} // namespace kaleidoscope
#endif
#endif // ifdef ARDUINO_GD32F303CC_GENERIC

@ -1,168 +0,0 @@
/* -*- mode: c++ -*-
* Kaleidoscope - Firmware for computer input devices
* 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_GD32F303ZE_EVAL
#include <Arduino.h>
#include <HardwareTimer.h>
#include "kaleidoscope/Runtime.h"
#include "kaleidoscope/device/gd32/eval/KeyScanner.h"
namespace kaleidoscope {
namespace device {
namespace gd32 {
namespace eval {
static HardwareTimer timer;
KeyScanner::col_state_t KeyScanner::matrix_state_[KeyScannerProps::matrix_columns];
bool KeyScanner::do_scan;
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];
static void scan_irq() {
KeyScanner::do_scan = true;
}
void KeyScanner::setup() {
for (uint8_t i = 0; i < Props_::matrix_columns; i++) {
pinMode(Props_::matrix_row_pins[i], INPUT_PULLUP);
}
for (uint8_t i = 0; i < Props_::matrix_rows; i++) {
pinMode(Props_::matrix_row_pins[i], INPUT);
}
timer.setPeriodTime(5, FORMAT_MS);
timer.attachInterrupt(scan_irq);
timer.start();
}
void KeyScanner::scanMatrix() {
if (do_scan) {
do_scan = false;
readMatrix();
}
actOnMatrixScan();
}
uint16_t KeyScanner::readRows() {
uint16_t hot_pins = 0;
for (uint8_t i = 0; i < Props_::matrix_rows; i++) {
uint8_t rowPin = Props_::matrix_row_pins[i];
pinMode(rowPin, INPUT_PULLUP);
uint8_t v = !!digitalRead(rowPin);
pinMode(rowPin, INPUT);
hot_pins |= v << i;
}
return hot_pins;
}
uint16_t KeyScanner::debounce(uint16_t sample, debounce_t *debouncer) {
uint16_t 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;
}
void KeyScanner::readMatrix() {
uint16_t any_debounced_changes = 0;
for (uint8_t col = 0; col < Props_::matrix_columns; col++) {
uint8_t colPin = Props_::matrix_col_pins[col];
pinMode(colPin, OUTPUT);
digitalWrite(colPin, LOW);
uint16_t hot_pins = readRows();
pinMode(colPin, INPUT);
any_debounced_changes |= debounce(hot_pins, &matrix_state_[col].debouncer);
if (any_debounced_changes) {
for (uint8_t i = 0; i < Props_::matrix_columns; i++) {
matrix_state_[i].current = matrix_state_[i].debouncer.debounced_state;
}
}
}
}
void KeyScanner::actOnMatrixScan() {
for (uint8_t col = 0; col < Props_::matrix_columns; col++) {
for (uint8_t row = 0; row < Props_::matrix_rows; row++) {
uint8_t keyState = (bitRead(matrix_state_[col].previous, row) << 0) | (bitRead(matrix_state_[col].current, row) << 1);
if (keyState) {
ThisType::handleKeyswitchEvent(Key_NoKey, typename Props_::KeyAddr(row, col), keyState);
}
}
matrix_state_[col].previous = matrix_state_[col].current;
}
}
bool KeyScanner::isKeyswitchPressed(KeyAddr key_addr) {
return (bitRead(matrix_state_[key_addr.col()].current, key_addr.row()) != 0);
}
uint8_t KeyScanner::pressedKeyswitchCount() {
uint8_t count = 0;
for (int8_t c = 0; c < Props_::matrix_columns; c++) {
count += __builtin_popcount(matrix_state_[c].current);
}
return count;
}
bool KeyScanner::wasKeyswitchPressed(KeyAddr key_addr) {
return (bitRead(matrix_state_[key_addr.col()].previous, key_addr.row()) != 0);
}
uint8_t KeyScanner::previousPressedKeyswitchCount() {
uint8_t count = 0;
for (int8_t c = 0; c < Props_::matrix_columns; c++) {
count += __builtin_popcount(matrix_state_[c].previous);
}
return count;
}
} // namespace eval
} // namespace gd32
} // namespace device
} // namespace kaleidoscope
#endif

@ -1,89 +0,0 @@
/* -*- mode: c++ -*-
* Kaleidoscope - Firmware for computer input devices
* 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
#ifdef ARDUINO_GD32F303ZE_EVAL
#include "kaleidoscope/device/gd32/eval/KeyScanner.h"
#include <Arduino.h>
namespace kaleidoscope {
namespace device {
namespace gd32 {
namespace eval {
struct KeyScannerProps : public kaleidoscope::driver::keyscanner::BaseProps {
static constexpr uint8_t matrix_rows = 1;
static constexpr uint8_t matrix_columns = 2;
static constexpr uint8_t matrix_row_pins[] = {PA3};
static constexpr uint8_t matrix_col_pins[] = {PE4, PD12};
typedef MatrixAddr<matrix_rows, matrix_columns> KeyAddr;
};
class KeyScanner : public kaleidoscope::driver::keyscanner::Base<KeyScannerProps> {
private:
typedef KeyScanner ThisType;
typedef KeyScannerProps Props_;
public:
static bool do_scan;
static void setup();
static void scanMatrix();
static void readMatrix();
static void actOnMatrixScan();
static bool isKeyswitchPressed(KeyAddr key_addr);
static uint8_t pressedKeyswitchCount();
static bool wasKeyswitchPressed(KeyAddr key_addr);
static uint8_t previousPressedKeyswitchCount();
private:
/*
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 {
uint16_t db0; // counter bit 0
uint16_t db1; // counter bit 1
uint16_t debounced_state; // debounced state
};
struct col_state_t {
uint16_t previous;
uint16_t current;
debounce_t debouncer;
};
static col_state_t matrix_state_[Props_::matrix_columns];
static inline uint16_t debounce(uint16_t sample, debounce_t *debouncer);
static uint16_t readRows();
};
} // namespace eval
} // namespace gd32
} // namespace device
} // namespace kaleidoscope
#endif
Loading…
Cancel
Save