~ruther/qmk_firmware

aed18a5ff3b9eae14464aca2efb2a3ed029aea49 — ENDO Katsuhiro 5 years ago 307be48
[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.
A keyboards/chidori/board.c => keyboards/chidori/board.c +366 -0
@@ 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();
}

A keyboards/chidori/board.h => keyboards/chidori/board.h +190 -0
@@ 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);

A keyboards/chidori/chidori.c => keyboards/chidori/chidori.c +15 -0
@@ 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/>.
 */

A keyboards/chidori/chidori.h => keyboards/chidori/chidori.h +59 -0
@@ 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

A keyboards/chidori/config.h => keyboards/chidori/config.h +253 -0
@@ 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

A keyboards/chidori/info.json => keyboards/chidori/info.json +25 -0
@@ 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}
            ]
        }
    }
}

A keyboards/chidori/keymaps/default/config.h => keyboards/chidori/keymaps/default/config.h +48 -0
@@ 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 \
    }, \
}
*/

A keyboards/chidori/keymaps/default/keymap.c => keyboards/chidori/keymaps/default/keymap.c +176 -0
@@ 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);
    }
}

A keyboards/chidori/keymaps/default/readme.md => keyboards/chidori/keymaps/default/readme.md +1 -0
@@ 0,0 1,1 @@
# The default keymap for chidori

A keyboards/chidori/keymaps/extended/config.h => keyboards/chidori/keymaps/extended/config.h +59 -0
@@ 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 \
    }, \
}
*/


A keyboards/chidori/keymaps/extended/keymap.c => keyboards/chidori/keymaps/extended/keymap.c +181 -0
@@ 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);
    }
}

A keyboards/chidori/keymaps/extended/readme.md => keyboards/chidori/keymaps/extended/readme.md +1 -0
@@ 0,0 1,1 @@
# The extended keymap for chidori

A keyboards/chidori/matrix.c => keyboards/chidori/matrix.c +113 -0
@@ 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;
}

A keyboards/chidori/readme.md => keyboards/chidori/readme.md +15 -0
@@ 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).

A keyboards/chidori/rules.mk => keyboards/chidori/rules.mk +44 -0
@@ 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

A keyboards/chidori/usbconfig.h => keyboards/chidori/usbconfig.h +397 -0
@@ 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__ */