浏览代码

[Keyboard] Add a new keyboard Chidori. (#7496)

* [Keyboard] Add a new keyboard Chidori.

* Update keyboards/chidori/info.json

* Update keyboards/chidori/keymaps/default/keymap.c

* Update keyboards/chidori/chidori.h

* Update keyboards/chidori/keymaps/extended/keymap.c

* Update keyboards/chidori/keymaps/extended/keymap.c

* Update keyboards/chidori/keymaps/extended/keymap.c

* Update keyboards/chidori/keymaps/extended/keymap.c

* Update keyboards/chidori/keymaps/extended/keymap.c

* Update keyboards/chidori/keymaps/extended/keymap.c

* Update keyboards/chidori/keymaps/extended/keymap.c

* Update keyboards/chidori/readme.md

* Update keyboards/chidori/readme.md

* Update keyboards/chidori/readme.md

* Update keyboards/chidori/readme.md

* Update keyboards/chidori/rules.mk

* Update keyboards/chidori/rules.mk

* Update keyboards/chidori/rules.mk

* Update keyboards/chidori/rules.mk

* Update keyboards/chidori/rules.mk

* Update keyboards/chidori/rules.mk

* Update keyboards/chidori/rules.mk

* Update keyboards/chidori/rules.mk

* Update keyboards/chidori/rules.mk

* Update rules.mk

* Delete unnecesarry lines.

* Changes layer keys handing.
ENDO Katsuhiro 5 年之前
父节点
当前提交
aed18a5ff3

+ 366 - 0
keyboards/chidori/board.c

@@ -0,0 +1,366 @@
+/* Copyright 2019 ENDO Katsuhiro <ka2hiro@kagizaraya.jp>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdint.h>
+#include <stdbool.h>
+#include "wait.h"
+#include "print.h"
+#include "debug.h"
+#include "matrix.h"
+#include "quantum.h"
+#include "board.h"
+#include "i2c_master.h"
+
+static board_info_t  boards[NUM_BOARDS] = BOARD_INFOS;
+static board_info_t* master_board       = NULL;
+
+static bool          board_is_master(board_info_t* board);
+static bool          board_is_initialized(board_info_t* board);
+static board_info_t* get_board_by_index(uint8_t board_index);
+static uint8_t       board_merge_led_config(board_info_t* board, uint8_t iodir);
+static uint8_t       board_merge_led_status(board_info_t* board, uint8_t data);
+static void          board_master_init(void);
+static void          board_slave_init(void);
+
+//
+// board interface
+//
+static void board_select_master_row(board_info_t* board, uint8_t row);
+static void board_unselect_master_row(board_info_t* board, uint8_t row);
+static void board_unselect_master_rows(board_info_t* board);
+static bool board_read_cols_on_master_row(board_info_t* board, matrix_row_t current_matrix[], uint8_t row);
+static void board_set_master_led(board_info_t* board, uint8_t led_index, bool status);
+static void board_select_slave_row(board_info_t* board, uint8_t row);
+static void board_unselect_slave_row(board_info_t* board, uint8_t row);
+static void board_unselect_slave_rows(board_info_t* board);
+static bool board_read_cols_on_slave_row(board_info_t* board, matrix_row_t current_matrix[], uint8_t row);
+static void board_set_slave_led(board_info_t* board, uint8_t led_index, bool status);
+
+static board_interface_t master_interface = {board_select_master_row, board_unselect_master_row, board_unselect_master_rows, board_read_cols_on_master_row, board_set_master_led};
+static board_interface_t slave_interface  = {board_select_slave_row, board_unselect_slave_row, board_unselect_slave_rows, board_read_cols_on_slave_row, board_set_slave_led};
+
+static board_interface_t* get_interface(board_info_t* board) {
+    if (board_is_master(board)) {
+        return &master_interface;
+    }
+    return &slave_interface;
+}
+
+static void board_set_master_led(board_info_t* board, uint8_t led_index, bool status) {
+    pin_t pin                    = board->led_pins[led_index];
+    board->led_status[led_index] = status;
+    setPinOutput(pin);
+    status ? writePinHigh(pin) : writePinLow(pin);
+}
+
+static void board_set_slave_led(board_info_t* board, uint8_t led_index, bool status) {
+    board->led_status[led_index] = status;
+    uint8_t iodir                = board_merge_led_config(board, 0xff);
+    uint8_t data                 = board_merge_led_status(board, 0x00);
+    i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_IODIRB, (const uint8_t*)&iodir, sizeof(iodir), BOARD_I2C_TIMEOUT);
+    i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_OLATB, (const uint8_t*)&data, sizeof(data), BOARD_I2C_TIMEOUT);
+}
+
+static uint8_t board_merge_led_config(board_info_t* board, uint8_t iodir) {
+    for (uint8_t i = 0; i < NUM_LEDS; i++) {
+        iodir &= PIN2MASK(board->led_pins[i]);
+    }
+    return iodir;
+}
+
+static bool board_slave_config(board_info_t* board) {
+    uint8_t      set   = 0xff;
+    uint8_t      clear = 0x00;
+    i2c_status_t res   = 0;
+
+    // Set to input
+    res = i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_IODIRA, (const uint8_t*)&set, sizeof(set), BOARD_I2C_TIMEOUT);
+    if (res < 0) return false;
+    // RESTRICTION: LEDs only on PORT B.
+    set = board_merge_led_config(board, set);
+    res = i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_IODIRB, (const uint8_t*)&set, sizeof(set), BOARD_I2C_TIMEOUT);
+    if (res < 0) return false;
+    set = 0xff;
+
+    // Pull up for input - enable
+    res = i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_GPPUA, (const uint8_t*)&set, sizeof(set), BOARD_I2C_TIMEOUT);
+    if (res < 0) return false;
+    res = i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_GPPUB, (const uint8_t*)&set, sizeof(set), BOARD_I2C_TIMEOUT);
+    if (res < 0) return false;
+
+    // Disable interrupt
+    res = i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_GPINTENA, (const uint8_t*)&clear, sizeof(clear), BOARD_I2C_TIMEOUT);
+    if (res < 0) return false;
+    res = i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_GPINTENB, (const uint8_t*)&clear, sizeof(clear), BOARD_I2C_TIMEOUT);
+    if (res < 0) return false;
+
+    // Polarity - same logic
+    res = i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_IPOLA, (const uint8_t*)&clear, sizeof(clear), BOARD_I2C_TIMEOUT);
+    if (res < 0) return false;
+    res = i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_IPOLB, (const uint8_t*)&clear, sizeof(clear), BOARD_I2C_TIMEOUT);
+    if (res < 0) return false;
+
+    return true;
+}
+
+static void board_slave_init(void) {
+    i2c_init();
+    _delay_ms(500);
+
+    for (uint8_t i = 0; i < NUM_BOARDS; i++) {
+        board_info_t* board = &boards[i];
+        if (board_is_master(board)) {
+            continue;
+        }
+        if (i2c_start(EXPANDER_ADDR(board->i2c_address), BOARD_I2C_TIMEOUT) != I2C_STATUS_SUCCESS) {
+            continue;
+        }
+        i2c_stop();
+        if (board_slave_config(board)) {
+            board->initialized = true;
+        }
+    }
+}
+
+inline bool board_is_master(board_info_t* board) {
+    if (board) {
+        return board->master;
+    }
+    return false;
+}
+
+inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
+
+inline uint8_t matrix2board(uint8_t row) { return row % NUM_ROWS; }
+
+inline uint8_t board_index(uint8_t row) { return row / NUM_ROWS; }
+
+static board_info_t* get_master_board(void) {
+    if (master_board == NULL) {
+        for (uint8_t i = 0; i < NUM_BOARDS; i++) {
+            if (boards[i].master) {
+                master_board = &boards[i];
+                return master_board;
+            }
+        }
+    }
+    return NULL;
+}
+
+inline bool board_is_initialized(board_info_t* board) { return board == NULL ? false : board->initialized; }
+
+static board_info_t* get_board_by_index(uint8_t board_index) {
+    if (board_index >= 0 && board_index < NUM_BOARDS) {
+        if (!board_is_initialized(&boards[board_index])) {
+            return NULL;
+        }
+        return &boards[board_index];
+    }
+    return NULL;
+}
+
+static board_info_t* get_board(uint8_t row) {
+    uint8_t idx = board_index(row);
+    if (idx >= 0 && idx < NUM_BOARDS) {
+        if (!board_is_initialized(&boards[idx])) {
+            return NULL;
+        }
+        return &boards[idx];
+    }
+    return NULL;
+}
+
+static uint8_t board_merge_led_status(board_info_t* board, uint8_t data) {
+    if (!board_is_initialized(board)) {
+        return data;
+    }
+    for (uint8_t i = 0; i < NUM_LEDS; i++) {
+        bool status = board->led_status[i];
+        if (status) {
+            data |= (uint8_t)1 << PIN2INDEX(board->led_pins[i]);
+        } else {
+            data &= PIN2MASK(board->led_pins[i]);
+        }
+    }
+    return data;
+}
+
+//
+// Functions for slave
+//
+static uint8_t board_read_slave_cols(board_info_t* board) {
+    if (!board_is_initialized(board)) {
+        return 0xff;
+    }
+    uint8_t      data = 0xff;
+    i2c_status_t res  = i2c_readReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_GPIOA, &data, sizeof(data), BOARD_I2C_TIMEOUT);
+    return (res < 0) ? 0xff : data;
+}
+
+static void board_select_slave_row(board_info_t* board, uint8_t board_row) {
+    if (!board_is_initialized(board)) {
+        return;
+    }
+    uint8_t pin    = board->row_pins[board_row];
+    uint8_t iodir  = board_merge_led_config(board, PIN2MASK(pin));
+    uint8_t status = board_merge_led_status(board, PIN2MASK(pin));
+    i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_IODIRB, (const uint8_t*)&iodir, sizeof(iodir), BOARD_I2C_TIMEOUT);
+    i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_OLATB, (const uint8_t*)&status, sizeof(status), BOARD_I2C_TIMEOUT);
+}
+
+static void board_unselect_slave_rows(board_info_t* board) {
+    if (!board_is_initialized(board)) {
+        return;
+    }
+    uint8_t iodir = board_merge_led_config(board, 0xff);
+    uint8_t data  = board_merge_led_status(board, 0x00);
+    i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_IODIRB, (const uint8_t*)&iodir, sizeof(iodir), BOARD_I2C_TIMEOUT);
+    i2c_writeReg(EXPANDER_ADDR(board->i2c_address), EXPANDER_OLATB, (const uint8_t*)&data, sizeof(data), BOARD_I2C_TIMEOUT);
+}
+
+static void board_unselect_slave_row(board_info_t* board, uint8_t board_row) { board_unselect_slave_rows(board); }
+
+/*
+ * row : matrix row (not board row)
+ */
+static bool board_read_cols_on_slave_row(board_info_t* board, matrix_row_t current_matrix[], uint8_t row) {
+    matrix_row_t last_row_value = current_matrix[row];
+    current_matrix[row]         = 0;
+
+    uint8_t board_row = matrix2board(row);
+    board_select_slave_row(board, board_row);
+    wait_us(30);
+
+    uint8_t cols = board_read_slave_cols(board);
+    for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
+        uint8_t pin       = board->col_pins[col_index];
+        uint8_t pin_state = cols & PIN2BIT(pin);
+        current_matrix[row] |= pin_state ? 0 : (1 << col_index);
+    }
+    board_unselect_slave_row(board, board_row);
+
+    return (last_row_value != current_matrix[row]);
+}
+
+//
+// Functions for master board
+//
+static void board_select_master_row(board_info_t* board, uint8_t board_row) {
+    setPinOutput(board->row_pins[board_row]);
+    writePinLow(board->row_pins[board_row]);
+}
+
+static void board_unselect_master_row(board_info_t* board, uint8_t board_row) { setPinInputHigh(board->row_pins[board_row]); }
+
+static void board_unselect_master_rows(board_info_t* board) {
+    if (!board) {
+        return;
+    }
+    for (uint8_t x = 0; x < NUM_ROWS; x++) {
+        setPinInput(board->row_pins[x]);
+    }
+}
+
+/*
+ * row : matrix row (not board row)
+ */
+static bool board_read_cols_on_master_row(board_info_t* board, matrix_row_t current_matrix[], uint8_t row) {
+    matrix_row_t last_row_value = current_matrix[row];
+    current_matrix[row]         = 0;
+
+    uint8_t board_row = matrix2board(row);
+    board_select_master_row(board, board_row);
+    wait_us(30);
+
+    for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++) {
+        uint8_t pin_state = readPin(board->col_pins[col_index]);
+        current_matrix[row] |= pin_state ? 0 : (1 << col_index);
+    }
+    board_unselect_master_row(board, board_row);
+
+    return (last_row_value != current_matrix[row]);
+}
+
+static void board_master_init(void) {
+    board_info_t* board = get_master_board();
+    if (!board) {
+        return;
+    }
+    for (uint8_t x = 0; x < NUM_COLS; x++) {
+        setPinInputHigh(board->col_pins[x]);
+    }
+    board->initialized = true;
+}
+
+static void board_setup(void) {
+    for (uint8_t i = 0; i < NUM_BOARDS; i++) {
+        board_info_t* board = &boards[i];
+        board->interface    = get_interface(board);
+    }
+}
+
+//
+// Public functions
+//
+
+// NOTE: Do not call this while matrix scanning...
+void board_set_led_by_index(uint8_t board_index, uint8_t led_index, bool status) {
+    board_info_t* board = get_board_by_index(board_index);
+    if (!board) return;
+    if (led_index < 0 || led_index > NUM_LEDS) return;
+    (*board->interface->set_led)(board, led_index, status);
+}
+
+bool board_read_cols_on_row(matrix_row_t current_matrix[], uint8_t row) {
+    bool          result = false;
+    board_info_t* board  = get_board(row);
+    if (!board) {
+        return false;
+    }
+    result = (*board->interface->read_cols_on_row)(board, current_matrix, row);
+    return result;
+}
+
+void board_select_row(uint8_t row) {
+    board_info_t* board = get_board(row);
+    if (!board) {
+        return;
+    }
+    uint8_t board_row = matrix2board(row);
+    (*board->interface->select_row)(board, board_row);
+}
+
+void board_unselect_row(uint8_t row) {
+    board_info_t* board = get_board(row);
+    if (!board) {
+        return;
+    }
+    uint8_t board_row = matrix2board(row);
+    (*board->interface->unselect_row)(board, board_row);
+}
+
+void board_unselect_rows(void) {
+    for (uint8_t i = 0; i < NUM_BOARDS; i++) {
+        board_info_t* board = &boards[i];
+        (*board->interface->unselect_rows)(board);
+    }
+}
+
+void board_init(void) {
+    board_setup();
+    board_master_init();
+    board_slave_init();
+    board_unselect_rows();
+}

+ 190 - 0
keyboards/chidori/board.h

@@ -0,0 +1,190 @@
+/* Copyright 2019 ENDO Katsuhiro <ka2hiro@kagizaraya.jp>
+ *
+ * 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
+
+#define NUM_ROWS 4
+#define NUM_COLS 6
+#define NUM_LEDS 2
+
+#define LED_GREEN 0
+#define LED_YELLOW 1
+
+typedef struct board_info_t      board_info_t;
+typedef struct board_interface_t board_interface_t;
+
+struct board_info_t {
+    bool               master;
+    bool               initialized;
+    uint8_t            i2c_address;
+    pin_t              row_pins[NUM_ROWS];
+    pin_t              col_pins[NUM_COLS];
+    pin_t              led_pins[NUM_LEDS];
+    bool               led_status[NUM_LEDS];
+    board_interface_t* interface;
+};
+
+struct board_interface_t {
+    void (*select_row)(board_info_t* board, uint8_t row);
+    void (*unselect_row)(board_info_t* board, uint8_t row);
+    void (*unselect_rows)(board_info_t* board);
+    bool (*read_cols_on_row)(board_info_t* board, matrix_row_t current_matrix[], uint8_t row);
+    void (*set_led)(board_info_t* board, uint8_t led_index, bool status);
+};
+
+#define BOARD_I2C_TIMEOUT 20
+
+#define GPA0 0x00
+#define GPA1 0x01
+#define GPA2 0x02
+#define GPA3 0x03
+#define GPA4 0x04
+#define GPA5 0x05
+#define GPA6 0x06
+#define GPA7 0x07
+#define GPB0 0x08
+#define GPB1 0x09
+#define GPB2 0x0A
+#define GPB3 0x0B
+#define GPB4 0x0C
+#define GPB5 0x0D
+#define GPB6 0x0E
+#define GPB7 0x0F
+
+//#define PORTA   0x00
+//#define PORTB   0x01
+#define PORT_MASK 0x08
+#define PIN_MASK 0x07
+
+#define PIN2REGISTER(reg, pin) (reg & ((pin & PORT_MASK) >> 3))
+#define PIN2PORT(pin) ((pin & PORT_MASK) >> 3)
+#define PIN2MASK(pin) (~(1 << PIN2INDEX(pin)))
+#define PIN2INDEX(pin) (pin & ~PORT_MASK)
+#define PIN2BIT(pin) (1 << PIN2INDEX(pin))
+
+#define EXPANDER_ADDR(addr) (addr << 1)
+
+#define EXPANDER_IODIR(pin) (0x00 | PIN2PORT(pin))
+#define EXPANDER_IPOL(pin) (0x02 | PIN2PORT(pin))
+#define EXPANDER_GPINTEN(pin) (0x04 | PIN2PORT(pin))
+#define EXPANDER_DEFVAL(pin) (0x06 | PIN2PORT(pin))
+#define EXPANDER_INTCON(pin) (0x08 | PIN2PORT(pin))
+#define EXPANDER_IOCON(pin) (0x0A | PIN2PORT(pin))
+#define EXPANDER_GPPU(pin) (0x0C | PIN2PORT(pin))
+#define EXPANDER_INTF(pin) (0x0E | PIN2PORT(pin))
+#define EXPANDER_INTCAP(pin) (0x10 | PIN2PORT(pin))
+#define EXPANDER_GPIO(pin) (0x12 | PIN2PORT(pin))
+#define EXPANDER_OLAT(pin) (0x14 | PIN2PORT(pin))
+
+#define EXPANDER_IODIRA 0x00
+#define EXPANDER_IODIRB 0x01
+#define EXPANDER_IPOLA 0x02
+#define EXPANDER_IPOLB 0x03
+#define EXPANDER_GPINTENA 0x04
+#define EXPANDER_GPINTENB 0x05
+#define EXPANDER_DEFVALA 0x06
+#define EXPANDER_DEFVALB 0x07
+#define EXPANDER_INTCONA 0x08
+#define EXPANDER_INTCONB 0x09
+#define EXPANDER_IOCONA 0x0A
+#define EXPANDER_IOCONB 0x0B
+#define EXPANDER_GPPUA 0x0C
+#define EXPANDER_GPPUB 0x0D
+#define EXPANDER_INTFA 0x0E
+#define EXPANDER_INTFB 0x0F
+#define EXPANDER_INTCAPA 0x10
+#define EXPANDER_INTCAPB 0x11
+#define EXPANDER_GPIOA 0x12
+#define EXPANDER_GPIOB 0x13
+#define EXPANDER_OLATA 0x14
+#define EXPANDER_OLATB 0x15
+
+//
+// Default board config
+//
+#ifndef NUM_BOARDS
+#    define NUM_BOARDS 2
+#endif
+
+// clang-format off
+#ifndef BOARD_INFOS
+#if NUM_BOARDS == 2
+#define BOARD_INFOS \
+{ \
+    { \
+        true, \
+        false, \
+        0x00, \
+        { D4, D5, D6, D7 }, \
+        { D1, D0, C3, C2, C1, C0 }, \
+        { B1, B2 }, \
+        { false, false }, \
+        NULL \
+    }, \
+    { \
+        false, \
+        false, \
+        0x20, \
+        { GPB4, GPB5, GPB6, GPB7 }, \
+        { GPA7, GPA6, GPA5, GPA4, GPA3, GPA2 }, \
+        { GPB0, GPB1 }, \
+        { false, false }, \
+        NULL \
+    }, \
+}
+#elif NUM_BOARDS == 3
+#define BOARD_INFOS \
+{ \
+    { \
+        true, \
+        false, \
+        0x00, \
+        { D4, D5, D6, D7 }, \
+        { D1, D0, C3, C2, C1, C0 }, \
+        { B1, B2 }, \
+        { false, false }, \
+        NULL \
+    }, \
+    { \
+        false, \
+        false, \
+        0x20, \
+        { GPB4, GPB5, GPB6, GPB7 }, \
+        { GPA7, GPA6, GPA5, GPA4, GPA3, GPA2 }, \
+        { GPB0, GPB1 }, \
+        { false, false }, \
+        NULL \
+    }, \
+    { \
+        false, \
+        false, \
+        0x21, \
+        { GPB4, GPB5, GPB6, GPB7 }, \
+        { GPA7, GPA6, GPA5, GPA4, GPA3, GPA2 }, \
+        { GPB0, GPB1 }, \
+        { false, false }, \
+        NULL \
+    }, \
+}
+#endif
+#endif
+// clang-format on
+
+void board_set_led_by_index(uint8_t board_index, uint8_t led_index, bool status);
+bool board_read_cols_on_row(matrix_row_t current_matrix[], uint8_t row);
+void board_select_row(uint8_t row);
+void board_unselect_row(uint8_t row);
+void board_unselect_rows(void);
+void board_init(void);

+ 15 - 0
keyboards/chidori/chidori.c

@@ -0,0 +1,15 @@
+/* Copyright 2019 ENDO Katsuhiro <ka2hiro@kagizaraya.jp>
+ *
+ * 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/>.
+ */

+ 59 - 0
keyboards/chidori/chidori.h

@@ -0,0 +1,59 @@
+/* Copyright 2019 ENDO Katsuhiro <ka2hiro@kagizaraya.jp>
+ *
+ * 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"
+
+// clang-format off
+#define LAYOUT( \
+        L01, L02, L03, L04, L05, L06, R01, R02, R03, R04, R05, R06, \
+        L07, L08, L09, L10, L11, L12, R07, R08, R09, R10, R11, R12, \
+        L13, L14, L15, L16, L17, L18, R13, R14, R15, R16, R17, R18, \
+        L19, L20, L21, L22, L23, L24, R19, R20, R21, R22, R23, R24  \
+    ) \
+    { \
+        { L01, L02, L03, L04, L05, L06 }, \
+        { L07, L08, L09, L10, L11, L12 }, \
+        { L13, L14, L15, L16, L17, L18 }, \
+        { L19, L20, L21, L22, L23, L24 }, \
+        { R01, R02, R03, R04, R05, R06 }, \
+        { R07, R08, R09, R10, R11, R12 }, \
+        { R13, R14, R15, R16, R17, R18 }, \
+        { R19, R20, R21, R22, R23, R24 }  \
+    }
+
+#define LAYOUT_extended( \
+        L01, L02, L03, L04, L05, L06, M01, M02, M03, M04, M05, M06, R01, R02, R03, R04, R05, R06, \
+        L07, L08, L09, L10, L11, L12, M07, M08, M09, M10, M11, M12, R07, R08, R09, R10, R11, R12, \
+        L13, L14, L15, L16, L17, L18, M13, M14, M15, M16, M17, M18, R13, R14, R15, R16, R17, R18, \
+        L19, L20, L21, L22, L23, L24, M19, M20, M21, M22, M23, M24, R19, R20, R21, R22, R23, R24  \
+    ) \
+    { \
+        { L01, L02, L03, L04, L05, L06 }, \
+        { L07, L08, L09, L10, L11, L12 }, \
+        { L13, L14, L15, L16, L17, L18 }, \
+        { L19, L20, L21, L22, L23, L24 }, \
+        { M01, M02, M03, M04, M05, M06 }, \
+        { M07, M08, M09, M10, M11, M12 }, \
+        { M13, M14, M15, M16, M17, M18 }, \
+        { M19, M20, M21, M22, M23, M24 }, \
+        { R01, R02, R03, R04, R05, R06 }, \
+        { R07, R08, R09, R10, R11, R12 }, \
+        { R13, R14, R15, R16, R17, R18 }, \
+        { R19, R20, R21, R22, R23, R24 }  \
+    }
+
+// clang-format on

+ 253 - 0
keyboards/chidori/config.h

@@ -0,0 +1,253 @@
+/*
+Copyright 2019 ENDO Katsuhiro <ka2hiro@kagizaraya.jp>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0xFEED
+#define PRODUCT_ID 0x3942
+#define DEVICE_VER 0x0001
+#define MANUFACTURER Kagizaraya
+#define PRODUCT Chidori
+#define DESCRIPTION Yet another split keyboard made with only through - hole components
+
+/* key matrix size */
+#define MATRIX_ROWS 12
+#define MATRIX_COLS 6
+
+/*
+ * Keyboard Matrix Assignments
+ *
+ * Change this to how you wired your keyboard
+ * COLS: AVR pins used for columns, left to right
+ * ROWS: AVR pins used for rows, top to bottom
+ * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
+ *                  ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
+ *
+ */
+/*
+#define MATRIX_ROW_PINS \
+    { D0, D5 }
+#define MATRIX_COL_PINS \
+    { F1, F0, B0 }
+*/
+#define UNUSED_PINS
+
+/* COL2ROW, ROW2COL*/
+// #define DIODE_DIRECTION COL2ROW
+
+/*
+ * Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk, and define SOFT_SERIAL_PIN.
+ */
+// #define SOFT_SERIAL_PIN D0  // or D1, D2, D3, E6
+
+// #define BACKLIGHT_PIN B7
+// #define BACKLIGHT_BREATHING
+// #define BACKLIGHT_LEVELS 3
+
+// #define RGB_DI_PIN E2
+// #ifdef RGB_DI_PIN
+//   #define RGBLED_NUM 16
+//   #define RGBLIGHT_HUE_STEP 8
+//   #define RGBLIGHT_SAT_STEP 8
+//   #define RGBLIGHT_VAL_STEP 8
+//   #define RGBLIGHT_LIMIT_VAL 255 /* The maximum brightness level */
+//   #define RGBLIGHT_SLEEP  /* If defined, the RGB lighting will be switched off when the host goes to sleep */
+// /*== all animations enable ==*/
+//   #define RGBLIGHT_ANIMATIONS
+// /*== or choose animations ==*/
+//   #define RGBLIGHT_EFFECT_BREATHING
+//   #define RGBLIGHT_EFFECT_RAINBOW_MOOD
+//   #define RGBLIGHT_EFFECT_RAINBOW_SWIRL
+//   #define RGBLIGHT_EFFECT_SNAKE
+//   #define RGBLIGHT_EFFECT_KNIGHT
+//   #define RGBLIGHT_EFFECT_CHRISTMAS
+//   #define RGBLIGHT_EFFECT_STATIC_GRADIENT
+//   #define RGBLIGHT_EFFECT_RGB_TEST
+//   #define RGBLIGHT_EFFECT_ALTERNATING
+// /*== customize breathing effect ==*/
+//   /*==== (DEFAULT) use fixed table instead of exp() and sin() ====*/
+//   #define RGBLIGHT_BREATHE_TABLE_SIZE 256      // 256(default) or 128 or 64
+//   /*==== use exp() and sin() ====*/
+//   #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85  // 1 to 2.7
+//   #define RGBLIGHT_EFFECT_BREATHE_MAX    255   // 0 to 255
+// #endif
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCE 5
+
+/* define if matrix has ghost (lacks anti-ghosting diodes) */
+//#define MATRIX_HAS_GHOST
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+/* If defined, GRAVE_ESC will always act as ESC when CTRL is held.
+ * This is userful for the Windows task manager shortcut (ctrl+shift+esc).
+ */
+// #define GRAVE_ESC_CTRL_OVERRIDE
+
+/*
+ * Force NKRO
+ *
+ * Force NKRO (nKey Rollover) to be enabled by default, regardless of the saved
+ * state in the bootmagic EEPROM settings. (Note that NKRO must be enabled in the
+ * makefile for this to work.)
+ *
+ * If forced on, NKRO can be disabled via magic key (default = LShift+RShift+N)
+ * until the next keyboard reset.
+ *
+ * NKRO may prevent your keystrokes from being detected in the BIOS, but it is
+ * fully operational during normal computer usage.
+ *
+ * For a less heavy-handed approach, enable NKRO via magic key (LShift+RShift+N)
+ * or via bootmagic (hold SPACE+N while plugging in the keyboard). Once set by
+ * bootmagic, NKRO mode will always be enabled until it is toggled again during a
+ * power-up.
+ *
+ */
+//#define FORCE_NKRO
+
+/*
+ * Magic Key Options
+ *
+ * Magic keys are hotkey commands that allow control over firmware functions of
+ * the keyboard. They are best used in combination with the HID Listen program,
+ * found here: https://www.pjrc.com/teensy/hid_listen.html
+ *
+ * The options below allow the magic key functionality to be changed. This is
+ * useful if your keyboard/keypad is missing keys and you want magic key support.
+ *
+ */
+
+/* key combination for magic key command */
+/* defined by default; to change, uncomment and set to the combination you want */
+#define IS_COMMAND() (get_mods() == (MOD_BIT(KC_LSFT) | MOD_BIT(KC_LCTL)))
+
+/* control how magic key switches layers */
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS  true
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS  true
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
+
+/* override magic key keymap */
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
+//#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
+//#define MAGIC_KEY_HELP           H
+//#define MAGIC_KEY_HELP_ALT       SLASH
+//#define MAGIC_KEY_DEBUG          D
+//#define MAGIC_KEY_DEBUG_MATRIX   X
+//#define MAGIC_KEY_DEBUG_KBD      K
+//#define MAGIC_KEY_DEBUG_MOUSE    M
+//#define MAGIC_KEY_VERSION        V
+//#define MAGIC_KEY_STATUS         S
+//#define MAGIC_KEY_CONSOLE        C
+//#define MAGIC_KEY_LAYER0         0
+//#define MAGIC_KEY_LAYER0_ALT     GRAVE
+//#define MAGIC_KEY_LAYER1         1
+//#define MAGIC_KEY_LAYER2         2
+//#define MAGIC_KEY_LAYER3         3
+//#define MAGIC_KEY_LAYER4         4
+//#define MAGIC_KEY_LAYER5         5
+//#define MAGIC_KEY_LAYER6         6
+//#define MAGIC_KEY_LAYER7         7
+//#define MAGIC_KEY_LAYER8         8
+//#define MAGIC_KEY_LAYER9         9
+//#define MAGIC_KEY_BOOTLOADER     B
+//#define MAGIC_KEY_BOOTLOADER_ALT ESC
+//#define MAGIC_KEY_LOCK           CAPS
+//#define MAGIC_KEY_EEPROM         E
+//#define MAGIC_KEY_EEPROM_CLEAR   BSPACE
+//#define MAGIC_KEY_NKRO           N
+//#define MAGIC_KEY_SLEEP_LED      Z
+
+/*
+ * Feature disable options
+ *  These options are also useful to firmware size reduction.
+ */
+
+/* disable debug print */
+//#define NO_DEBUG
+
+/* disable print */
+//#define NO_PRINT
+
+/* disable action features */
+//#define NO_ACTION_LAYER
+//#define NO_ACTION_TAPPING
+//#define NO_ACTION_ONESHOT
+//#define NO_ACTION_MACRO
+//#define NO_ACTION_FUNCTION
+
+/*
+ * MIDI options
+ */
+
+/* Prevent use of disabled MIDI features in the keymap */
+//#define MIDI_ENABLE_STRICT 1
+
+/* enable basic MIDI features:
+   - MIDI notes can be sent when in Music mode is on
+*/
+//#define MIDI_BASIC
+
+/* enable advanced MIDI features:
+   - MIDI notes can be added to the keymap
+   - Octave shift and transpose
+   - Virtual sustain, portamento, and modulation wheel
+   - etc.
+*/
+//#define MIDI_ADVANCED
+
+/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
+//#define MIDI_TONE_KEYCODE_OCTAVES 1
+
+/*
+ * HD44780 LCD Display Configuration
+ */
+/*
+#define LCD_LINES           2     //< number of visible lines of the display
+#define LCD_DISP_LENGTH    16     //< visibles characters per line of the display
+
+#define LCD_IO_MODE      1            //< 0: memory mapped mode, 1: IO port mode
+
+#if LCD_IO_MODE
+#define LCD_PORT         PORTB        //< port for the LCD lines
+#define LCD_DATA0_PORT   LCD_PORT     //< port for 4bit data bit 0
+#define LCD_DATA1_PORT   LCD_PORT     //< port for 4bit data bit 1
+#define LCD_DATA2_PORT   LCD_PORT     //< port for 4bit data bit 2
+#define LCD_DATA3_PORT   LCD_PORT     //< port for 4bit data bit 3
+#define LCD_DATA0_PIN    4            //< pin for 4bit data bit 0
+#define LCD_DATA1_PIN    5            //< pin for 4bit data bit 1
+#define LCD_DATA2_PIN    6            //< pin for 4bit data bit 2
+#define LCD_DATA3_PIN    7            //< pin for 4bit data bit 3
+#define LCD_RS_PORT      LCD_PORT     //< port for RS line
+#define LCD_RS_PIN       3            //< pin  for RS line
+#define LCD_RW_PORT      LCD_PORT     //< port for RW line
+#define LCD_RW_PIN       2            //< pin  for RW line
+#define LCD_E_PORT       LCD_PORT     //< port for Enable line
+#define LCD_E_PIN        1            //< pin  for Enable line
+#endif
+*/
+
+/* Bootmagic Lite key configuration */
+// #define BOOTMAGIC_LITE_ROW 0
+// #define BOOTMAGIC_LITE_COLUMN 0

+ 25 - 0
keyboards/chidori/info.json

@@ -0,0 +1,25 @@
+{
+    "keyboard_name": "Chidori", 
+    "url": "", 
+    "maintainer": "ka2hiro", 
+    "width": 12, 
+    "height": 4, 
+    "layouts": {
+        "LAYOUT": {
+            "layout": [
+                {"x":0, "y":0}, {"x":1, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":4, "y":0}, {"x":5, "y":0}, {"x":7, "y":0}, {"x":8, "y":0}, {"x":9, "y":0}, {"x":10, "y":0}, {"x":11, "y":0},
+                {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1}, {"x":3, "y":1}, {"x":4, "y":1}, {"x":5, "y":1}, {"x":7, "y":1}, {"x":8, "y":1}, {"x":9, "y":1}, {"x":10, "y":1}, {"x":11, "y":1},
+                {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}, {"x":3, "y":2}, {"x":4, "y":2}, {"x":5, "y":2}, {"x":7, "y":2}, {"x":8, "y":2}, {"x":9, "y":2}, {"x":10, "y":2}, {"x":11, "y":2},
+                {"x":0, "y":3}, {"x":1, "y":3}, {"x":2, "y":3}, {"x":3, "y":3}, {"x":4, "y":3}, {"x":5, "y":3}, {"x":7, "y":3}, {"x":8, "y":3}, {"x":9, "y":3}, {"x":10, "y":3}, {"x":11, "y":3}
+            ]
+        },
+        "LAYOUT_extended": {
+            "layout": [
+                {"x":0, "y":0}, {"x":1, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":4, "y":0}, {"x":5, "y":0}, {"x":7, "y":0}, {"x":8, "y":0}, {"x":9, "y":0}, {"x":10, "y":0}, {"x":11, "y":0}, {"x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0}, {"x":15, "y":0},
+                {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1}, {"x":3, "y":1}, {"x":4, "y":1}, {"x":5, "y":1}, {"x":7, "y":1}, {"x":8, "y":1}, {"x":9, "y":1}, {"x":10, "y":1}, {"x":11, "y":1}, {"x":12, "y":1}, {"x":13, "y":1}, {"x":14, "y":1}, {"x":15, "y":1},
+                {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}, {"x":3, "y":2}, {"x":4, "y":2}, {"x":5, "y":2}, {"x":7, "y":2}, {"x":8, "y":2}, {"x":9, "y":2}, {"x":10, "y":2}, {"x":11, "y":2}, {"x":12, "y":2}, {"x":13, "y":2}, {"x":14, "y":2}, {"x":15, "y":2},
+                {"x":0, "y":3}, {"x":1, "y":3}, {"x":2, "y":3}, {"x":3, "y":3}, {"x":4, "y":3}, {"x":5, "y":3}, {"x":7, "y":3}, {"x":8, "y":3}, {"x":9, "y":3}, {"x":10, "y":3}, {"x":11, "y":3}, {"x":12, "y":3}, {"x":13, "y":3}, {"x":14, "y":3}, {"x":15, "y":3}
+            ]
+        }
+    }
+}

+ 48 - 0
keyboards/chidori/keymaps/default/config.h

@@ -0,0 +1,48 @@
+/* Copyright 2019 ENDO Katsuhiro <ka2hiro@kagizaraya.jp>
+ *
+ * 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
+
+/*
+ * Board config
+ */
+/*
+#define NUM_BOARDS  2
+
+#define BOARD_INFOS \
+{ \
+    { \
+        true, \
+        false, \
+        0x00, \
+        { D4, D5, D6, D7 }, \
+        { D1, D0, C3, C2, C1, C0 }, \
+        { B1, B2 }, \
+        { false, false }, \
+        NULL \
+    }, \
+    { \
+        false, \
+        false, \
+        0x20, \
+        { GPB4, GPB5, GPB6, GPB7 }, \
+        { GPA7, GPA6, GPA5, GPA4, GPA3, GPA2 }, \
+        { GPB0, GPB1 }, \
+        { false, false }, \
+        NULL \
+    }, \
+}
+*/

+ 176 - 0
keyboards/chidori/keymaps/default/keymap.c

@@ -0,0 +1,176 @@
+/* Copyright 2019 ENDO Katsuhiro <ka2hiro@kagizaraya.jp>
+ *
+ * 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 "board.h"
+
+enum layer_number { _QWERTY = 0, _COLEMAK, _DVORAK, _LOWER, _RAISE, _ADJUST };
+
+// Defines the keycodes used by our macros in process_record_user
+enum custom_keycodes { QWERTY = SAFE_RANGE, COLEMAK, DVORAK };
+
+#define LOWER  MO(_LOWER)
+#define RAISE  MO(_RAISE)
+#define ADJUST MO(_ADJUST)
+
+// clang-format off
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+  /* Qwerty
+   * ,-----------------------------------------.             ,-----------------------------------------.
+   * | Tab  |   Q  |   W  |   E  |   R  |   T  |             |   Y  |   U  |   I  |   O  |   P  | Bksp |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Ctrl |   A  |   S  |   D  |   F  |   G  |             |   H  |   J  |   K  |   L  |   ;  |  '   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Shift|   Z  |   X  |   C  |   V  |   B  |             |   N  |   M  |   ,  |   .  |   /  |Enter |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |ADJUST| Esc  | Alt  | GUI  |LOWER |Space |             | Space| RAISE| Left | Down |  Up  | Right|
+   * `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_QWERTY] = LAYOUT(
+      KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,              KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC,
+      KC_LCTL, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,              KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,
+      KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,              KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT,
+      ADJUST,  KC_ESC,  KC_LALT, KC_LGUI, LOWER,   KC_SPC,            KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT
+    ),
+  /* Colemak
+   * ,-----------------------------------------.             ,-----------------------------------------.
+   * | Tab  |   Q  |   W  |   F  |   P  |   G  |             |   J  |   L  |   U  |   Y  |   ;  | Bksp |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Ctrl |   A  |   R  |   S  |   T  |   D  |             |   H  |   N  |   E  |   I  |   O  |  '   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Shift|   Z  |   X  |   C  |   V  |   B  |             |   K  |   M  |   ,  |   .  |   /  |Enter |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |ADJUST| Esc  | Alt  | GUI  |LOWER |Space |             | Space| RAISE| Left | Down |  Up  | Right|
+   * `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_COLEMAK] = LAYOUT(
+      KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_G,              KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN, KC_BSPC,
+      KC_LCTL, KC_A,    KC_R,    KC_S,    KC_T,    KC_D,              KC_H,    KC_N,    KC_E,    KC_I,    KC_O,    KC_QUOT,
+      KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,              KC_K,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT,
+      ADJUST,  KC_ESC,  KC_LALT, KC_LGUI, LOWER,   KC_SPC,            KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT
+    ),
+
+  /* Dvorak
+   * ,-----------------------------------------.             ,-----------------------------------------.
+   * | Tab  |   '  |   ,  |   .  |   P  |   Y  |             |   F  |   G  |   C  |   R  |   L  | Bksp |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Ctrl |   A  |   O  |   E  |   U  |   I  |             |   D  |   H  |   T  |   N  |   S  |  /   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Shift|   ;  |   Q  |   J  |   K  |   X  |             |   B  |   M  |   W  |   V  |   Z  |Enter |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |ADJUST| Esc  | Alt  | GUI  |LOWER |Space |             | Space| RAISE| Left | Down |  Up  | Right|
+   * `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_DVORAK] = LAYOUT(
+      KC_TAB,  KC_QUOT, KC_COMM, KC_DOT,  KC_P,    KC_Y,              KC_F,    KC_G,    KC_C,    KC_R,    KC_L,    KC_BSPC,
+      KC_LCTL, KC_A,    KC_O,    KC_E,    KC_U,    KC_I,              KC_D,    KC_H,    KC_T,    KC_N,    KC_S,    KC_SLSH,
+      KC_LSFT, KC_SCLN, KC_Q,    KC_J,    KC_K,    KC_X,              KC_B,    KC_M,    KC_W,    KC_V,    KC_Z,    KC_ENT,
+      ADJUST,  KC_ESC,  KC_LALT, KC_LGUI, LOWER,   KC_SPC,            KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT
+    ),
+
+  /* Lower
+   * ,-----------------------------------------.             ,-----------------------------------------.
+   * |   ~  |   !  |   @  |   #  |   $  |   %  |             |   ^  |   &  |   *  |   (  |   )  |      |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |      |      |      |      |      |             |   -  |   _  |   +  |   {  |   }  |  |   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |      |      |      |      |      |             |      |      |      | Home | End  |      |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |      |      |      |      |      |             |      |      | Next | Vol- | Vol+ | Play |
+   * `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_LOWER] = LAYOUT(
+      KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC,           KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______,
+      _______, _______, _______, _______, _______, _______,           KC_MINS, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
+      _______, _______, _______, _______, _______, _______,           _______, _______, _______, KC_HOME, KC_END,  _______,
+      _______, _______, _______, _______, _______, _______,           _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY
+    ),
+
+  /* Raise
+   * ,-----------------------------------------.             ,-----------------------------------------.
+   * |   `  |   1  |   2  |   3  |   4  |   5  |             |   6  |   7  |   8  |   9  |   0  | Del  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |  F1  |  F2  |  F3  |  F4  |  F5  |             |  F6  |   -  |   =  |   [  |   ]  |  \   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |  F7  |  F8  |  F9  |  F10 |  F11 |             |  F12 |      |      |      |      |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |      |      |      |      |      |             |      |      | Next | Vol- | Vol+ | Play |
+   * `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_RAISE] = LAYOUT(
+      KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,              KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_DEL,
+      _______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,             KC_F6,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS,
+      _______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,            KC_F12,  _______, _______, _______, _______, _______,
+      _______, _______, _______, _______, _______, _______,           _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY
+    ),
+
+  /* Adjust (Lower + Raise)
+   * ,-----------------------------------------.             ,-----------------------------------------.
+   * |      | Reset|      |      |      |      |             |      |Qwerty|Colemk|Dvorak|      | Ins  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Caps |      |      |      |      | Mac  |             | Win  |  -   |   =  |Print |ScLock|Pause |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |      |      |      |      |      |             |      |      |      |      |      |      |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |      |      |      |      |      |             | KANA |      | Home |PageDn|PageUp| End  |
+   * `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_ADJUST] = LAYOUT(
+      _______, RESET,   _______, _______, _______, _______,           _______, QWERTY,  COLEMAK, DVORAK,  _______, KC_INS,
+      KC_CAPS, _______, _______, _______, _______, AG_NORM,           AG_SWAP, KC_MINS, KC_EQL,  KC_PSCR, KC_SLCK, KC_PAUS,
+      _______, _______, _______, _______, _______, _______,           _______, _______, _______, _______, _______, _______,
+      _______, _______, _______, _______, _______, _______,           _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END
+    )
+};
+// clang-format on
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+  return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+    switch (keycode) {
+        case QWERTY:
+            if (record->event.pressed) {
+                set_single_persistent_default_layer(_QWERTY);
+            }
+            return false;
+        case COLEMAK:
+            if (record->event.pressed) {
+                set_single_persistent_default_layer(_COLEMAK);
+            }
+            return false;
+        case DVORAK:
+            if (record->event.pressed) {
+                set_single_persistent_default_layer(_DVORAK);
+            }
+            return false;
+    }
+    return true;
+}
+
+void led_set_user(uint8_t usb_led) {
+    if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
+        board_set_led_by_index(0, LED_YELLOW, true);
+    } else {
+        board_set_led_by_index(0, LED_YELLOW, false);
+    }
+    if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
+        board_set_led_by_index(1, LED_YELLOW, true);
+    } else {
+        board_set_led_by_index(1, LED_YELLOW, false);
+    }
+}

+ 1 - 0
keyboards/chidori/keymaps/default/readme.md

@@ -0,0 +1 @@
+# The default keymap for chidori

+ 59 - 0
keyboards/chidori/keymaps/extended/config.h

@@ -0,0 +1,59 @@
+/* Copyright 2019 ENDO Katsuhiro <ka2hiro@kagizaraya.jp>
+ *
+ * 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
+
+/*
+ * Board config
+ */
+#define NUM_BOARDS  3
+
+/*
+#define BOARD_INFOS \
+{ \
+    { \
+        true, \
+        false, \
+        0x00, \
+        { D4, D5, D6, D7 }, \
+        { D1, D0, C3, C2, C1, C0 }, \
+        { B1, B2 }, \
+        { false, false }, \
+        NULL \
+    }, \
+    { \
+        false, \
+        false, \
+        0x20, \
+        { GPB4, GPB5, GPB6, GPB7 }, \
+        { GPA7, GPA6, GPA5, GPA4, GPA3, GPA2 }, \
+        { GPB0, GPB1 }, \
+        { false, false }, \
+        NULL \
+    }, \
+    { \
+        false, \
+        false, \
+        0x21, \
+        { GPB4, GPB5, GPB6, GPB7 }, \
+        { GPA7, GPA6, GPA5, GPA4, GPA3, GPA2 }, \
+        { GPB0, GPB1 }, \
+        { false, false }, \
+        NULL \
+    }, \
+}
+*/
+

+ 181 - 0
keyboards/chidori/keymaps/extended/keymap.c

@@ -0,0 +1,181 @@
+/* Copyright 2019 ENDO Katsuhiro <ka2hiro@kagizaraya.jp>
+ *
+ * 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 "board.h"
+
+enum layer_number { _QWERTY = 0, _COLEMAK, _DVORAK, _LOWER, _RAISE, _ADJUST };
+
+// Defines the keycodes used by our macros in process_record_user
+enum custom_keycodes { QWERTY = SAFE_RANGE, COLEMAK, DVORAK };
+
+#define LOWER  MO(_LOWER)
+#define RAISE  MO(_RAISE)
+#define ADJUST MO(_ADJUST)
+
+// clang-format off
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+  /* Qwerty
+   * ,-----------------------------------------.             ,-----------------------------------------.             ,-----------------------------------------.
+   * | Tab  |   Q  |   W  |   E  |   R  |   T  |             |   Y  |   U  |   I  |   O  |   P  | Bksp |             |   7  |   8  |   9  |      |NumLck| Esc  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------|  +   |------+------|
+   * | Ctrl |   A  |   S  |   D  |   F  |   G  |             |   H  |   J  |   K  |   L  |   ;  |  '   |             |   4  |   5  |   6  |      |   /  | Tab  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Shift|   Z  |   X  |   C  |   V  |   B  |             |   N  |   M  |   ,  |   .  |   /  |Enter |             |   1  |   2  |   3  |      |   *  |  =   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |-------------+------|Enter |------+------|
+   * |ADJUST| Esc  | Alt  | GUI  |LOWER |Space |             | Space| RAISE| Left | Down |  Up  | Right|             |      0      |   .  |      |   -  | Bksp |
+   * `-----------------------------------------'             `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_QWERTY] = LAYOUT_extended(
+      KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,              KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC,         KC_P7,   KC_P8,   KC_P9,  KC_PPLS, KC_NLCK, KC_ESC,
+      KC_LCTL, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,              KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,         KC_P4,   KC_P5,   KC_P6,  _______, KC_PSLS, KC_TAB,
+      KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,              KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT ,         KC_P1,   KC_P2,   KC_P3,  KC_PENT, KC_PAST, KC_PEQL,
+      ADJUST,  KC_ESC,  KC_LALT, KC_LGUI, LOWER,   KC_SPC,            KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT,      KC_P0,   _______, KC_PDOT,_______, KC_PMNS, KC_BSPC
+    ),
+  /* Colemak
+   * ,-----------------------------------------.             ,-----------------------------------------.             ,-----------------------------------------.
+   * | Tab  |   Q  |   W  |   F  |   P  |   G  |             |   J  |   L  |   U  |   Y  |   ;  | Bksp |             |   7  |   8  |   9  |      |NumLck| Esc  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------|  +   |------+------|
+   * | Ctrl |   A  |   R  |   S  |   T  |   D  |             |   H  |   N  |   E  |   I  |   O  |  '   |             |   4  |   5  |   6  |      |   /  | Tab  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Shift|   Z  |   X  |   C  |   V  |   B  |             |   K  |   M  |   ,  |   .  |   /  |Enter |             |   1  |   2  |   3  |      |   *  |  =   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |-------------+------|Enter |------+------|
+   * |ADJUST| Esc  | Alt  | GUI  |LOWER |Space |             | Space| RAISE| Left | Down |  Up  | Right|             |      0      |   .  |      |   -  | Bksp |
+   * `-----------------------------------------'             `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_COLEMAK] = LAYOUT_extended(
+      KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_G,              KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN, KC_BSPC,       KC_P7,   KC_P8,   KC_P9,  KC_PPLS, KC_NLCK, KC_ESC,
+      KC_LCTL, KC_A,    KC_R,    KC_S,    KC_T,    KC_D,              KC_H,    KC_N,    KC_E,    KC_I,    KC_O,    KC_QUOT,       KC_P4,   KC_P5,   KC_P6,  _______, KC_PSLS, KC_TAB,
+      KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,              KC_K,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT ,       KC_P1,   KC_P2,   KC_P3,  KC_PENT, KC_PAST, KC_PEQL,
+      ADJUST,  KC_ESC,  KC_LALT, KC_LGUI, LOWER,   KC_SPC,            KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT,       KC_P0,   _______, KC_PDOT,_______, KC_PMNS, KC_BSPC
+    ),
+
+  /* Dvorak
+   * ,-----------------------------------------.             ,-----------------------------------------.             ,-----------------------------------------.
+   * | Tab  |   '  |   ,  |   .  |   P  |   Y  |             |   F  |   G  |   C  |   R  |   L  | Del  |             |   7  |   8  |   9  |      |NumLck| Esc  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------|  +   |------+------|
+   * | Ctrl |   A  |   O  |   E  |   U  |   I  |             |   D  |   H  |   T  |   N  |   S  |  /   |             |   4  |   5  |   6  |      |   /  | Tab  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * | Shift|   ;  |   Q  |   J  |   K  |   X  |             |   B  |   M  |   W  |   V  |   Z  |Enter |             |   1  |   2  |   3  |      |   *  |  =   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |-------------+------|Enter |------+------|
+   * |ADJUST| Esc  | Alt  | GUI  |LOWER |Space |             | Space| RAISE| Left | Down |  Up  | Right|             |      0      |   .  |      |   -  | Bksp |
+   * `-----------------------------------------'             `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_DVORAK] = LAYOUT_extended(
+      KC_TAB,  KC_QUOT, KC_COMM, KC_DOT,  KC_P,    KC_Y,              KC_F,    KC_G,    KC_C,    KC_R,    KC_L,    KC_DEL,        KC_P7,   KC_P8,   KC_P9,  KC_PPLS, KC_NLCK, KC_ESC,
+      KC_LCTL, KC_A,    KC_O,    KC_E,    KC_U,    KC_I,              KC_D,    KC_H,    KC_T,    KC_N,    KC_S,    KC_SLSH,       KC_P4,   KC_P5,   KC_P6,  _______, KC_PSLS, KC_TAB,
+      KC_LSFT, KC_SCLN, KC_Q,    KC_J,    KC_K,    KC_X,              KC_B,    KC_M,    KC_W,    KC_V,    KC_Z,    KC_ENT ,       KC_P1,   KC_P2,   KC_P3,  KC_PENT, KC_PAST, KC_PEQL,
+      ADJUST,  KC_ESC,  KC_LALT, KC_LGUI, LOWER,   KC_SPC,            KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT,       KC_P0,   _______, KC_PDOT,_______, KC_PMNS, KC_BSPC
+    ),
+
+  /* Lower
+   * ,-----------------------------------------.             ,-----------------------------------------.             ,-----------------------------------------.
+   * |   ~  |   !  |   @  |   #  |   $  |   %  |             |   ^  |   &  |   *  |   (  |   )  |      |             |   7  |   8  |   9  |      |NumLck| Esc  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------|  +   |------+------|
+   * |      |      |      |      |      |      |             |   -  |   _  |   +  |   {  |   }  |  |   |             |   4  |   5  |   6  |      |   /  | Tab  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |      |      |      |      |      |             |      |      |      | Home | End  |      |             |   1  |   2  |   3  |      |   *  |  =   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |-------------+------|Enter |------+------|
+   * |      |      |      |      |      |      |             |      |      | Next | Vol- | Vol+ | Play |             |      0      |   .  |      |   -  | Bksp |
+   * `-----------------------------------------'             `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_LOWER] = LAYOUT_extended(
+      KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC,           KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______,       KC_P7,   KC_P8,   KC_P9,  KC_PPLS, KC_NLCK, KC_ESC,
+      _______, _______, _______, _______, _______, _______,           KC_MINS, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,       KC_P4,   KC_P5,   KC_P6,  _______, KC_PSLS, KC_TAB,
+      _______, _______, _______, _______, _______, _______,           _______, _______, _______, KC_HOME, KC_END,  _______,       KC_P1,   KC_P2,   KC_P3,  KC_PENT, KC_PAST, KC_PEQL,
+      _______, _______, _______, _______, _______, _______,           _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY,       KC_P0,   _______, KC_PDOT,_______, KC_PMNS, KC_BSPC
+    ),
+
+  /* Raise
+   * ,-----------------------------------------.             ,-----------------------------------------.             ,-----------------------------------------.
+   * |   `  |   1  |   2  |   3  |   4  |   5  |             |   6  |   7  |   8  |   9  |   0  | Del  |             |   7  |   8  |   9  |      |NumLck| Esc  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------|  +   |------+------|
+   * |      |  F1  |  F2  |  F3  |  F4  |  F5  |             |  F6  |   -  |   =  |   [  |   ]  |  \   |             |   4  |   5  |   6  |      |   /  | Tab  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |  F7  |  F8  |  F9  |  F10 |  F11 |             |  F12 |      |      |      |      |                    |   1  |   2  |   3  |      |   *  |  =   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |-------------+------|Enter |------+------|
+   * |      |      |      |      |      |      |             |      |      | Next | Vol- | Vol+ | Play |             |      0      |   .  |      |   -  | Bksp |
+   * `-----------------------------------------'             `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_RAISE] = LAYOUT_extended(
+      KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,              KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_DEL,        KC_P7,   KC_P8,   KC_P9,  KC_PPLS, KC_NLCK, KC_ESC,
+      _______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,             KC_F6,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS,       KC_P4,   KC_P5,   KC_P6,  _______, KC_PSLS, KC_TAB,
+      _______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,            KC_F12,  _______, _______, _______, _______, _______,       KC_P1,   KC_P2,   KC_P3,  KC_PENT, KC_PAST, KC_PEQL,
+      _______, _______, _______, _______, _______, _______,           _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY,       KC_P0,   _______, KC_PDOT,_______, KC_PMNS, KC_BSPC
+    ),
+
+  /* Adjust (Lower + Raise)
+   * ,-----------------------------------------.             ,-----------------------------------------.             ,-----------------------------------------.
+   * |      | Reset|      |      |      |      |             |      |Qwerty|Colemk|Dvorak|      | Ins  |             |   7  |   8  |   9  |      |NumLck| Esc  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------|  +   |------+------|
+   * | Caps |      |      |      |      | Mac  |             | Win  |  -   |   =  |Print |ScLock|Pause |             |   4  |   5  |   6  |      |   /  | Tab  |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |------+------+------+------+------+------|
+   * |      |      |      |      |      |      |             |      |      |      |      |      |      |             |   1  |   2  |   3  |      |   *  |  =   |
+   * |------+------+------+------+------+------|             |------+------+------+------+------+------|             |-------------+------|Enter |------+------|
+   * |      |      |      |      |      |      |             |      |      | Home |PageDn|PageUp| End  |             |      0      |   .  |      |   -  | Bksp |
+   * `-----------------------------------------'             `-----------------------------------------'             `-----------------------------------------'
+   */
+    [_ADJUST] = LAYOUT_extended(
+      _______, RESET,   _______, _______, _______, _______,           _______, QWERTY,  COLEMAK, DVORAK,  _______, KC_INS,        KC_P7,   KC_P8,   KC_P9,  KC_PPLS, KC_NLCK, KC_ESC,
+      KC_CAPS, _______, _______, _______, _______, AG_NORM,           AG_SWAP, KC_MINS, KC_EQL,  KC_PSCR, KC_SLCK, KC_PAUS,       KC_P4,   KC_P5,   KC_P6,  _______, KC_PSLS, KC_TAB,
+      _______, _______, _______, _______, _______, _______,           _______, _______, _______, _______, _______, _______,       KC_P1,   KC_P2,   KC_P3,  KC_PENT, KC_PAST, KC_PEQL,
+      _______, _______, _______, _______, _______, _______,           _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END,        KC_P0,   _______, KC_PDOT,_______, KC_PMNS, KC_BSPC
+    )
+};
+// clang-format on
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+  return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+    switch (keycode) {
+        case QWERTY:
+            if (record->event.pressed) {
+                set_single_persistent_default_layer(_QWERTY);
+            }
+            return false;
+        case COLEMAK:
+            if (record->event.pressed) {
+                set_single_persistent_default_layer(_COLEMAK);
+            }
+            return false;
+        case DVORAK:
+            if (record->event.pressed) {
+                set_single_persistent_default_layer(_DVORAK);
+            }
+            return false;
+    }
+    return true;
+}
+
+void led_set_user(uint8_t usb_led) {
+    if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
+        board_set_led_by_index(0, LED_YELLOW, true);
+    } else {
+        board_set_led_by_index(0, LED_YELLOW, false);
+    }
+    if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
+        board_set_led_by_index(1, LED_YELLOW, true);
+    } else {
+        board_set_led_by_index(1, LED_YELLOW, false);
+    }
+    if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
+        board_set_led_by_index(2, LED_YELLOW, true);
+    } else {
+        board_set_led_by_index(2, LED_YELLOW, false);
+    }
+}

+ 1 - 0
keyboards/chidori/keymaps/extended/readme.md

@@ -0,0 +1 @@
+# The extended keymap for chidori

+ 113 - 0
keyboards/chidori/matrix.c

@@ -0,0 +1,113 @@
+/*
+Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stdint.h>
+#include <stdbool.h>
+#include "wait.h"
+#include "print.h"
+#include "debug.h"
+#include "util.h"
+#include "matrix.h"
+#include "debounce.h"
+#include "quantum.h"
+#include "board.h"
+
+#if (MATRIX_COLS <= 8)
+#    define print_matrix_header() print("\nr/c 01234567\n")
+#    define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
+#    define 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
+
+#ifdef MATRIX_MASKED
+extern const matrix_row_t matrix_mask[];
+#endif
+
+/* matrix state(1:on, 0:off) */
+static matrix_row_t raw_matrix[MATRIX_ROWS];  // raw values
+static matrix_row_t matrix[MATRIX_ROWS];      // debounced values
+
+__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 matrix_row_t matrix_get_row(uint8_t row) {
+    // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a
+    // switch blocker installed and the switch is always pressed.
+#ifdef MATRIX_MASKED
+    return matrix[row] & matrix_mask[row];
+#else
+    return matrix[row];
+#endif
+}
+
+void matrix_print(void) {
+    print_matrix_header();
+
+    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+        phex(row);
+        print(": ");
+        print_matrix_row(row);
+        print("\n");
+    }
+}
+
+void matrix_init(void) {
+    // initialize key pins
+    board_init();
+
+    // initialize matrix state: all keys off
+    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+        raw_matrix[i] = 0;
+        matrix[i]     = 0;
+    }
+
+    debounce_init(MATRIX_ROWS);
+
+    matrix_init_quantum();
+}
+
+uint8_t matrix_scan(void) {
+    bool changed = false;
+
+    // Set row, read cols
+    for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) {
+        changed |= board_read_cols_on_row(raw_matrix, current_row);
+    }
+
+    debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
+
+    matrix_scan_quantum();
+    return 1;
+}

+ 15 - 0
keyboards/chidori/readme.md

@@ -0,0 +1,15 @@
+# chidori
+
+![Chidori](https://i.imgur.com/QvpLiOvl.jpg)
+
+Yet another split keyboard made with only through-hole components.
+
+* Keyboard Maintainer: [ka2hiro](https://github.com/ka2hiro) [@ka2hiro](https://twitter.com/ka2hiro)
+* Hardware Supported: Chidori PCB, ATMEGA328P
+* Hardware Availability: [@kagizaraya](https://twitter.com/kagizaraya)
+
+Make example for this keyboard (after setting up your build environment):
+
+    make chidori:default:usbasp
+
+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).

+ 44 - 0
keyboards/chidori/rules.mk

@@ -0,0 +1,44 @@
+# MCU name
+MCU = atmega328p
+ARCH = AVR8
+F_USB = $(F_CPU)
+
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+# Bootloader selection
+#   Teensy       halfkay
+#   Pro Micro    caterina
+#   Atmel DFU    atmel-dfu
+#   LUFA DFU     lufa-dfu
+#   QMK DFU      qmk-dfu
+#   ATmega32A    bootloadHID
+#   ATmega328P   USBasp
+BOOTLOADER = USBasp
+
+# 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
+# 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
+BACKLIGHT_ENABLE = no       # Enable keyboard backlight functionality
+RGBLIGHT_ENABLE = no        # Enable keyboard RGB underglow
+MIDI_ENABLE = no            # MIDI support
+UNICODE_ENABLE = no         # Unicode
+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
+HD44780_ENABLE = no        # Enable support for HD44780 based LCDs
+
+CUSTOM_MATRIX = yes
+
+# project specific files
+SRC += matrix.c
+SRC += board.c
+QUANTUM_LIB_SRC += i2c_master.c

+ 397 - 0
keyboards/chidori/usbconfig.h

@@ -0,0 +1,397 @@
+/* Name: usbconfig.h
+ * Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
+ * Author: Christian Starkjohann
+ * Creation Date: 2005-04-01
+ * Tabsize: 4
+ * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
+ * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
+ * This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $
+ */
+
+#ifndef __usbconfig_h_included__
+#define __usbconfig_h_included__
+
+#include "config.h"
+
+/*
+General Description:
+This file is an example configuration (with inline documentation) for the USB
+driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
+also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
+wire the lines to any other port, as long as D+ is also wired to INT0 (or any
+other hardware interrupt, as long as it is the highest level interrupt, see
+section at the end of this file).
+*/
+
+/* ---------------------------- Hardware Config ---------------------------- */
+
+#define USB_CFG_IOPORTNAME      D
+/* This is the port where the USB bus is connected. When you configure it to
+ * "B", the registers PORTB, PINB and DDRB will be used.
+ */
+#define USB_CFG_DMINUS_BIT      3
+/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
+ * This may be any bit in the port.
+ */
+#define USB_CFG_DPLUS_BIT       2
+/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
+ * This may be any bit in the port. Please note that D+ must also be connected
+ * to interrupt pin INT0! [You can also use other interrupts, see section
+ * "Optional MCU Description" below, or you can connect D- to the interrupt, as
+ * it is required if you use the USB_COUNT_SOF feature. If you use D- for the
+ * interrupt, the USB interrupt will also be triggered at Start-Of-Frame
+ * markers every millisecond.]
+ */
+#define USB_CFG_CLOCK_KHZ       (F_CPU/1000)
+/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
+ * 16500, 18000 and 20000. The 12.8 MHz and 16.5 MHz versions of the code
+ * require no crystal, they tolerate +/- 1% deviation from the nominal
+ * frequency. All other rates require a precision of 2000 ppm and thus a
+ * crystal!
+ * Since F_CPU should be defined to your actual clock rate anyway, you should
+ * not need to modify this setting.
+ */
+#define USB_CFG_CHECK_CRC       0
+/* Define this to 1 if you want that the driver checks integrity of incoming
+ * data packets (CRC checks). CRC checks cost quite a bit of code size and are
+ * currently only available for 18 MHz crystal clock. You must choose
+ * USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
+ */
+
+/* ----------------------- Optional Hardware Config ------------------------ */
+
+/* #define USB_CFG_PULLUP_IOPORTNAME   D */
+/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
+ * V+, you can connect and disconnect the device from firmware by calling
+ * the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
+ * This constant defines the port on which the pullup resistor is connected.
+ */
+/* #define USB_CFG_PULLUP_BIT          4 */
+/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
+ * above) where the 1.5k pullup resistor is connected. See description
+ * above for details.
+ */
+
+/* --------------------------- Functional Range ---------------------------- */
+
+#define USB_CFG_HAVE_INTRIN_ENDPOINT    1
+/* Define this to 1 if you want to compile a version with two endpoints: The
+ * default control endpoint 0 and an interrupt-in endpoint (any other endpoint
+ * number).
+ */
+#define USB_CFG_HAVE_INTRIN_ENDPOINT3   1
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 3 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP3_NUMBER              3
+/* If the so-called endpoint 3 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 3.
+ */
+/* #define USB_INITIAL_DATATOKEN           USBPID_DATA1 */
+/* The above macro defines the startup condition for data toggling on the
+ * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
+ * Since the token is toggled BEFORE sending any data, the first packet is
+ * sent with the oposite value of this configuration!
+ */
+#define USB_CFG_IMPLEMENT_HALT          0
+/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
+ * for endpoint 1 (interrupt endpoint). Although you may not need this feature,
+ * it is required by the standard. We have made it a config option because it
+ * bloats the code considerably.
+ */
+#define USB_CFG_SUPPRESS_INTR_CODE      0
+/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
+ * want to send any data over them. If this macro is defined to 1, functions
+ * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
+ * you need the interrupt-in endpoints in order to comply to an interface
+ * (e.g. HID), but never want to send any data. This option saves a couple
+ * of bytes in flash memory and the transmit buffers in RAM.
+ */
+#define USB_CFG_INTR_POLL_INTERVAL      1
+/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
+ * interval. The value is in milliseconds and must not be less than 10 ms for
+ * low speed devices.
+ */
+#define USB_CFG_IS_SELF_POWERED         0
+/* Define this to 1 if the device has its own power supply. Set it to 0 if the
+ * device is powered from the USB bus.
+ */
+// max power draw with maxed white underglow measured at 120 mA (peaks)
+#define USB_CFG_MAX_BUS_POWER           100
+/* Set this variable to the maximum USB bus power consumption of your device.
+ * The value is in milliamperes. [It will be divided by two since USB
+ * communicates power requirements in units of 2 mA.]
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITE      1
+/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
+ * transfers. Set it to 0 if you don't need it and want to save a couple of
+ * bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_READ       0
+/* Set this to 1 if you need to send control replies which are generated
+ * "on the fly" when usbFunctionRead() is called. If you only want to send
+ * data from a static buffer, set it to 0 and return the data from
+ * usbFunctionSetup(). This saves a couple of bytes.
+ */
+#define USB_CFG_IMPLEMENT_FN_WRITEOUT   0
+/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
+ * You must implement the function usbFunctionWriteOut() which receives all
+ * interrupt/bulk data sent to any endpoint other than 0. The endpoint number
+ * can be found in 'usbRxToken'.
+ */
+#define USB_CFG_HAVE_FLOWCONTROL        0
+/* Define this to 1 if you want flowcontrol over USB data. See the definition
+ * of the macros usbDisableAllRequests() and usbEnableAllRequests() in
+ * usbdrv.h.
+ */
+#define USB_CFG_DRIVER_FLASH_PAGE       0
+/* If the device has more than 64 kBytes of flash, define this to the 64 k page
+ * where the driver's constants (descriptors) are located. Or in other words:
+ * Define this to 1 for boot loaders on the ATMega128.
+ */
+#define USB_CFG_LONG_TRANSFERS          0
+/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
+ * in a single control-in or control-out transfer. Note that the capability
+ * for long transfers increases the driver size.
+ */
+/* #define USB_RX_USER_HOOK(data, len)     if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
+/* This macro is a hook if you want to do unconventional things. If it is
+ * defined, it's inserted at the beginning of received message processing.
+ * If you eat the received message and don't want default processing to
+ * proceed, do a return after doing your things. One possible application
+ * (besides debugging) is to flash a status LED on each packet.
+ */
+/* #define USB_RESET_HOOK(resetStarts)     if(!resetStarts){hadUsbReset();} */
+/* This macro is a hook if you need to know when an USB RESET occurs. It has
+ * one parameter which distinguishes between the start of RESET state and its
+ * end.
+ */
+/* #define USB_SET_ADDRESS_HOOK()              hadAddressAssigned(); */
+/* This macro (if defined) is executed when a USB SET_ADDRESS request was
+ * received.
+ */
+#define USB_COUNT_SOF                   0
+/* define this macro to 1 if you need the global variable "usbSofCount" which
+ * counts SOF packets. This feature requires that the hardware interrupt is
+ * connected to D- instead of D+.
+ */
+/* #ifdef __ASSEMBLER__
+ * macro myAssemblerMacro
+ *     in      YL, TCNT0
+ *     sts     timer0Snapshot, YL
+ *     endm
+ * #endif
+ * #define USB_SOF_HOOK                    myAssemblerMacro
+ * This macro (if defined) is executed in the assembler module when a
+ * Start Of Frame condition is detected. It is recommended to define it to
+ * the name of an assembler macro which is defined here as well so that more
+ * than one assembler instruction can be used. The macro may use the register
+ * YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
+ * immediately after an SOF pulse may be lost and must be retried by the host.
+ * What can you do with this hook? Since the SOF signal occurs exactly every
+ * 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
+ * designs running on the internal RC oscillator.
+ * Please note that Start Of Frame detection works only if D- is wired to the
+ * interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
+ */
+#define USB_CFG_CHECK_DATA_TOGGLING     0
+/* define this macro to 1 if you want to filter out duplicate data packets
+ * sent by the host. Duplicates occur only as a consequence of communication
+ * errors, when the host does not receive an ACK. Please note that you need to
+ * implement the filtering yourself in usbFunctionWriteOut() and
+ * usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
+ * for each control- and out-endpoint to check for duplicate packets.
+ */
+#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH   0
+/* define this macro to 1 if you want the function usbMeasureFrameLength()
+ * compiled in. This function can be used to calibrate the AVR's RC oscillator.
+ */
+#define USB_USE_FAST_CRC                0
+/* The assembler module has two implementations for the CRC algorithm. One is
+ * faster, the other is smaller. This CRC routine is only used for transmitted
+ * messages where timing is not critical. The faster routine needs 31 cycles
+ * per byte while the smaller one needs 61 to 69 cycles. The faster routine
+ * may be worth the 32 bytes bigger code size if you transmit lots of data and
+ * run the AVR close to its limit.
+ */
+
+/* -------------------------- Device Description --------------------------- */
+
+#define USB_CFG_VENDOR_ID       (VENDOR_ID & 0xED), ((VENDOR_ID >> 8) & 0xFE)
+/* USB vendor ID for the device, low byte first. If you have registered your
+ * own Vendor ID, define it here. Otherwise you may use one of obdev's free
+ * shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc.  Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_ID       (PRODUCT_ID & 0x00), ((PRODUCT_ID >> 8) & 0x00)
+/* This is the ID of the product, low byte first. It is interpreted in the
+ * scope of the vendor ID. If you have registered your own VID with usb.org
+ * or if you have licensed a PID from somebody else, define it here. Otherwise
+ * you may use one of obdev's free shared VID/PID pairs. See the file
+ * USB-IDs-for-free.txt for details!
+ * *** IMPORTANT NOTE ***
+ * This template uses obdev's shared VID/PID pair for Vendor Class devices
+ * with libusb: 0x16c0/0x5dc.  Use this VID/PID pair ONLY if you understand
+ * the implications!
+ */
+#define USB_CFG_DEVICE_VERSION  0x00, 0x01
+/* Version number of the device: Minor number first, then major number.
+ */
+#define USB_CFG_VENDOR_NAME     'k','a','g','i','z','a','r','a','y','a'
+#define USB_CFG_VENDOR_NAME_LEN 10
+/* These two values define the vendor name returned by the USB device. The name
+ * must be given as a list of characters under single quotes. The characters
+ * are interpreted as Unicode (UTF-16) entities.
+ * If you don't want a vendor name string, undefine these macros.
+ * ALWAYS define a vendor name containing your Internet domain name if you use
+ * obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for
+ * details.
+ */
+#define USB_CFG_DEVICE_NAME     'C', 'h', 'i', 'd', 'o', 'r', 'i'
+#define USB_CFG_DEVICE_NAME_LEN 7
+/* Same as above for the device name. If you don't want a device name, undefine
+ * the macros. See the file USB-IDs-for-free.txt before you assign a name if
+ * you use a shared VID/PID.
+ */
+//#define USB_CFG_SERIAL_NUMBER   'd','m','9','r','e','c','o','r','d','s','.','c','o','m',':','p','1'
+//#define USB_CFG_SERIAL_NUMBER_LEN   17
+/* Same as above for the serial number. If you don't want a serial number,
+ * undefine the macros.
+ * It may be useful to provide the serial number through other means than at
+ * compile time. See the section about descriptor properties below for how
+ * to fine tune control over USB descriptors such as the string descriptor
+ * for the serial number.
+ */
+#define USB_CFG_DEVICE_CLASS        0
+#define USB_CFG_DEVICE_SUBCLASS     0
+/* See USB specification if you want to conform to an existing device class.
+ * Class 0xff is "vendor specific".
+ */
+#define USB_CFG_INTERFACE_CLASS     3   /* HID */
+#define USB_CFG_INTERFACE_SUBCLASS  1   /* Boot */
+#define USB_CFG_INTERFACE_PROTOCOL  1   /* Keyboard */
+/* See USB specification if you want to conform to an existing device class or
+ * protocol. The following classes must be set at interface level:
+ * HID class is 3, no subclass and protocol required (but may be useful!)
+ * CDC class is 2, use subclass 2 and protocol 1 for ACM
+ */
+#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH    0
+/* Define this to the length of the HID report descriptor, if you implement
+ * an HID device. Otherwise don't define it or define it to 0.
+ * If you use this define, you must add a PROGMEM character array named
+ * "usbHidReportDescriptor" to your code which contains the report descriptor.
+ * Don't forget to keep the array and this define in sync!
+ */
+
+/* #define USB_PUBLIC static */
+/* Use the define above if you #include usbdrv.c instead of linking against it.
+ * This technique saves a couple of bytes in flash memory.
+ */
+
+/* ------------------- Fine Control over USB Descriptors ------------------- */
+/* If you don't want to use the driver's default USB descriptors, you can
+ * provide our own. These can be provided as (1) fixed length static data in
+ * flash memory, (2) fixed length static data in RAM or (3) dynamically at
+ * runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
+ * information about this function.
+ * Descriptor handling is configured through the descriptor's properties. If
+ * no properties are defined or if they are 0, the default descriptor is used.
+ * Possible properties are:
+ *   + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
+ *     at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
+ *     used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
+ *     you want RAM pointers.
+ *   + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
+ *     in static memory is in RAM, not in flash memory.
+ *   + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
+ *     the driver must know the descriptor's length. The descriptor itself is
+ *     found at the address of a well known identifier (see below).
+ * List of static descriptor names (must be declared PROGMEM if in flash):
+ *   char usbDescriptorDevice[];
+ *   char usbDescriptorConfiguration[];
+ *   char usbDescriptorHidReport[];
+ *   char usbDescriptorString0[];
+ *   int usbDescriptorStringVendor[];
+ *   int usbDescriptorStringDevice[];
+ *   int usbDescriptorStringSerialNumber[];
+ * Other descriptors can't be provided statically, they must be provided
+ * dynamically at runtime.
+ *
+ * Descriptor properties are or-ed or added together, e.g.:
+ * #define USB_CFG_DESCR_PROPS_DEVICE   (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
+ *
+ * The following descriptors are defined:
+ *   USB_CFG_DESCR_PROPS_DEVICE
+ *   USB_CFG_DESCR_PROPS_CONFIGURATION
+ *   USB_CFG_DESCR_PROPS_STRINGS
+ *   USB_CFG_DESCR_PROPS_STRING_0
+ *   USB_CFG_DESCR_PROPS_STRING_VENDOR
+ *   USB_CFG_DESCR_PROPS_STRING_PRODUCT
+ *   USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
+ *   USB_CFG_DESCR_PROPS_HID
+ *   USB_CFG_DESCR_PROPS_HID_REPORT
+ *   USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
+ *
+ * Note about string descriptors: String descriptors are not just strings, they
+ * are Unicode strings prefixed with a 2 byte header. Example:
+ * int  serialNumberDescriptor[] = {
+ *     USB_STRING_DESCRIPTOR_HEADER(6),
+ *     'S', 'e', 'r', 'i', 'a', 'l'
+ * };
+ */
+
+#define USB_CFG_DESCR_PROPS_DEVICE                  0
+#define USB_CFG_DESCR_PROPS_CONFIGURATION           USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_CONFIGURATION           0
+#define USB_CFG_DESCR_PROPS_STRINGS                 0
+#define USB_CFG_DESCR_PROPS_STRING_0                0
+#define USB_CFG_DESCR_PROPS_STRING_VENDOR           0
+#define USB_CFG_DESCR_PROPS_STRING_PRODUCT          0
+#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER    0
+#define USB_CFG_DESCR_PROPS_HID                     USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_HID                     0
+#define USB_CFG_DESCR_PROPS_HID_REPORT              USB_PROP_IS_DYNAMIC
+//#define USB_CFG_DESCR_PROPS_HID_REPORT              0
+#define USB_CFG_DESCR_PROPS_UNKNOWN                 0
+
+#define usbMsgPtr_t unsigned short
+/* If usbMsgPtr_t is not defined, it defaults to 'uchar *'. We define it to
+ * a scalar type here because gcc generates slightly shorter code for scalar
+ * arithmetics than for pointer arithmetics. Remove this define for backward
+ * type compatibility or define it to an 8 bit type if you use data in RAM only
+ * and all RAM is below 256 bytes (tiny memory model in IAR CC).
+ */
+
+/* ----------------------- Optional MCU Description ------------------------ */
+
+/* The following configurations have working defaults in usbdrv.h. You
+ * usually don't need to set them explicitly. Only if you want to run
+ * the driver on a device which is not yet supported or with a compiler
+ * which is not fully supported (such as IAR C) or if you use a differnt
+ * interrupt than INT0, you may have to define some of these.
+ */
+/* #define USB_INTR_CFG            MCUCR */
+/* #define USB_INTR_CFG_SET        ((1 << ISC00) | (1 << ISC01)) */
+/* #define USB_INTR_CFG_CLR        0 */
+/* #define USB_INTR_ENABLE         GIMSK */
+/* #define USB_INTR_ENABLE_BIT     INT0 */
+/* #define USB_INTR_PENDING        GIFR */
+/* #define USB_INTR_PENDING_BIT    INTF0 */
+/* #define USB_INTR_VECTOR         INT0_vect */
+
+/* Set INT1 for D- falling edge to count SOF */
+/* #define USB_INTR_CFG            EICRA */
+// #define USB_INTR_CFG_SET        ((1 << ISC11) | (0 << ISC10))
+// /* #define USB_INTR_CFG_CLR        0 */
+// /* #define USB_INTR_ENABLE         EIMSK */
+// #define USB_INTR_ENABLE_BIT     INT1
+// /* #define USB_INTR_PENDING        EIFR */
+// #define USB_INTR_PENDING_BIT    INTF1
+// #define USB_INTR_VECTOR         INT1_vect
+
+#endif /* __usbconfig_h_included__ */