Initial bring up of better tidbit keymaps and kemonine tidbit keymaps

This commit is contained in:
kemonine 2020-11-12 18:21:15 -05:00
parent 34b1a591f7
commit 89b508925f
31 changed files with 1870 additions and 0 deletions

View file

@ -0,0 +1,5 @@
# nullbits tidbit
The information, keymaps, firmware and keyboard layout for KemoNine's setup on the [nullbits tidbit](https://nullbits.co/tidbit/) number pad (macro board).
Layout files were generated by [www.keyboard-layout-editor.com](http://www.keyboard-layout-editor.com/)

View file

@ -0,0 +1,31 @@
/* Copyright 2020 KemoNine
*
* 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
// place overrides here
#undef RGBLIGHT_ANIMATIONS
#define RGBLIGHT_LAYERS
// Mouse settings
#define MOUSEKEY_DELAY 175
#define MOUSEKEY_WHEEL_DELAY 175
#define MOUSEKEY_INTERVAL 20
#define MOUSEKEY_TIME_TO_MAX 15
#define MOUSEKEY_MAX_SPEED 5
#define MOUSEKEY_WHEEL_INTERVAL 50
#define MOUSEKEY_WHEEL_TIME_TO_MAX 20
#define MOUSEKEY_WHEEL_MAX_SPEED 10

View file

@ -0,0 +1,126 @@
/* Copyright 2020 Jay Greco
*
* 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 QMK_KEYBOARD_H
#include "remote_kb.h"
#include "bitc_led.h"
enum custom_keycodes {
PROG = SAFE_RANGE,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Base layer (numpad)
[0] = LAYOUT(
TO(1), PROG, KC_NO, \
LCTL(LALT(KC_TAB)), LGUI(KC_DOWN), KC_NO, KC_AUDIO_VOL_UP, \
KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, KC_AUDIO_VOL_DOWN, \
KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_MS_BTN3, \
KC_NO, KC_MS_WH_LEFT, KC_MS_WH_RIGHT, KC_ESC \
),
// Function layer (numpad)
[1] = LAYOUT(
TO(0), PROG, KC_KP_SLASH,
KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_ASTERISK,
KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_MINUS,
KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_PLUS,
KC_NO, KC_KP_0, KC_KP_DOT, KC_KP_ENTER
),
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
process_record_remote_kb(keycode, record);
switch(keycode) {
case PROG:
if (record->event.pressed) {
set_bitc_LED(LED_ON);
rgblight_disable_noeeprom();
bootloader_jump(); //jump to bootloader
}
break;
default:
break;
}
return true;
}
void encoder_update_user(uint8_t index, bool clockwise) {
if (clockwise) {
if (layer_state_is(0)) {
tap_code(KC_MS_WH_UP);
}
else if (layer_state_is(1)) {
tap_code(KC_AUDIO_VOL_UP);
}
} else {
if (layer_state_is(0)) {
tap_code(KC_MS_WH_DOWN);
}
else if (layer_state_is(1)) {
tap_code(KC_AUDIO_VOL_DOWN);
}
}
}
void led_set_kb(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_NUM_LOCK))
set_bitc_LED(LED_ON);
else
set_bitc_LED(LED_DIM);
}
// Customized HSV values for layer highlights
#define HSV_KMN_PURPLE 191, 255, 120
#define HSV_KMN_GREEN 85, 255, 120
const rgblight_segment_t PROGMEM led_underglow_purple[] = RGBLIGHT_LAYER_SEGMENTS(
{0, RGBLED_NUM, HSV_KMN_PURPLE}
);
const rgblight_segment_t PROGMEM led_underglow_green[] = RGBLIGHT_LAYER_SEGMENTS(
{0, RGBLED_NUM, HSV_KMN_GREEN}
);
// Array of layers for management
const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(
led_underglow_purple,
led_underglow_green
);
// Layer color init
void keyboard_post_init_user(void) {
rgblight_layers = my_rgb_layers;
layer_clear();
layer_on(0);
rgblight_sethsv_noeeprom(HSV_KMN_PURPLE);
}
layer_state_t layer_state_set_user(layer_state_t state) {
switch (get_highest_layer(state)) {
case 1:
register_code(KC_NLCK);
rgblight_set_layer_state(1, layer_state_cmp(state, 1));
break;
default: // for any other layers, or the default layer
unregister_code(KC_NLCK);
rgblight_set_layer_state(0, layer_state_cmp(state, 0));
break;
}
return state;
}

View file

@ -0,0 +1,46 @@
[
{
"backcolor": "#ba00ff",
"name": "Layer 1 - Mouse",
"author": "KemoNine"
},
[
{
"x": 1,
"a": 7
},
"TG(1)",
"Boot",
""
],
[
"Ctrl + Alt + Tab",
"GUI + Down",
"",
"Vol Up"
],
[
"Left Click",
"Up",
"Right Click",
"Vol Down"
],
[
"Left",
"Down",
"Right",
"Mouse 3"
],
[
{
"a": 5
},
"W Up\nW Dn\n\n\n\n\nEnc",
{
"a": 7
},
"W Left",
"W Right",
"Esc"
]
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,46 @@
[
{
"backcolor": "#00ff5a",
"name": "Layer 2 - Number Pad",
"author": "KemoNine"
},
[
{
"x": 1,
"a": 7
},
"TG(0)",
"Boot",
"/"
],
[
"7",
"8",
"9",
"*"
],
[
"4",
"5",
"6",
"-"
],
[
"1",
"2",
"3",
"+"
],
[
{
"a": 5
},
"V Up\nV Dn\n\n\n\n\nEnc",
{
"a": 7
},
"0",
".",
"Enter"
]
]

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View file

@ -0,0 +1,52 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf

View file

@ -0,0 +1,134 @@
/* Copyright 2020 Jay Greco
*
* 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 "HT16K33_GFX.h"
#include <string.h>
#define DISP_MODE_SCROLL 0
#define DISP_MODE_BOUNCE 1
#define DISP_MODE_PUSH 2
#define BLANK " "
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
typedef struct animation_t {
uint8_t mode : 7;
uint8_t enabled: 1;
int8_t pos : 8;
int8_t dir : 3;
uint16_t speed : 13;
uint16_t delay_timer : 16;
HT16K33 *disp;
char *message;
} animation_t;
animation_t *newAnimation (HT16K33 *disp) {
animation_t *animation = malloc(sizeof(animation_t));
if (animation == NULL)
return NULL;
animation->mode = DISP_MODE_SCROLL;
animation->enabled = false;
animation->pos = 0;
animation->dir = 1;
animation->speed = 300;
animation->delay_timer = timer_read();
animation->disp = disp;
animation->message = "";
return animation;
}
__attribute__((weak)) void animation_done_cbk(animation_t *animation) {
}
void animation_scroll(animation_t *animation) {
uint8_t target = min(animation->disp->size, strlen(animation->message));
for (uint8_t n=0; n<target; n++) {
HT16K33_dispASCII(animation->disp, n, animation->message[animation->pos+n]);
}
if ((animation->enabled) && (strlen(animation->message) > animation->disp->size)) {
if (++animation->pos > strlen(animation->message) - animation->disp->size) {
animation->pos = 0;
animation_done_cbk(animation);
}
}
HT16K33_refresh(animation->disp);
animation->delay_timer = timer_read();
}
void animation_bounce(animation_t *animation) {
uint8_t target = min(animation->disp->size, strlen(animation->message));
for (uint8_t n=0; n<target; n++) {
HT16K33_dispASCII(animation->disp, n, animation->message[animation->pos+n]);
}
if ((animation->enabled) && (strlen(animation->message) > animation->disp->size)) {
animation->pos += animation->dir;
if (animation->pos < 0) {
animation->dir = 1;
animation->pos += animation->dir;
animation_done_cbk(animation);
}
else if (animation->pos > strlen(animation->message) - animation->disp->size) {
animation->dir = -1;
animation->pos += animation->dir;
}
}
HT16K33_refresh(animation->disp);
animation->delay_timer = timer_read();
}
void _refresh(animation_t *animation, bool force) {
if ((timer_elapsed(animation->delay_timer) > animation->speed) || force) {
if (strlen(animation->message) > INT8_MAX) {
// dprintf("Message too long! Max: %d\n", INT8_MAX);
return;
}
switch (animation->mode) {
case DISP_MODE_SCROLL:
animation_scroll(animation);
break;
case DISP_MODE_BOUNCE:
animation_bounce(animation);
break;
default:
break;
}
}
}
void animation_refresh(animation_t *animation) {
_refresh(animation, false);
}
void force_animation_refresh(animation_t *animation) {
animation->pos = 0;
animation->dir = 1;
_refresh(animation, true);
}

View file

@ -0,0 +1,95 @@
/* Copyright 2020 Jay Greco
*
* 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 <quantum.h>
#include <stdint.h>
#include <i2c_master.h>
#include <progmem.h>
#define I2C_TIMEOUT 100
#define OSC_ENABLED 0x01
#define OSC_DISABLED 0x00
#define HT16K33_DISP_ON 0x01
#define HT16K33_DISP_OFF 0x01
#define HT16K33_BLINK_OFF 0x00
#define HT16K33_BLINK_ON 0x01
#define HT16K33_BLINK_2HZ 0x01
#define HT16K33_BLINK_1HZ 0x02
#define HT16K33_BLINK_HALFHZ 0x03
#define HT16K33_CMD_DISP 0x00
#define HT16K33_CMD_ENABLE 0x20
#define HT16K33_CMD_BLINK 0x80
#define HT16K33_CMD_BRIGHTNESS 0xE0
#define HT16K33_BRIGHTNESS_MIN 0x00
#define HT16K33_BRIGHTNESS_MAX 0x0F
void ht16K33_init(uint8_t addr),
ht16K33_setBlinkMode(uint8_t addr, uint8_t mode),
ht16K33_setBrightness(uint8_t addr, uint8_t brightness),
ht16K33_refresh(uint8_t addr, uint16_t *displayBuffer, uint8_t bufLen);
#if defined(__AVR__)
static i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout) {
i2c_status_t status = i2c_start(address | I2C_WRITE, timeout);
for (uint16_t i = 0; i < length && status >= 0; i++) {
status = i2c_write(pgm_read_byte((const char *)data++), timeout);
if (status) break;
}
i2c_stop();
return status;
}
#endif
void ht16K33_init(uint8_t addr) {
i2c_init();
static const uint8_t PROGMEM data[] = {HT16K33_CMD_ENABLE | OSC_ENABLED};
i2c_transmit_P((addr << 1), &data[0], sizeof(data), I2C_TIMEOUT);
ht16K33_setBrightness(addr, HT16K33_BRIGHTNESS_MIN);
ht16K33_setBlinkMode(addr, HT16K33_BLINK_OFF);
}
void ht16K33_setBlinkMode(uint8_t addr, uint8_t mode) {
if ((mode < HT16K33_BLINK_OFF)|(mode > HT16K33_BLINK_HALFHZ)) {
mode = HT16K33_BLINK_OFF;
}
uint8_t data[] = {(HT16K33_CMD_BLINK | mode << 1 | HT16K33_DISP_ON)};
i2c_transmit((addr << 1), &data[0], sizeof(data), I2C_TIMEOUT);
}
void ht16K33_setBrightness(uint8_t addr, uint8_t brightness) {
uint8_t data[] = {(HT16K33_CMD_BRIGHTNESS | brightness)};
i2c_transmit((addr << 1), &data[0], sizeof(data), I2C_TIMEOUT);
}
void ht16K33_refresh(uint8_t addr, uint16_t *displayBuffer, uint8_t bufLen) {
i2c_start((addr << 1), I2C_TIMEOUT);
i2c_write((uint8_t)HT16K33_CMD_DISP, I2C_TIMEOUT);
for (int i = 0; i < bufLen; i++) {
i2c_write((displayBuffer[i] & 0xFF), I2C_TIMEOUT);
i2c_write((displayBuffer[i] >> 8), I2C_TIMEOUT);
}
i2c_stop();
}

View file

@ -0,0 +1,194 @@
/* Copyright 2020 Jay Greco
*
* 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 "HT16K33.h"
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte) \
(byte & 0x80 ? '1' : '0'), \
(byte & 0x40 ? '1' : '0'), \
(byte & 0x20 ? '1' : '0'), \
(byte & 0x10 ? '1' : '0'), \
(byte & 0x08 ? '1' : '0'), \
(byte & 0x04 ? '1' : '0'), \
(byte & 0x02 ? '1' : '0'), \
(byte & 0x01 ? '1' : '0')
static const uint16_t char_ASCII[96] = {
0b0000000000000000, //
0b0000000000000110, // !
0b0000001000100000, // "
0b0001001011001110, // #
0b0001001011101101, // $
0b0000110000100100, // %
0b0010001101011101, // &
0b0000010000000000, // '
0b0010010000000000, // (
0b0000100100000000, // )
0b0011111111000000, // *
0b0001001011000000, // +
0b0000100000000000, // ,
0b0000000011000000, // -
0b0100000000000000, // .
0b0000110000000000, // /
0b0000110000111111, // 0
0b0000000000000110, // 1
0b0000000011011011, // 2
0b0000000010001111, // 3
0b0000000011100110, // 4
0b0010000001101001, // 5
0b0000000011111101, // 6
0b0000000000000111, // 7
0b0000000011111111, // 8
0b0000000011101111, // 9
0b0001001000000000, // :
0b0000101000000000, // ;
0b0010010000000000, // <
0b0000000011001000, // =
0b0000100100000000, // >
0b0001000010000011, // ?
0b0000001010111011, // @
0b0000000011110111, // A
0b0001001010001111, // B
0b0000000000111001, // C
0b0001001000001111, // D
0b0000000011111001, // E
0b0000000001110001, // F
0b0000000010111101, // G
0b0000000011110110, // H
0b0001001000000000, // I
0b0000000000011110, // J
0b0010010001110000, // K
0b0000000000111000, // L
0b0000010100110110, // M
0b0010000100110110, // N
0b0000000000111111, // O
0b0000000011110011, // P
0b0010000000111111, // Q
0b0010000011110011, // R
0b0000000011101101, // S
0b0001001000000001, // T
0b0000000000111110, // U
0b0000110000110000, // V
0b0010100000110110, // W
0b0010110100000000, // X
0b0001010100000000, // Y
0b0000110000001001, // Z
0b0000000000111001, // [
0b0010000100000000, //
0b0000000000001111, // ]
0b0000110000000011, // ^
0b0000000000001000, // _
0b0000000100000000, // `
0b0001000001011000, // a
0b0010000001111000, // b
0b0000000011011000, // c
0b0000100010001110, // d
0b0000100001011000, // e
0b0000000001110001, // f
0b0000010010001110, // g
0b0001000001110000, // h
0b0001000000000000, // i
0b0000000000001110, // j
0b0011011000000000, // k
0b0000000000110000, // l
0b0001000011010100, // m
0b0001000001010000, // n
0b0000000011011100, // o
0b0000000101110000, // p
0b0000010010000110, // q
0b0000000001010000, // r
0b0010000010001000, // s
0b0000000001111000, // t
0b0000000000011100, // u
0b0010000000000100, // v
0b0010100000010100, // w
0b0010100011000000, // x
0b0010000000001100, // y
0b0000100001001000, // z
0b0000100101001001, // {
0b0001001000000000, // |
0b0010010010001001, // }
0b0000010100100000, // ~
0b0011111111111111,
};
typedef struct HT16K33 {
uint8_t addr;
uint16_t *buf;
uint8_t size;
} HT16K33;
HT16K33 *newHT16K33 (uint8_t sz, uint8_t addr);
void HT16K33_init(HT16K33 *disp),
HT16K33_clear(HT16K33 *disp),
HT16K33_dispASCII(HT16K33 *disp, uint8_t n, uint8_t a),
HT16K33_dispRaw(HT16K33 *disp, uint8_t n, uint16_t bmp),
HT16K33_refresh(HT16K33 *disp),
HT16K33_printBuffer(HT16K33 *disp);
HT16K33 *newHT16K33 (uint8_t size, uint8_t addr) {
HT16K33 *disp = malloc (sizeof(HT16K33));
if (disp == NULL)
return NULL;
disp->buf = calloc(size, sizeof(uint16_t));
if (disp->buf == NULL) {
free (disp);
return NULL;
}
disp->addr = addr;
disp->size = size;
HT16K33_init(disp);
return disp;
}
void HT16K33_init(HT16K33 *disp) {
ht16K33_init(disp->addr);
HT16K33_clear(disp);
HT16K33_refresh(disp);
}
void HT16K33_clear(HT16K33 *disp) {
for(uint8_t i = 0; i < disp->size; i++) {
disp->buf[i] = 0;
}
}
void HT16K33_dispASCII(HT16K33 *disp, uint8_t n, uint8_t a) {
disp->buf[n] = char_ASCII[a-32];
}
void HT16K33_dispRaw(HT16K33 *disp, uint8_t n, uint16_t bmp) {
disp->buf[n] = bmp;
}
void HT16K33_refresh(HT16K33 *disp) {
ht16K33_refresh(disp->addr, disp->buf, disp->size);
}
void HT16K33_printBuffer(HT16K33 *disp) {
for (uint8_t i=0; i<disp->size; i++) {
dprintf("%d:", i);
dprintf(" "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n",
BYTE_TO_BINARY(disp->buf[i] >> 8), BYTE_TO_BINARY(disp->buf[i] & 0xFF));
}
}

View file

@ -0,0 +1,15 @@
# TIDBIT
![TIDBIT](https://nullbits.co/static/img/tidbit1.jpg)
A very moddable 19-key numpad kit built by nullbits. [More info at nullbits.co](https://nullbits.co/tidbit/)
* Keyboard Maintainer: [Jay Greco](https://github.com/jaygreco)
* Hardware Supported: NIBBLE Rev1, [Bit-C](https://nullbits.co/bit-c/) Pro Micro with USB-C.
* Hardware Availability: [nullbits.co](https://nullbits.co/)
Make example for this keyboard (after setting up your build environment):
make nullbitsco/tidbit:default
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).

View file

@ -0,0 +1,38 @@
/* Copyright 2020 Jay Greco
*
* 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 "bitc_led.h"
void set_bitc_LED(uint8_t mode) {
switch(mode) {
case LED_ON:
setPinOutput(PIN_LED);
writePin(PIN_LED, GPIO_STATE_HIGH);
break;
case LED_DIM:
setPinInput(PIN_LED);
break;
case LED_OFF:
setPinOutput(PIN_LED);
writePin(PIN_LED, GPIO_STATE_LOW);
break;
default:
break;
}
}

View file

@ -0,0 +1,30 @@
/* Copyright 2020 Jay Greco
*
* 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 "quantum.h"
#define LED_ON 2
#define LED_DIM 1
#define LED_OFF 0
#define GPIO_STATE_LOW 0
#define GPIO_STATE_HIGH 1
#define PIN_LED F0
void set_bitc_LED(uint8_t mode);

View file

@ -0,0 +1,54 @@
/* Copyright 2020 Jay Greco
*
* 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"
/* Used to set slave for remote KB if VUSB detect doesn't work. */
// #define KEYBOARD_SLAVE
/* USB Device descriptor parameter */
#define VENDOR_ID 0x6E61
#define PRODUCT_ID 0x6061
#define DEVICE_VER 0x0001
#define MANUFACTURER nullbits
#define PRODUCT TIDBIT
#define DESCRIPTION QMK keyboard firmware
/* key matrix size */
#define MATRIX_ROWS 5
#define MATRIX_COLS 4
/* key matrix pins */
#define MATRIX_ROW_PINS { B1, E6, D7, C6, D4 }
#define MATRIX_COL_PINS { F4, F5, F6, F7 }
#define UNUSED_PINS
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION ROW2COL
/* Optional SMT LED pins */
#define RGB_DI_PIN B6
#define RGBLED_NUM 8
#define RGBLIGHT_ANIMATIONS
/* Optional encoder pins */
#define ENCODERS_PAD_A { B5, B3 }
#define ENCODERS_PAD_B { B4, B2 }
/* Additional optional encoder pins */
// #define ENCODERS_PAD_A { D1, D0 } //Can only be used if I2C is not used
// #define ENCODERS_PAD_B { D3, D2 } //Can only be used if serial (exp) is not used

View file

@ -0,0 +1,184 @@
/* Copyright 2020 Jay Greco
*
* 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 QMK_KEYBOARD_H
#include "14seg_animation.h"
#include "remote_kb.h"
#include "bitc_led.h"
#define ____ _______
#define _BASE 0
#define _LED 1
#define _ALT 2
#define _NAV 3
#define DISP_ADDR 0x70
HT16K33 *disp;
animation_t *animation;
char message[16];
uint16_t tap_timer = 0;
bool nav_press_active = false;
enum custom_keycodes {
PROG = SAFE_RANGE,
NAV_ENT,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Base layer (numpad)
[_BASE] = LAYOUT(
KC_F1, KC_F2, KC_F3, \
KC_PSLS, KC_7, KC_8, KC_9, \
KC_PAST, KC_4, KC_5, KC_6, \
KC_PMNS, KC_1, KC_2, KC_3, \
KC_PPLS, KC_0, KC_DOT, NAV_ENT \
),
// Navigation layer (nav + media)
[_NAV] = LAYOUT(
_______, _______, _______, \
PROG, KC_MPRV, KC_MPLY, KC_MNXT, \
TO(_LED), KC_VOLD, KC_MUTE, KC_VOLU, \
TO(_ALT), RM_1, RM_2, RM_3, \
TO(_BASE), _______, DEBUG, _______ \
),
// LED settings layer
[_LED] = LAYOUT(
_______, _______, _______, \
RGB_TOG, RGB_VAI, RGB_SAI, RGB_HUI, \
_______, RGB_VAD, RGB_SAD, RGB_HUD, \
_______, _______, RGB_MOD, _______, \
_______, _______, RGB_RMOD, MO(_NAV) \
),
// Altium settings layer
[_ALT] = LAYOUT(
____, ____, ____, \
____, ____, ____, ____, \
____, ____, ____, ____, \
____, ____, ____, ____, \
____, ____, ____, MO(_NAV) \
),
};
void matrix_init_user(void) {
matrix_init_remote_kb();
set_bitc_LED(LED_OFF);
disp = newHT16K33(4, DISP_ADDR);
animation = newAnimation(disp);
animation->message = message;
animation->mode = DISP_MODE_BOUNCE;
animation->enabled = true;
char tmp[] = "TIDBIT";
strcpy(message, tmp);
}
void matrix_scan_user(void) {
matrix_scan_remote_kb();
animation_refresh(animation);
if (nav_press_active) {
if (timer_elapsed(tap_timer) > 120) {
//change layer
layer_on(_NAV);
nav_press_active = false;
}
}
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
process_record_remote_kb(keycode, record);
switch(keycode) {
case PROG:
if (record->event.pressed) {
char tmp[] = "PROG";
strcpy(message, tmp);
force_animation_refresh(animation); //force refresh
rgblight_disable_noeeprom();
bootloader_jump(); //jump to bootloader
}
break;
case NAV_ENT:
if (record->event.pressed) {
nav_press_active = true;
tap_timer = timer_read();
}
else {
if (nav_press_active) {
nav_press_active = false;
SEND_STRING(SS_TAP(X_PENT));
send_msg(KC_PENT, true);
send_msg(KC_PENT, false);
}
else {
nav_press_active = false;
layer_off(_NAV);
}
}
break;
}
return true;
}
layer_state_t layer_state_set_user(layer_state_t state) {
switch (get_highest_layer(state)) {
case _BASE:
{
set_bitc_LED(LED_OFF);
char tmp[] = "TIDBIT";
strcpy(message, tmp);
force_animation_refresh(animation); //force refresh
break;
}
case _NAV:
{
set_bitc_LED(LED_ON);
char tmp[] = "NAV MENU";
strcpy(message, tmp);
force_animation_refresh(animation); //force refresh
break;
}
case _LED:
{
set_bitc_LED(LED_OFF);
char tmp[] = "LED MENU";
strcpy(message, tmp);
force_animation_refresh(animation); //force refresh
break;
}
case _ALT:
{
set_bitc_LED(LED_OFF);
char tmp[] = "ALTERNATE";
strcpy(message, tmp);
force_animation_refresh(animation); //force refresh
break;
}
default: // for any other layers, or the default layer
{
set_bitc_LED(LED_OFF);
char tmp[] = BLANK;
strcpy(message, tmp);
force_animation_refresh(animation); //force refresh
break;
}
}
return state;
}

View file

@ -0,0 +1,18 @@
/* Copyright 2020 Jay Greco
*
* 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/>.
*/
#define ENCODERS_PAD_A { B5, B3 }
#define ENCODERS_PAD_B { B4, B2 }

View file

@ -0,0 +1,100 @@
/* Copyright 2020 Jay Greco
*
* 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 QMK_KEYBOARD_H
#include "remote_kb.h"
#include "bitc_led.h"
#define _BASE 0
#define _FUNC 1
enum custom_keycodes {
PROG = SAFE_RANGE,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Base layer (numpad)
[_BASE] = LAYOUT(
TO(_FUNC), KC_NLCK, KC_KP_SLASH, \
KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_ASTERISK, \
KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_MINUS, \
KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_PLUS, \
KC_NO, KC_KP_0, KC_KP_DOT, KC_KP_ENTER \
),
// Function layer (numpad)
[_FUNC] = LAYOUT(
TO(_BASE), PROG, KC_NO,
KC_NO, KC_NO, RGB_MOD, KC_NO,
KC_NO, KC_NO, RGB_HUI, KC_NO,
KC_NO, KC_NO, RGB_SAI, KC_NO,
KC_NO, KC_NO, RGB_VAI, KC_NO
),
};
void matrix_init_user(void) {
matrix_init_remote_kb();
register_code(KC_NLCK);
}
void matrix_scan_user(void) {
matrix_scan_remote_kb();
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
process_record_remote_kb(keycode, record);
switch(keycode) {
case PROG:
if (record->event.pressed) {
set_bitc_LED(LED_DIM);
rgblight_disable_noeeprom();
bootloader_jump(); //jump to bootloader
}
break;
default:
break;
}
return true;
}
void encoder_update_user(uint8_t index, bool clockwise) {
if (clockwise) {
tap_code(KC_VOLU);
} else {
tap_code(KC_VOLD);
}
}
layer_state_t layer_state_set_user(layer_state_t state) {
switch (get_highest_layer(state)) {
case _FUNC:
unregister_code(KC_NLCK);
break;
default: // for any other layers, or the default layer
register_code(KC_NLCK);
break;
}
return state;
}
void led_set_kb(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_NUM_LOCK))
set_bitc_LED(LED_ON);
else
set_bitc_LED(LED_OFF);
}

View file

@ -0,0 +1,20 @@
/* Copyright 2020 Jay Greco
*
* 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/>.
*/
#define TAPPING_TERM 200
#define ENCODERS_PAD_A { B5, B3 }
#define ENCODERS_PAD_B { B4, B2 }

View file

@ -0,0 +1,110 @@
/* Copyright 2020 Jay Greco
*
* 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 QMK_KEYBOARD_H
#include "action_layer.h"
#include "remote_kb.h"
#include "bitc_led.h"
#define _BASE 0
#define _FUNC 1
enum custom_keycodes {
PROG = SAFE_RANGE,
};
enum td_keycodes {
TD_ENTER_LAYER
};
// Tap Dance definitions
qk_tap_dance_action_t tap_dance_actions[] = {
// Tap once for KP_ENTER, twice for _FUNC layer
[TD_ENTER_LAYER] = ACTION_TAP_DANCE_LAYER_TOGGLE(KC_KP_ENTER, 1),
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Base layer (numpad)
[_BASE] = LAYOUT(
KC_NO, KC_KP_ASTERISK, KC_KP_MINUS, \
KC_KP_7, KC_KP_8, KC_KP_9, KC_NO, \
KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_PLUS, \
KC_KP_1, KC_KP_2, KC_KP_3, KC_NO, \
KC_KP_0, KC_NO, KC_KP_DOT, TD(TD_ENTER_LAYER) \
),
// Function layer (numpad)
[_FUNC] = LAYOUT(
KC_NO, RGB_TOG, KC_NO,
KC_NO, KC_NO, RGB_MOD, KC_NO,
KC_NO, KC_NO, RGB_HUI, KC_NO,
KC_NO, KC_NO, RGB_SAI, KC_NO,
PROG, KC_NO, RGB_VAI, TO(_BASE)
),
};
void matrix_init_user(void) {
matrix_init_remote_kb();
register_code(KC_NLCK);
}
void matrix_scan_user(void) {
matrix_scan_remote_kb();
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
process_record_remote_kb(keycode, record);
switch(keycode) {
case PROG:
if (record->event.pressed) {
set_bitc_LED(LED_DIM);
rgblight_disable_noeeprom();
bootloader_jump(); //jump to bootloader
}
break;
default:
break;
}
return true;
}
void encoder_update_user(uint8_t index, bool clockwise) {
if (clockwise) {
tap_code(KC_VOLU);
} else {
tap_code(KC_VOLD);
}
}
layer_state_t layer_state_set_user(layer_state_t state) {
switch (get_highest_layer(state)) {
case _FUNC:
unregister_code(KC_NLCK);
break;
default: // for any other layers, or the default layer
register_code(KC_NLCK);
break;
}
return state;
}
void led_set_kb(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_NUM_LOCK))
set_bitc_LED(LED_ON);
else
set_bitc_LED(LED_OFF);
}

View file

@ -0,0 +1 @@
TAP_DANCE_ENABLE = yes

View file

@ -0,0 +1,31 @@
/* Copyright 2020 KemoNine
*
* 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
// place overrides here
#undef RGBLIGHT_ANIMATIONS
#define RGBLIGHT_LAYERS
// Mouse settings
#define MOUSEKEY_DELAY 175
#define MOUSEKEY_WHEEL_DELAY 175
#define MOUSEKEY_INTERVAL 20
#define MOUSEKEY_TIME_TO_MAX 15
#define MOUSEKEY_MAX_SPEED 5
#define MOUSEKEY_WHEEL_INTERVAL 50
#define MOUSEKEY_WHEEL_TIME_TO_MAX 20
#define MOUSEKEY_WHEEL_MAX_SPEED 10

View file

@ -0,0 +1,126 @@
/* Copyright 2020 Jay Greco
*
* 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 QMK_KEYBOARD_H
#include "remote_kb.h"
#include "bitc_led.h"
enum custom_keycodes {
PROG = SAFE_RANGE,
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Base layer (numpad)
[0] = LAYOUT(
TO(1), PROG, KC_NO, \
LCTL(LALT(KC_TAB)), LGUI(KC_DOWN), KC_NO, KC_AUDIO_VOL_UP, \
KC_MS_BTN1, KC_MS_UP, KC_MS_BTN2, KC_AUDIO_VOL_DOWN, \
KC_MS_LEFT, KC_MS_DOWN, KC_MS_RIGHT, KC_MS_BTN3, \
KC_NO, KC_MS_WH_LEFT, KC_MS_WH_RIGHT, KC_ESC \
),
// Function layer (numpad)
[1] = LAYOUT(
TO(0), PROG, KC_KP_SLASH,
KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_ASTERISK,
KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_MINUS,
KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_PLUS,
KC_NO, KC_KP_0, KC_KP_DOT, KC_KP_ENTER
),
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
process_record_remote_kb(keycode, record);
switch(keycode) {
case PROG:
if (record->event.pressed) {
set_bitc_LED(LED_ON);
rgblight_disable_noeeprom();
bootloader_jump(); //jump to bootloader
}
break;
default:
break;
}
return true;
}
void encoder_update_user(uint8_t index, bool clockwise) {
if (clockwise) {
if (layer_state_is(0)) {
tap_code(KC_MS_WH_UP);
}
else if (layer_state_is(1)) {
tap_code(KC_AUDIO_VOL_UP);
}
} else {
if (layer_state_is(0)) {
tap_code(KC_MS_WH_DOWN);
}
else if (layer_state_is(1)) {
tap_code(KC_AUDIO_VOL_DOWN);
}
}
}
void led_set_kb(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_NUM_LOCK))
set_bitc_LED(LED_ON);
else
set_bitc_LED(LED_DIM);
}
// Customized HSV values for layer highlights
#define HSV_KMN_PURPLE 191, 255, 120
#define HSV_KMN_GREEN 85, 255, 120
const rgblight_segment_t PROGMEM led_underglow_purple[] = RGBLIGHT_LAYER_SEGMENTS(
{0, RGBLED_NUM, HSV_KMN_PURPLE}
);
const rgblight_segment_t PROGMEM led_underglow_green[] = RGBLIGHT_LAYER_SEGMENTS(
{0, RGBLED_NUM, HSV_KMN_GREEN}
);
// Array of layers for management
const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(
led_underglow_purple,
led_underglow_green
);
// Layer color init
void keyboard_post_init_user(void) {
rgblight_layers = my_rgb_layers;
layer_clear();
layer_on(0);
rgblight_sethsv_noeeprom(HSV_KMN_PURPLE);
}
layer_state_t layer_state_set_user(layer_state_t state) {
switch (get_highest_layer(state)) {
case 1:
register_code(KC_NLCK);
rgblight_set_layer_state(1, layer_state_cmp(state, 1));
break;
default: // for any other layers, or the default layer
unregister_code(KC_NLCK);
rgblight_set_layer_state(0, layer_state_cmp(state, 0));
break;
}
return state;
}

View file

@ -0,0 +1,87 @@
/* Copyright 2020 Jay Greco
*
* 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 QMK_KEYBOARD_H
#include "remote_kb.h"
#include "bitc_led.h"
#define _BASE 0
#define _VIA1 1
#define _VIA2 2
#define _VIA3 3
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT(
KC_F1, KC_F2, KC_F3, \
KC_7, KC_8, KC_9, KC_PSLS, \
KC_4, KC_5, KC_6, KC_PAST, \
KC_1, KC_2, KC_3, KC_PMNS, \
KC_0, KC_DOT, KC_ENT, KC_PPLS \
),
[_VIA1] = LAYOUT(
KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
),
[_VIA2] = LAYOUT(
KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
),
[_VIA3] = LAYOUT(
KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
),
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
process_record_remote_kb(keycode, record);
return true;
}
void matrix_init_user(void) {
matrix_init_remote_kb();
set_bitc_LED(LED_OFF);
}
void matrix_scan_user(void) {
matrix_scan_remote_kb();
}
void encoder_update_user(uint8_t index, bool clockwise) {
if (clockwise) {
tap_code(KC_VOLU);
} else {
tap_code(KC_VOLD);
}
}
void led_set_kb(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_NUM_LOCK))
set_bitc_LED(LED_DIM);
else
set_bitc_LED(LED_OFF);
}

View file

@ -0,0 +1 @@
VIA_ENABLE = yes

View file

@ -0,0 +1,23 @@
{
"name": "TIDBIT",
"vendorId": "0x6E61",
"productId": "0x6061",
"lighting": "qmk_rgblight",
"customFeatures": ["rotary-encoder"],
"matrix": {"rows": 5,"cols": 4},
"layouts": {
"labels": [
"2U + Key",
"2U Enter Key",
"2U 0 Key"
],
"keymap": [
[{"x":1},"0,1","0,2","0,3"],
["1,0","1,1","1,2","1,3\n\n\n0,0",{"h":2},"1,3\n\n\n0,1"],
["2,0","2,1","2,2","2,3\n\n\n0,0"],
["3,0","3,1","3,2","3,3\n\n\n1,0",{"h":2},"3,3\n\n\n1,1"],
["4,0\n\n\n2,0","4,1\n\n\n2,0","4,2","4,3\n\n\n1,0"],
[{"w":2},"4,0\n\n\n2,1"]
]
}
}

View file

@ -0,0 +1,148 @@
/* Copyright 2020 Jay Greco
*
* 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 "remote_kb.h"
//todo: remove master/slave
uint8_t
msg[UART_MSG_LEN],
msg_idx = 0;
bool
is_master = true;
bool vbus_detect(void) {
//returns true if VBUS is present, false otherwise.
USBCON |= (1 << OTGPADE); //enables VBUS pad
_delay_us(10);
return (USBSTA & (1<<VBUS)); //checks state of VBUS
}
uint8_t chksum8(const unsigned char *buf, size_t len) {
unsigned int sum;
for (sum = 0 ; len != 0 ; len--)
sum += *(buf++);
return (uint8_t)sum;
}
void send_msg(uint16_t keycode, bool pressed) {
msg[IDX_PREAMBLE] = UART_PREAMBLE;
msg[IDX_KCLSB] = (keycode & 0xFF);
msg[IDX_KCMSB] = (keycode >> 8) & 0xFF;
msg[IDX_PRESSED] = pressed;
msg[IDX_CHECKSUM] = chksum8(msg, UART_MSG_LEN-1);
for (int i=0; i<UART_MSG_LEN; i++) {
uart_putchar(msg[i]);
}
}
void get_msg(void) {
while (uart_available()) {
msg[msg_idx] = uart_getchar();
dprintf("idx: %u, recv: %u\n", msg_idx, msg[msg_idx]);
if (msg_idx == 0 && (msg[msg_idx] != UART_PREAMBLE)) {
dprintf("Byte sync error!\n");
msg_idx = 0;
} else if (msg_idx == (UART_MSG_LEN-1)) {
process_uart();
msg_idx = 0;
} else {
msg_idx++;
}
}
}
void _print_message_buffer(void) {
for (int i=0; i<UART_MSG_LEN; i++) {
dprintf("msg[%u]: %u\n", i, msg[i]);
}
}
void process_uart(void) {
uint8_t chksum = chksum8(msg, UART_MSG_LEN-1);
if (msg[IDX_PREAMBLE] != UART_PREAMBLE || msg[IDX_CHECKSUM] != chksum) {
dprintf("UART checksum mismatch!\n");
_print_message_buffer();
dprintf("calc checksum: %u\n", chksum);
} else {
uint16_t keycode = (uint16_t)msg[IDX_KCLSB] | ((uint16_t)msg[IDX_KCMSB] << 8);
bool pressed = (bool)msg[IDX_PRESSED];
if (IS_RM_KC(keycode)) {
keyrecord_t record;
record.event.pressed = pressed;
if (pressed) dprintf("Remote macro: press [%u]\n", keycode);
else dprintf("Remote macro: release [%u]\n", keycode);
process_record_user(keycode, &record);
} else {
if (pressed) {
dprintf("Remote: press [%u]\n", keycode);
register_code(keycode);
} else {
dprintf("Remote: release [%u]\n", keycode);
unregister_code(keycode);
}
}
}
}
void matrix_init_remote_kb(void) {
uart_init(SERIAL_UART_BAUD);
is_master = vbus_detect();
}
//todo: unify with send/recv functions
void process_record_remote_kb(uint16_t keycode, keyrecord_t *record) {
#if defined (KEYBOARD_MASTER)
// for future reverse link use
#elif defined(KEYBOARD_SLAVE)
if (IS_HID_KC(keycode) || IS_RM_KC(keycode)) {
dprintf("Remote: send [%u]\n", keycode);
send_msg(keycode, record->event.pressed);
}
#else //auto check with VBUS
if (is_master) {
// for future reverse link use
}
else {
if (IS_HID_KC(keycode) || IS_RM_KC(keycode)) {
dprintf("Remote: send [%u]\n", keycode);
send_msg(keycode, record->event.pressed);
}
}
#endif
}
void matrix_scan_remote_kb(void) {
#if defined(KEYBOARD_MASTER)
get_msg();
#elif defined (KEYBOARD_SLAVE)
// for future reverse link use
#else //auto check with VBUS
if (is_master) {
get_msg();
}
else {
// for future reverse link use
}
#endif
}

View file

@ -0,0 +1,62 @@
/* Copyright 2020 Jay Greco
*
* 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 "quantum.h"
#include "tmk_core/common/uart.h"
#define SERIAL_UART_BAUD 153600 //low error rate for 32u4 @ 16MHz
#define UART_PREAMBLE 0x69
#define UART_MSG_LEN 5
#define UART_NULL 0
#define IDX_PREAMBLE 0
#define IDX_KCLSB 1
#define IDX_KCMSB 2
#define IDX_PRESSED 3
#define IDX_CHECKSUM 4
#define IS_HID_KC(x) ((x > 0) && (x < 0xFF))
#define IS_RM_KC(x) ((x >= RM_BASE) && (x <= 0xFFFF))
#define RM_BASE 0xFFFF-16
enum remote_macros {
RM_1 = RM_BASE,
RM_2, RM_3,
RM_4, RM_5,
RM_6, RM_7,
RM_8, RM_9,
RM_10, RM_11,
RM_12, RM_13,
RM_14, RM_15,
};
uint8_t
chksum8(const unsigned char *buf, size_t len);
void
send_msg(uint16_t keycode, bool pressed),
get_msg(void),
process_uart(void),
matrix_init_remote_kb(void),
process_record_remote_kb(uint16_t keycode, keyrecord_t *record),
matrix_scan_remote_kb(void);
bool
vbus_detect(void);

View file

@ -0,0 +1,29 @@
MCU = atmega32u4
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
BOOTLOADER = atmel-dfu
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
MOUSEKEY_ENABLE = no # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
NKRO_ENABLE = no # USB Nkey Rollover
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow
MIDI_ENABLE = no # MIDI support
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE = no # Audio output on port C6
FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
ENCODER_ENABLE = yes # Use rotary encoder
LTO_ENABLE = yes # Link-time optimization
SRC += i2c_master.c
SRC += bitc_led.c
SRC += remote_kb.c
SRC += tmk_core/common/uart.c

View file

@ -0,0 +1,30 @@
/* Copyright 2020 Jay Greco
*
* 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 QMK_KEYBOARD_H
void matrix_init_kb(void) {
led_init_ports();
matrix_init_user();
}
void matrix_scan_kb(void) {
matrix_scan_user();
}
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
return process_record_user(keycode, record);
}

View file

@ -0,0 +1,34 @@
/* Copyright 2020 Jay Greco
*
* 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 "quantum.h"
#define LAYOUT( \
K01, K02, K03, \
K10, K11, K12, K13, \
K20, K21, K22, K23, \
K30, K31, K32, K33, \
K40, K41, K42, K43 \
) \
{ \
{ KC_NO, K01, K02, K03 }, \
{ K10, K11, K12, K13 }, \
{ K20, K21, K22, K23 }, \
{ K30, K31, K32, K33 }, \
{ K40, K41, K42, K43 } \
}