summaryrefslogtreecommitdiffstats
path: root/keyboards/scarletbandana
diff options
context:
space:
mode:
authorCole Markham <github@themarkhams.us>2019-02-05 23:56:17 +0100
committerMechMerlin <30334081+mechmerlin@users.noreply.github.com>2019-02-05 23:56:17 +0100
commit0affcc8bc3fbe6ed1f5ef6791a41b459421f0ed8 (patch)
tree3718b15a37f983d61ac19414f16d1f13b89c9ac1 /keyboards/scarletbandana
parent5c7a31eae2518b2630f31cf825ecbb08e358ae76 (diff)
downloadqmk_firmware-0affcc8bc3fbe6ed1f5ef6791a41b459421f0ed8.tar.gz
qmk_firmware-0affcc8bc3fbe6ed1f5ef6791a41b459421f0ed8.tar.xz
Add Scarlet Bandana Version IV mark.2 (#3397)
* Add scarlet bandana * updates for scarlet bandana
Diffstat (limited to 'keyboards/scarletbandana')
-rw-r--r--keyboards/scarletbandana/config.h63
-rw-r--r--keyboards/scarletbandana/keymaps/default/config.h24
-rw-r--r--keyboards/scarletbandana/keymaps/default/keymap.c192
-rw-r--r--keyboards/scarletbandana/keymaps/default/readme.md1
-rw-r--r--keyboards/scarletbandana/matrix.c326
-rw-r--r--keyboards/scarletbandana/readme.md31
-rw-r--r--keyboards/scarletbandana/rules.mk69
-rw-r--r--keyboards/scarletbandana/scarletbandana.c102
-rw-r--r--keyboards/scarletbandana/scarletbandana.h43
9 files changed, 851 insertions, 0 deletions
diff --git a/keyboards/scarletbandana/config.h b/keyboards/scarletbandana/config.h
new file mode 100644
index 000000000..7716813dd
--- /dev/null
+++ b/keyboards/scarletbandana/config.h
@@ -0,0 +1,63 @@
+/*
+Copyright 2017 Cole Markham
+
+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/>.
+*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x6969
+#define DEVICE_VER 0x0001
+#define MANUFACTURER WoodKeys.click
+#define PRODUCT Scarlet Bandana Version IV mark.2
+#define DESCRIPTION What keyboard is that?
+
+/* key matrix size */
+#define MATRIX_ROWS 5
+#define MATRIX_COLS 17
+
+/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
+#define DIODE_DIRECTION ROW2COL
+
+#ifdef RGBLIGHT_ENABLE
+#define RGB_DI_PIN D3
+#define RGBLIGHT_ANIMATIONS
+#define RGBLED_NUM 8 // Number of LEDs
+#endif
+
+#define MATRIX_ROW_PINS { D4, D6, D7, B4, B5 }
+#define MATRIX_COL_PINS { B2, B3, B7, B1, F5, F4, F6, F7, B0, F0, F1, D0, D1, D2, D5, B6, C7 }
+
+#define QMK_SPEAKER C6
+
+#ifdef AUDIO_ENABLE
+#define C6_AUDIO
+#define STARTUP_SONG SONG(PREONIC_SOUND)
+// Disable music mode to keep the firmware size down
+#define NO_MUSIC_MODE
+#endif
+
+#define DEBOUNCING_DELAY 5
+
+/* key combination for command */
+#define IS_COMMAND() ( \
+ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+#endif
diff --git a/keyboards/scarletbandana/keymaps/default/config.h b/keyboards/scarletbandana/keymaps/default/config.h
new file mode 100644
index 000000000..97210115b
--- /dev/null
+++ b/keyboards/scarletbandana/keymaps/default/config.h
@@ -0,0 +1,24 @@
+/* Copyright 2017 Cole Markham, WoodKeys.click
+ *
+ * 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/>.
+ */
+
+#ifndef CONFIG_USER_H
+#define CONFIG_USER_H
+
+#include "../../config.h"
+
+// place overrides here
+
+#endif
diff --git a/keyboards/scarletbandana/keymaps/default/keymap.c b/keyboards/scarletbandana/keymaps/default/keymap.c
new file mode 100644
index 000000000..c67eeab7f
--- /dev/null
+++ b/keyboards/scarletbandana/keymaps/default/keymap.c
@@ -0,0 +1,192 @@
+/* Copyright 2017 Cole Markham
+ *
+ * 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 "../../scarletbandana.h"
+
+#ifdef RGBLIGHT_ENABLE
+//Following line allows macro to read current RGB settings
+extern rgblight_config_t rgblight_config;
+#endif
+
+#define _QWERTY 0
+#define _COLEMAK 1
+#define _DVORAK 2
+#define _LOWER 3
+#define _RAISE 4
+#define _ADJUST 16
+
+enum custom_keycodes {
+ QWERTY = SAFE_RANGE,
+ COLEMAK,
+ DVORAK,
+ LOWER,
+ RAISE,
+ ADJUST,
+};
+
+// define variables for reactive RGB
+bool TOG_STATUS = false;
+int RGB_current_mode;
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [_QWERTY] = KEYMAP(
+ KC_F1, KC_F2, KC_ESC,KC_1,KC_2,KC_3,KC_4,KC_5,KC_6,KC_7,KC_8,KC_9,KC_0,KC_MINS,KC_EQL,KC_BSPC, KC_PGUP,\
+ KC_F3, KC_F4, KC_TAB,KC_Q,KC_W,KC_E,KC_R,KC_T,KC_Y,KC_U,KC_I,KC_O,KC_P,KC_LBRC,KC_RBRC,KC_BSLS, KC_PGDN,\
+ KC_F5, KC_F6, KC_CAPS,KC_A,KC_S,KC_D,KC_F,KC_G,KC_H,KC_J,KC_K,KC_L,KC_SCLN,KC_QUOT,KC_ENT, KC_DEL, KC_HOME,\
+ KC_F7, KC_F8, KC_LSFT,KC_Z,KC_X,KC_C,KC_V,KC_B,KC_N,KC_M,KC_COMM,KC_DOT,KC_SLASH,KC_RSFT,KC_UP,KC_END,\
+ KC_F9, KC_F10, KC_LCTL,KC_LGUI,KC_LALT, RAISE, KC_SPACE, LOWER, KC_RALT,KC_APP,KC_RCTRL,KC_LEFT,KC_DOWN,KC_RIGHT),
+
+ [_RAISE] = KEYMAP(
+ RGB_MOD, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,\
+ _______, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,\
+ _______, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, _______,\
+ _______, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,\
+ _______, _______, _______,_______,_______, _______, _______, _______, _______,_______,_______,_______,_______,_______),
+
+ [_LOWER] = KEYMAP(
+ RGB_MOD, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,\
+ _______, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,\
+ _______, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, _______,\
+ _______, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,\
+ _______, _______, _______,_______,_______, _______, _______, _______, _______,_______,_______,_______,_______,_______),
+
+ [_ADJUST] = KEYMAP(
+ RESET, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,\
+ _______, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______,\
+ _______, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______, _______, _______,\
+ _______, _______, _______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,_______,\
+ _______, _______, _______,_______,_______, _______, _______, _______, _______,_______,_______,_______,_______,_______)
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+
+};
+
+// Setting ADJUST layer RGB back to default
+void update_tri_layer_RGB(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
+ if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
+#ifdef RGBLIGHT_ENABLE
+ rgblight_mode(RGB_current_mode);
+#endif
+ layer_on(layer3);
+ } else {
+ layer_off(layer3);
+ }
+}
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+ // MACRODOWN only works in this function
+ switch(id) {
+ case 0:
+ if (record->event.pressed) {
+ register_code(KC_RSFT);
+ } else {
+ unregister_code(KC_RSFT);
+ }
+ break;
+ }
+ return MACRO_NONE;
+};
+
+#ifdef AUDIO_ENABLE
+
+ float tone_qwerty[][2] = SONG(QWERTY_SOUND);
+#endif
+
+void matrix_init_user(void) {
+
+}
+
+void matrix_scan_user(void) {
+
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case LOWER:
+ if (record->event.pressed) {
+ //not sure how to have keyboard check mode and set it to a variable, so my work around
+ //uses another variable that would be set to true after the first time a reactive key is pressed.
+ if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
+ } else {
+ TOG_STATUS = !TOG_STATUS;
+#ifdef RGBLIGHT_ENABLE
+ rgblight_mode(16);
+#endif
+ }
+ layer_on(_LOWER);
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ } else {
+#ifdef RGBLIGHT_ENABLE
+ rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
+#endif
+ TOG_STATUS = false;
+ layer_off(_LOWER);
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ }
+ return false;
+ break;
+ case RAISE:
+ if (record->event.pressed) {
+ //not sure how to have keyboard check mode and set it to a variable, so my work around
+ //uses another variable that would be set to true after the first time a reactive key is pressed.
+ if (TOG_STATUS) { //TOG_STATUS checks is another reactive key currently pressed, only changes RGB mode if returns false
+ } else {
+ TOG_STATUS = !TOG_STATUS;
+#ifdef RGBLIGHT_ENABLE
+ rgblight_mode(15);
+#endif
+ }
+ layer_on(_RAISE);
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ } else {
+#ifdef RGBLIGHT_ENABLE
+ rgblight_mode(RGB_current_mode); // revert RGB to initial mode prior to RGB mode change
+#endif
+ layer_off(_RAISE);
+ TOG_STATUS = false;
+ update_tri_layer_RGB(_LOWER, _RAISE, _ADJUST);
+ }
+ return false;
+ break;
+ case ADJUST:
+ // FIXME add RGB feedback
+ if (record->event.pressed) {
+ layer_on(_ADJUST);
+ } else {
+ layer_off(_ADJUST);
+ }
+ return false;
+ break;
+ break;
+ //led operations - RGB mode change now updates the RGB_current_mode to allow the right RGB mode to be set after reactive keys are released
+#ifdef RGBLIGHT_ENABLE
+ case RGB_MOD:
+ if (record->event.pressed) {
+ rgblight_mode(RGB_current_mode);
+ rgblight_step();
+ RGB_current_mode = rgblight_config.mode;
+ }
+ return false;
+ break;
+#endif
+ }
+ return true;
+}
+
+void led_set_user(uint8_t usb_led) {
+
+}
diff --git a/keyboards/scarletbandana/keymaps/default/readme.md b/keyboards/scarletbandana/keymaps/default/readme.md
new file mode 100644
index 000000000..c2c281fe3
--- /dev/null
+++ b/keyboards/scarletbandana/keymaps/default/readme.md
@@ -0,0 +1 @@
+# The default keymap for scarletbandana
diff --git a/keyboards/scarletbandana/matrix.c b/keyboards/scarletbandana/matrix.c
new file mode 100644
index 000000000..7b7934c9e
--- /dev/null
+++ b/keyboards/scarletbandana/matrix.c
@@ -0,0 +1,326 @@
+/*
+Copyright 2012 Jun Wako <wakojun@gmail.com>
+Copyright 2017 Cole Markham <cole@ccmcomputing.net>
+
+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/>.
+*/
+
+/*
+ * scan matrix
+ */
+#include <stdint.h>
+#include <stdbool.h>
+#if defined(__AVR__)
+#include <avr/io.h>
+#include "pincontrol.h"
+#endif
+#include "wait.h"
+#include "print.h"
+#include "debug.h"
+#include "util.h"
+#include "matrix.h"
+#include "config.h"
+#include "timer.h"
+//#include "audio.h"
+
+#ifndef DEBOUNCING_DELAY
+# define DEBOUNCING_DELAY 5
+#endif
+
+#if (DEBOUNCING_DELAY > 0)
+ static uint16_t debouncing_time;
+ static bool debouncing = false;
+#endif
+
+#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 matrix_bitpop(i) bitpop(matrix[i])
+# 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 matrix_bitpop(i) bitpop16(matrix[i])
+# 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 matrix_bitpop(i) bitpop32(matrix[i])
+# define ROW_SHIFTER ((uint32_t)1)
+#endif
+
+static matrix_row_t matrix_debouncing[MATRIX_ROWS];
+
+static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
+static const uint8_t col_pins[4] = MATRIX_COL_PINS;
+static const uint8_t xcol_pins[MATRIX_COLS - 16] = MATRIX_XCOL_PINS;
+//
+//float init_song[][2] = SONG(QWERTY_SOUND);
+
+/* matrix state(1:on, 0:off) */
+static matrix_row_t matrix[MATRIX_ROWS];
+static matrix_row_t matrix_debouncing[MATRIX_ROWS];
+static void init_rows(void);
+static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
+static void unselect_cols(void);
+static void init_cols(void);
+static void select_col(uint8_t col);
+//static void demux_enable(bool enabled);
+
+__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)
+{
+ debug_enable = true;
+ debug_matrix = true;
+ debug_mouse = true;
+ dprintf("matrix init");
+ // initialize row and col
+ init_cols();
+ init_rows();
+
+
+// PLAY_NOTE_ARRAY(init_song, false, 0);
+
+
+ // initialize matrix state: all keys off
+ for (uint8_t i=0; i < MATRIX_ROWS; i++) {
+ matrix[i] = 0;
+ matrix_debouncing[i] = 0;
+ }
+
+ matrix_init_quantum();
+
+}
+
+uint8_t _matrix_scan(void)
+{
+ // Set col, read rows
+ for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
+# if (DEBOUNCING_DELAY > 0)
+ bool matrix_changed = read_rows_on_col(matrix_debouncing, current_col);
+ if (matrix_changed) {
+ debouncing = true;
+ debouncing_time = timer_read();
+ }
+# else
+ read_rows_on_col(matrix, current_col);
+# endif
+
+ }
+
+ // Unselect cols
+ unselect_cols();
+
+# if (DEBOUNCING_DELAY > 0)
+ if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) {
+ for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+ matrix[i] = matrix_debouncing[i];
+ }
+ debouncing = false;
+ }
+# endif
+
+ return 1;
+}
+
+uint8_t matrix_scan(void)
+{
+ uint8_t ret = _matrix_scan();
+ matrix_scan_quantum();
+ return ret;
+}
+
+bool matrix_is_modified(void)
+{
+ if (debouncing) return false;
+ return true;
+}
+
+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("\nr/c 0123456789ABCDEF\n");
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ phex(row); print(": ");
+ pbin_reverse16(matrix_get_row(row));
+ print("\n");
+ }
+}
+
+uint8_t matrix_key_count(void)
+{
+ uint8_t count = 0;
+ for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+ count += bitpop16(matrix[i]);
+ }
+ return count;
+}
+
+
+static void init_rows(void)
+{
+ for(uint8_t x = 0; x < MATRIX_ROWS; x++) {
+ uint8_t pin = row_pins[x];
+ pinMode(pin, PinDirectionInput);
+ digitalWrite(pin, PinLevelHigh);
+ }
+}
+
+
+static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
+{
+ bool matrix_changed = false;
+
+ // Select col and wait for col selection to stabilize
+ select_col(current_col);
+ wait_us(30);
+// wait_ms(1000);
+// PLAY_NOTE_ARRAY(init_song, false, 0);
+
+ // For each row...
+ for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++)
+ {
+
+ // Store last value of row prior to reading
+ matrix_row_t last_row_value = current_matrix[row_index];
+
+ // Check row pin state
+ uint8_t pin = row_pins[row_index];
+ if (digitalRead(pin) == 0)
+ {
+ // Pin LO, set col bit
+ current_matrix[row_index] |= (ROW_SHIFTER << current_col);
+ }
+ else
+ {
+ // Pin HI, clear col bit
+ current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
+ }
+
+ // Determine if the matrix changed state
+ if ((last_row_value != current_matrix[row_index]) && !(matrix_changed))
+ {
+ matrix_changed = true;
+ }
+ }
+
+ return matrix_changed;
+}
+
+static void select_col(uint8_t col)
+{
+ for (uint8_t y = 16; y < MATRIX_COLS; y++) {
+ uint8_t pin = xcol_pins[y-16];
+ if (y == col) {
+ digitalWrite(pin, PinLevelLow);
+ } else {
+ digitalWrite(pin, PinLevelHigh);
+ }
+ }
+ if (col >= 16) {
+// demux_enable(false);
+// digitalWrite(MATRIX_EN_PIN, PinLevelHigh);
+ } else {
+ for(uint8_t x = 0; x < 4; x++) {
+ uint8_t pin = col_pins[x];
+ pinMode(pin, PinDirectionOutput);
+ digitalWrite(pin, (col >> x) & 0x1);
+ }
+// demux_enable(true);
+ digitalWrite(MATRIX_EN_PIN, PinLevelLow);
+ }
+}
+
+static void init_cols(void) {
+ for (uint8_t y = 16; y < MATRIX_COLS; y++) {
+ uint8_t pin = xcol_pins[y-16];
+ pinMode(pin, PinDirectionOutput);
+ }
+ for(uint8_t x = 0; x < 4; x++) {
+ uint8_t pin = col_pins[x];
+ pinMode(pin, PinDirectionOutput);
+ }
+ pinMode(MATRIX_EN_PIN, PinDirectionOutput);
+// digitalWrite(MATRIX_EN_PIN, PinLevelHigh);
+ unselect_cols();
+}
+
+static void unselect_cols(void)
+{
+ for (uint8_t y = 16; y < MATRIX_COLS; y++) {
+ uint8_t pin = xcol_pins[y-16];
+ digitalWrite(pin, PinLevelHigh);
+ }
+// demux_enable(false);
+// digitalWrite(MATRIX_EN_PIN, PinLevelHigh);
+}
+
+//static void demux_enable(uint8_t state)
+//{
+// if (enabled){
+// digitalWrite(F7, PinLevelLow);
+// } else {
+// digitalWrite(F7, PinLevelHigh);
+// }
+//}
diff --git a/keyboards/scarletbandana/readme.md b/keyboards/scarletbandana/readme.md
new file mode 100644
index 000000000..6d5d9b553
--- /dev/null
+++ b/keyboards/scarletbandana/readme.md
@@ -0,0 +1,31 @@
+# Meira
+
+![Miera](https://imgur.com/kF4MFlW)
+
+A 4x12 ortholinear low-profile keyboard.
+
+Keyboard Maintainer: [Cole Markham](https://github.com/colemarkham)
+Hardware Supported: Meira/ProMicro, Meira/FeatherBLE
+Hardware Availability: [WoodKeys.click](https://woodkeys.click/meira)
+
+Two controllers are support: the Pro Micro, and the Adafruit Feather BLE 32u4. Support for each is defined as a hardware revision subfolder in QMK. Main differences include processor frequencies and matrix pinouts.
+
+Make example for this keyboard (after setting up your build environment):
+
+ make meira/promicro:default
+
+or
+
+ make meira/featherble:default
+
+See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information on generic QMK configuration and setup.
+
+Both the Pro Micro and the Feather BLE use the Catalina bootloader, which is typically programmed using avrdude.
+
+## Matrix
+
+In order to have enough pins for the matrix and other functions, a custom matrix is implemented using a demultiplexer to scan the columns. Since the demux is active low, the diodes must be oriented with the cathode connected to the demux pin. When looking at the bottom of the board with the controller at the top right, the cathode mark on the diode should be toward the left.
+
+## LED Controller
+
+The in-switch LEDs are driven by an ISSI LED controller (IS31FL3731). The micro controller communicates with this chip using I2C. Individual LED control is possible, but currently only general backlighting support is implemented. This functionality is located in lighting.c, issi.c, and TWILib.c. \ No newline at end of file
diff --git a/keyboards/scarletbandana/rules.mk b/keyboards/scarletbandana/rules.mk
new file mode 100644
index 000000000..b6f61d8a4
--- /dev/null
+++ b/keyboards/scarletbandana/rules.mk
@@ -0,0 +1,69 @@
+# MCU name
+#MCU = at90usb1286
+MCU = atmega32u4
+
+# Processor frequency.
+# This will define a symbol, F_CPU, in all source code files equal to the
+# processor frequency in Hz. You can then use this symbol in your source code to
+# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+# automatically to create a 32-bit value in your source code.
+#
+# This will be an integer division of F_USB below, as it is sourced by
+# F_USB after it has run through any CPU prescalers. Note that this value
+# does not *change* the processor frequency - it should merely be updated to
+# reflect the processor speed set externally so that the code can use accurate
+# software delays.
+F_CPU = 16000000
+
+
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+# This will define a symbol, F_USB, in all source code files equal to the
+# input clock frequency (before any prescaling is performed) in Hz. This value may
+# differ from F_CPU if prescaling is used on the latter, and is required as the
+# raw input clock is fed directly to the PLL sections of the AVR for high speed
+# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+# at the end, this will be done automatically to create a 32-bit value in your
+# source code.
+#
+# If no clock division is performed on the input clock inside the AVR (via the
+# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+
+# Boot Section Size in *bytes*
+# Teensy halfKay 512
+# Teensy++ halfKay 1024
+# Atmel DFU loader 4096
+# LUFA bootloader 4096
+# USBaspLoader 2048
+OPT_DEFS += -DBOOTLOADER_SIZE=4096
+
+
+# Build Options
+# change yes to no to disable
+#
+BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
+EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
+CONSOLE_ENABLE = no # Console for debug(+400)
+COMMAND_ENABLE = no # Commands for debug and configuration
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
+# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+NKRO_ENABLE = no # USB Nkey Rollover
+MIDI_ENABLE = no # MIDI support (+2400 to 4200, depending on config)
+UNICODE_ENABLE = no # Unicode
+BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
+AUDIO_ENABLE = yes # Audio output on port C6
+RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
+FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
+BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality, also set ISSI_ENABLE below for Miera
diff --git a/keyboards/scarletbandana/scarletbandana.c b/keyboards/scarletbandana/scarletbandana.c
new file mode 100644
index 000000000..6926312ec
--- /dev/null
+++ b/keyboards/scarletbandana/scarletbandana.c
@@ -0,0 +1,102 @@
+/* Copyright 2017 Cole Markham, WoodKeys.click
+ *
+ * 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 "scarletbandana.h"
+#include <LUFA/Common/Common.h>
+
+#include "quantum.h"
+
+#ifdef AUDIO_ENABLE
+ float tone_startup[][2] = SONG(STARTUP_SOUND);
+ float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
+#endif
+
+
+void shutdown_user(void) {
+ #ifdef AUDIO_ENABLE
+ PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
+ _delay_ms(150);
+ stop_all_notes();
+ #endif
+}
+
+
+void matrix_init_kb(void)
+{
+ // This is required to access the pins in the F-register
+ JTAG_DISABLE();
+ debug_enable=true;
+ print("sb matrix_init_kb\n");
+#ifdef AUDIO_ENABLE
+ _delay_ms(20); // gets rid of tick
+ PLAY_NOTE_ARRAY(tone_startup, false, 0);
+#endif
+
+
+ // put your keyboard start-up code here
+ // runs once when the firmware starts up
+ matrix_init_user();
+}
+
+void matrix_scan_kb(void)
+{
+ matrix_scan_user();
+}
+
+bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
+ // Test code that turns on the switch led for the key that is pressed
+ // set_backlight_by_keymap(record->event.key.col, record->event.key.row);
+ if (keycode == RESET) {
+ reset_keyboard_kb();
+ } else {
+ }
+ return process_record_user(keycode, record);
+}
+
+void led_set_kb(uint8_t usb_led) {
+ // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
+ led_set_user(usb_led);
+}
+
+//void action_function(keyrecord_t *event, uint8_t id, uint8_t opt)
+//{
+//#ifdef AUDIO_ENABLE
+// int8_t sign = 1;
+//#endif
+// if(id == LFK_ESC_TILDE){
+// // Send ~ on shift-esc
+// void (*method)(uint8_t) = (event->event.pressed) ? &add_key : &del_key;
+// uint8_t shifted = get_mods() & (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT));
+// method(shifted ? KC_GRAVE : KC_ESCAPE);
+// send_keyboard_report();
+// }else if(event->event.pressed){
+// switch(id){
+// case LFK_CLEAR:
+// // Go back to default layer
+// layer_clear();
+// break;
+//#ifdef ISSI_ENABLE
+// case LFK_LED_TEST:
+// led_test();
+// break;
+//#endif
+// }
+// }
+//}
+
+void reset_keyboard_kb(){
+ xprintf("programming!\n");
+ reset_keyboard();
+}
diff --git a/keyboards/scarletbandana/scarletbandana.h b/keyboards/scarletbandana/scarletbandana.h
new file mode 100644
index 000000000..77b6afa7a
--- /dev/null
+++ b/keyboards/scarletbandana/scarletbandana.h
@@ -0,0 +1,43 @@
+/* Copyright 2017 Cole Markham
+ *
+ * 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/>.
+ */
+#ifndef SCARLETBANDANA_H
+#define SCARLETBANDANA_H
+
+#include "quantum.h"
+
+void reset_keyboard_kb(void);
+
+// This a shortcut to help you visually see your layout.
+// The following is an example using the Planck MIT layout
+// The first section contains all of the arguments
+// The second converts the arguments into a two-dimensional array
+#define KEYMAP( \
+ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, k0e, k0f, k0g, \
+ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e, k1f, k1g, \
+ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, k2e, k2f, k2g, \
+ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3e, k3f, k3g, \
+ k40, k41, k42, k43, k44, k45, k47, k49, k4a, k4b, k4c, k4e, k4f, k4g \
+) \
+{ \
+ { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, k0e, k0f, k0g }, \
+ { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, k1e, k1f, k1g }, \
+ { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2c, k2d, k2e, k2f, k2g }, \
+ { k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, KC_NO, k3e, k3f, k3g }, \
+ { k40, k41, k42, k43, k44, k45, KC_NO, k47, KC_NO, k49, k4a, k4b, k4c, KC_NO, k4e, k4f, k4g } \
+}
+
+#endif
+