move keyhive exclusive boards into /keyhive (#16084)

Co-authored-by: Nick Brassel <nick@tzarc.org>
This commit is contained in:
peepeetee 2022-04-19 18:17:21 +08:00 committed by GitHub
parent cff489bfdb
commit 9f63bce70b
Failed to generate hash of commit
148 changed files with 19 additions and 19 deletions

View file

@ -0,0 +1,45 @@
/*
Copyright 2019 @filoxo
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, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "config_common.h"
/* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED
#define PRODUCT_ID 0xACC8
#define DEVICE_VER 0x0001
#define MANUFACTURER Keyhive
#define PRODUCT Honeycomb Macropad
/* key matrix size */
#define MATRIX_ROWS 1
#define MATRIX_COLS 16
#define ONESHOT_TIMEOUT 500
/* disable debug print */
//#define NO_DEBUG
/* disable print */
//#define NO_PRINT
/* disable action features */
//#define NO_ACTION_LAYER
//#define NO_ACTION_TAPPING
//#define NO_ACTION_ONESHOT

View file

@ -0,0 +1,76 @@
#include "honeycomb.h"
#include "pointing_device.h"
#include "report.h"
void pointing_device_task(void){
/*report_mouse_t currentReport = {};
uint32_t timeout = 0;
//the m character requests the RF slave to send the mouse report
uart_write('m');
//trust the external inputs completely, erase old data
uint8_t uart_data[5] = {0};
//there are 10 bytes corresponding to 10 columns, and an end byte
for (uint8_t i = 0; i < 5; i++) {
//wait for the serial data, timeout if it's been too long
//this only happened in testing with a loose wire, but does no
//harm to leave it in here
while(!uart_available()){
timeout++;
if (timeout > 10000){
xprintf("\r\nTIMED OUT");
break;
}
}
xprintf("\r\nGOT DATA for %d",i);
uart_data[i] = uart_read();
}
//check for the end packet, bytes 1-4 are movement and scroll
//but byte 5 has bits 0-3 for the scroll button state
//(1000 if pressed, 0000 if not) and bits 4-7 are always 1
//We can use this to verify the report sent properly.
if (uart_data[4] == 0x0F || uart_data[4] == 0x8F)
{
xprintf("\r\nREQUESTED MOUSE, RECEIVED %i, %i, %i, %i, %i",uart_data[0],uart_data[1],uart_data[2],uart_data[3],uart_data[4]);
currentReport = pointing_device_get_report();
//shifting and transferring the info to the mouse report varaible
//mouseReport.x = 127 max -127 min
currentReport.x = (int8_t) uart_data[0];
//mouseReport.y = 127 max -127 min
currentReport.y = (int8_t) uart_data[1];
//mouseReport.v = 127 max -127 min (scroll vertical)
currentReport.v = (int8_t) uart_data[2];
//mouseReport.h = 127 max -127 min (scroll horizontal)
currentReport.h = (int8_t) uart_data[3];
//mouseReport.buttons = 0x31 max (bitmask for mouse buttons 1-5) 0x00 min
//mouse buttons 1 and 2 are handled by the keymap, but not 3
if (uart_data[4] == 0x0F) { //then 3 is not pressed
currentReport.buttons &= ~MOUSE_BTN3; //MOUSE_BTN3 is def in report.h
} else { //3 must be pressed
currentReport.buttons |= MOUSE_BTN3;
}
pointing_device_set_report(currentReport);
} else {
xprintf("\r\nRequested packet, data 4 was %d",uart_data[4]);
}*/
pointing_device_send();
}
void led_init(void) {
setPinOutput(D1);
writePinHigh(D1);
setPinOutput(F4);
writePinHigh(F4);
setPinOutput(F5);
writePinHigh(F5);
}
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
matrix_init_user();
led_init();
}

View file

@ -0,0 +1,32 @@
#pragma once
#include "quantum.h"
#define RED_LED_OFF() writePinHigh(F6)
#define RED_LED_ON() writePinLow(F6)
#define BLU_LED_OFF() writePinHigh(F5)
#define BLU_LED_ON() writePinLow(F5)
#define GRN_LED_OFF() writePinHigh(D1)
#define GRN_LED_ON() writePinLow(D1)
#define SET_LED_OFF (RED_LED_OFF(); GRN_LED_OFF(); BLU_LED_OFF(); )
#define SET_LED_RED (RED_LED_ON(); GRN_LED_OFF(); BLU_LED_OFF(); )
#define SET_LED_BLUE (RED_LED_OFF(); GRN_LED_OFF(); BLU_LED_ON(); )
#define SET_LED_GREEN (RED_LED_OFF(); GRN_LED_ON(); BLU_LED_OFF(); )
#define SET_LED_YELLOW (RED_LED_ON(); GRN_LED_ON(); BLU_LED_OFF(); )
#define SET_LED_MAGENTA (RED_LED_ON(); GRN_LED_OFF(); BLU_LED_ON(); )
#define SET_LED_CYAN (RED_LED_OFF(); GRN_LED_ON(); BLU_LED_ON(); )
#define SET_LED_WHITE (RED_LED_ON(); GRN_LED_ON(); BLU_LED_ON(); )
// This a shortcut to help you visually see your layout.
// The first section contains all of the arguements
// The second converts the arguments into a two-dimensional array
#define LAYOUT( \
k13, k14, k15, k16, \
k09, k10, k11, k12, \
k05, k06, k07, k08, \
k01, k02, k03, k04 \
) \
{ \
{ k01, k02, k03, k04, k05, k06, k07, k08, k09, k10, k11, k12, k13, k14, k15, k16 } \
}

View file

@ -0,0 +1,30 @@
{
"keyboard_name": "Honeycomb",
"url": "",
"maintainer": "filoxo",
"layouts": {
"LAYOUT": {
"layout": [
{"x":0, "y":0},
{"x":1, "y":0},
{"x":2, "y":0},
{"x":3, "y":0},
{"x":0, "y":1},
{"x":1, "y":1},
{"x":2, "y":1},
{"x":3, "y":1},
{"x":0, "y":2},
{"x":1, "y":2},
{"x":2, "y":2},
{"x":3, "y":2},
{"x":0, "y":3},
{"x":1, "y":3},
{"x":2, "y":3},
{"x":3, "y":3}
]
}
}
}

View file

@ -0,0 +1,91 @@
#include QMK_KEYBOARD_H
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
enum honeycomb_layers {
_BS,
_EN
};
// Macro definitions for readability
enum honeycomb_keycodes {
HW = SAFE_RANGE,
COPY,
PASTA
};
extern int8_t encoderValue;
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BS] = LAYOUT( /* Base layout, put whatever defaults. */
HW, COPY, PASTA, KC_MUTE,
KC_4, KC_5, KC_6, KC_7,
KC_8, KC_9, KC_A, KC_B,
KC_C, KC_D, KC_E, KC_F
),
[_EN] = LAYOUT( /* Alternate layer */
_______, _______, _______, _______,
_______, _______, _______, _______,
_______, _______, _______, _______,
_______, _______, _______, _______
)
};
report_mouse_t currentReport = {};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
//uint8_t layer = biton32(layer_state); // get the current layer
// Basic example functions
switch (keycode) {
case HW:
if (record->event.pressed) {
SEND_STRING("Hello, world!");
} else {
SEND_STRING("Goodbye, cruel world!");
}
break;
case COPY:
if (record->event.pressed) {
tap_code16(LCTL(KC_C)); // Replace with tap_code16(LCMD(KC_C)) to enable for Mac
}
break;
case PASTA:
if (record->event.pressed) {
tap_code16(LCTL(KC_V)); // Replace with tap_code16(LCMD(KC_V)) to enable for Mac
}
break;
return false;
}
return true;
};
void matrix_scan_user(void) {
/* Leaving some LED stuff in here in comment form so you can see how to use it.
if (shiftLED || capsLED){
red_led_on;
} else {
red_led_off;
}
if (numLED){
grn_led_on;
} else {
grn_led_off;
}
if (mouseLED){
blu_led_on;
} else {
blu_led_off;
}*/
while (encoderValue < 0){
tap_code(KC_VOLD);
encoderValue++;
}
while (encoderValue > 0){
tap_code(KC_VOLU);
encoderValue--;
}
};

View file

@ -0,0 +1,190 @@
/*
Copyright 2012 Jun Wako
Copyright 2014 Jack Humbert
Copyright 2019 @filoxo
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, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdbool.h>
#if defined(__AVR__)
#include <avr/io.h>
#endif
#include "wait.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
#include "timer.h"
#include "honeycomb.h"
#include "pointing_device.h"
#include "report.h"
#include "uart.h"
#if (MATRIX_COLS <= 8)
# define print_matrix_header() print("\nr/c 01234567\n")
# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
# define ROW_SHIFTER ((uint8_t)1)
#elif (MATRIX_COLS <= 16)
# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
# define ROW_SHIFTER ((uint16_t)1)
#elif (MATRIX_COLS <= 32)
# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
# define ROW_SHIFTER ((uint32_t)1)
#endif
/* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS];
//extern int8_t encoderValue;
int8_t encoderValue = 0;
__attribute__ ((weak))
void matrix_init_quantum(void) {
matrix_init_kb();
}
__attribute__ ((weak))
void matrix_scan_quantum(void) {
matrix_scan_kb();
}
__attribute__ ((weak))
void matrix_init_kb(void) {
matrix_init_user();
}
__attribute__ ((weak))
void matrix_scan_kb(void) {
matrix_scan_user();
}
__attribute__ ((weak))
void matrix_init_user(void) {
}
__attribute__ ((weak))
void matrix_scan_user(void) {
}
inline
uint8_t matrix_rows(void) {
return MATRIX_ROWS;
}
inline
uint8_t matrix_cols(void) {
return MATRIX_COLS;
}
void matrix_init(void) {
matrix_init_quantum();
uart_init(1000000);
}
uint8_t matrix_scan(void)
{
uint32_t timeout = 0;
// The 's' character requests the RF slave to send the matrix
uart_write('s');
// Trust the external keystates entirely, erase the last data
uint8_t uart_data[4] = {0};
// There are 3 bytes corresponding to the data, and a checksum
for (uint8_t i = 0; i < 4; i++) {
// Wait for the serial data, timeout if it's been too long
// This only happened in testing with a loose wire, but does no
// harm to leave it in here
while(!uart_available()){
timeout++;
if (timeout > 10000){
xprintf("\r\nTime out in keyboard.");
break;
}
}
uart_data[i] = uart_read();
}
// Check for the end packet, it's our checksum.
// Will only be a match if the correct bytes were recieved
if (uart_data[3] == (uart_data[0] ^ uart_data[1] ^ uart_data[2])) { // This is an arbitrary checksum calculated by XORing all the data.
// Transferring the keystates to the QMK matrix variable
/* ASSUMING MSB FIRST */
matrix[0] = ((uint16_t) uart_data[0] << 8) | ((uint16_t) uart_data[1]);
encoderValue += (int8_t) uart_data[2];
if ((uart_data[0] | uart_data[1] | uart_data[2])!=0){
xprintf("\r\n0x%0X%02X%02X",uart_data[0],uart_data[1], uart_data[2]);
}
/* OK, TURNS OUT THAT WAS A BAD ASSUMPTION */
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
// I've unpacked these into the mirror image of what QMK expects them to be, so...
matrix[i] = bitrev16(matrix[i]);
// So I'll reverse it, and this should be fine now.
}
// A mouse report for scrolling would go here, but I don't plan on doing scrolling with the encoder. So.
report_mouse_t currentReport = {};
/*
currentReport = pointing_device_get_report();
//mouseReport.x = 127 max -127 min
currentReport.x = (int8_t) uart_data[6];
//mouseReport.y = 127 max -127 min
currentReport.y = (int8_t) uart_data[7];
//mouseReport.v = 127 max -127 min (scroll vertical)
currentReport.v = (int8_t) uart_data[8];
//mouseReport.h = 127 max -127 min (scroll horizontal)
currentReport.h = (int8_t) uart_data[9];
*/
/*
currentReport.x = 0;
currentReport.y = 0;
currentReport.v = 0;
currentReport.h = 0;*/
pointing_device_set_report(currentReport);
} else {
xprintf("\r\nRequested packet, data 3 was %d",uart_data[3]);
}
matrix_scan_quantum();
return 1;
}
inline
bool matrix_is_on(uint8_t row, uint8_t col)
{
return (matrix[row] & ((matrix_row_t)1<col));
}
inline
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_print(void)
{
print_matrix_header();
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
print_hex8(row); print(": ");
print_matrix_row(row);
print("\n");
}
}

View file

@ -0,0 +1,20 @@
Honeycomb Keyboard Firmware
======================
These configuration files use a completely different 'matrix scan' system than other keyboards, it relies on an external nRF51822 microcontroller maintaining a matrix of keystates received from the macropad - it also receives rotary encoder information from the macropad. The matrix.c file contains the code to poll the external microcontroller for the key matrix, and the keymap.c file contains example code for encoder use. As long as the relevant functions in these files are not changed, all other QMK features are supported.
## Building
Run the following command in your terminal:
```
make keyhive/honeycomb:default
# or use this to automatically flash the controller
make keyhive/honeycomb:default:avrdude
```
Follow the QMK guide for this or ask in Discord.
### Other Keymaps
Because this is a totally custom macropad, it is recommended that you copy the `default/` folder, rename it as desired, and modify the `keymap.c` to your liking.

View file

@ -0,0 +1,23 @@
# MCU name
MCU = atmega32u4
# Bootloader selection
BOOTLOADER = caterina
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite
#MOUSEKEY_ENABLE = yes # Mouse keys
POINTING_DEVICE_ENABLE = yes # Generic Pointer, not as big as mouse keys hopefully.
POINTING_DEVICE_DRIVER = custom
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = yes # Console for debug
COMMAND_ENABLE = yes # Commands for debug and configuration
CUSTOM_MATRIX = yes # Remote matrix from the wireless bridge
NKRO_ENABLE = yes # Enable N-Key Rollover
# BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
# # project specific files
SRC += matrix.c
QUANTUM_LIB_SRC += uart.c