diff --git a/keyboards/nullbitsco/tidbit/README.md b/keyboards/nullbitsco/tidbit/README.md
new file mode 100644
index 00000000..79956650
--- /dev/null
+++ b/keyboards/nullbitsco/tidbit/README.md
@@ -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/)
diff --git a/keyboards/nullbitsco/tidbit/config.h b/keyboards/nullbitsco/tidbit/config.h
new file mode 100644
index 00000000..753cc3c6
--- /dev/null
+++ b/keyboards/nullbitsco/tidbit/config.h
@@ -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 .
+ */
+
+#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
diff --git a/keyboards/nullbitsco/tidbit/keymap.c b/keyboards/nullbitsco/tidbit/keymap.c
new file mode 100644
index 00000000..1188acf5
--- /dev/null
+++ b/keyboards/nullbitsco/tidbit/keymap.c
@@ -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 .
+ */
+
+#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<.
+ */
+
+#pragma once
+
+#include "HT16K33_GFX.h"
+#include
+
+#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; ndisp, 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; ndisp, 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);
+}
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/HT16K33.h b/qmk/keyboards/nullbitsco/tidbit/HT16K33.h
new file mode 100644
index 00000000..ba94f620
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/HT16K33.h
@@ -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 .
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include
+
+#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();
+}
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/HT16K33_GFX.h b/qmk/keyboards/nullbitsco/tidbit/HT16K33_GFX.h
new file mode 100644
index 00000000..281c809b
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/HT16K33_GFX.h
@@ -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 .
+ */
+
+#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; isize; 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));
+ }
+}
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/README.md b/qmk/keyboards/nullbitsco/tidbit/README.md
new file mode 100644
index 00000000..007812a5
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/README.md
@@ -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).
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/bitc_led.c b/qmk/keyboards/nullbitsco/tidbit/bitc_led.c
new file mode 100644
index 00000000..018875a2
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/bitc_led.c
@@ -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 .
+ */
+
+#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;
+ }
+}
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/bitc_led.h b/qmk/keyboards/nullbitsco/tidbit/bitc_led.h
new file mode 100644
index 00000000..53ac029a
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/bitc_led.h
@@ -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 .
+ */
+
+#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);
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/config.h b/qmk/keyboards/nullbitsco/tidbit/config.h
new file mode 100644
index 00000000..6f9b5ecf
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/config.h
@@ -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 .
+ */
+
+#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
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/keymaps/14seg/keymap.c b/qmk/keyboards/nullbitsco/tidbit/keymaps/14seg/keymap.c
new file mode 100644
index 00000000..6397bf0d
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/keymaps/14seg/keymap.c
@@ -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 .
+ */
+
+#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;
+}
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/keymaps/19keypad/config.h b/qmk/keyboards/nullbitsco/tidbit/keymaps/19keypad/config.h
new file mode 100644
index 00000000..6f0ef726
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/keymaps/19keypad/config.h
@@ -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 .
+ */
+
+#define ENCODERS_PAD_A { B5, B3 }
+#define ENCODERS_PAD_B { B4, B2 }
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/keymaps/19keypad/keymap.c b/qmk/keyboards/nullbitsco/tidbit/keymaps/19keypad/keymap.c
new file mode 100644
index 00000000..420f9cd3
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/keymaps/19keypad/keymap.c
@@ -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 .
+ */
+
+#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<.
+ */
+
+#define TAPPING_TERM 200
+
+#define ENCODERS_PAD_A { B5, B3 }
+#define ENCODERS_PAD_B { B4, B2 }
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/keymaps/default/keymap.c b/qmk/keyboards/nullbitsco/tidbit/keymaps/default/keymap.c
new file mode 100644
index 00000000..e2b8f581
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/keymaps/default/keymap.c
@@ -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 .
+ */
+
+#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<.
+ */
+
+#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
diff --git a/qmk/keyboards/nullbitsco/tidbit/keymaps/kemonine/keymap.c b/qmk/keyboards/nullbitsco/tidbit/keymaps/kemonine/keymap.c
new file mode 100644
index 00000000..4face859
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/keymaps/kemonine/keymap.c
@@ -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 .
+ */
+
+#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<.
+ */
+
+#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<.
+ */
+
+#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<> 8) & 0xFF;
+ msg[IDX_PRESSED] = pressed;
+ msg[IDX_CHECKSUM] = chksum8(msg, UART_MSG_LEN-1);
+
+ for (int i=0; ievent.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
+}
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/remote_kb.h b/qmk/keyboards/nullbitsco/tidbit/remote_kb.h
new file mode 100644
index 00000000..de427adb
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/remote_kb.h
@@ -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 .
+ */
+
+#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);
+
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/rules.mk b/qmk/keyboards/nullbitsco/tidbit/rules.mk
new file mode 100644
index 00000000..63498a22
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/rules.mk
@@ -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
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/tidbit.c b/qmk/keyboards/nullbitsco/tidbit/tidbit.c
new file mode 100644
index 00000000..56b6ae16
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/tidbit.c
@@ -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 .
+ */
+
+#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);
+}
\ No newline at end of file
diff --git a/qmk/keyboards/nullbitsco/tidbit/tidbit.h b/qmk/keyboards/nullbitsco/tidbit/tidbit.h
new file mode 100644
index 00000000..9fb1e30c
--- /dev/null
+++ b/qmk/keyboards/nullbitsco/tidbit/tidbit.h
@@ -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 .
+ */
+
+#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 } \
+}