summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--keyboards/mt40/config.h207
-rw-r--r--keyboards/mt40/i2c.c104
-rw-r--r--keyboards/mt40/i2c.h25
-rw-r--r--keyboards/mt40/keymaps/default/keymap.c84
-rw-r--r--keyboards/mt40/keymaps/default/readme.md17
-rw-r--r--keyboards/mt40/matrix.c106
-rw-r--r--keyboards/mt40/mt40.c43
-rw-r--r--keyboards/mt40/mt40.h87
-rwxr-xr-xkeyboards/mt40/program74
-rw-r--r--keyboards/mt40/readme.md16
-rw-r--r--keyboards/mt40/rules.mk36
-rw-r--r--keyboards/mt40/usbconfig.h396
12 files changed, 1195 insertions, 0 deletions
diff --git a/keyboards/mt40/config.h b/keyboards/mt40/config.h
new file mode 100644
index 0000000000..394cc78981
--- /dev/null
+++ b/keyboards/mt40/config.h
@@ -0,0 +1,207 @@
+/*
+Copyright 2017 REPLACE_WITH_YOUR_NAME
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID 0x20A0
+#define PRODUCT_ID 0x422D
+
+#define DEVICE_VER 0x0001
+
+#define MANUFACTURER ThomasDehaeze
+#define PRODUCT mt40
+
+#define DESCRIPTION A Planck clone
+
+/* key matrix size */
+#define MATRIX_ROWS 8
+#define MATRIX_COLS 15
+
+#define RGB_DI_PIN C0
+#define RGBLED_NUM 12
+#define RGBLIGHT_ANIMATIONS
+
+#define RGBLIGHT_HUE_STEP 12
+#define RGBLIGHT_SAT_STEP 15
+#define RGBLIGHT_VAL_STEP 18
+
+#define NO_UART 1
+#define BOOTLOADHID_BOOTLOADER 1
+
+#define TAPPING_TERM 200
+
+/*
+ * 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 CC6 0x63 // C3 */
+/* #define CB6 0x37 // B7 */
+/* #define CC7 0x62 // C2 */
+
+#define MATRIX_ROW_PINS { B0, B1, B2, B3, B4, B5, B6, B7 }
+#define MATRIX_COL_PINS { A0, A1, A2, A3, A4, A5, A6, A7, C2, C3, C4, C5, C6, C7, D7 }
+/* #define UNUSED_PINS */
+
+/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
+/* #define DIODE_DIRECTION COL2ROW */
+
+#define BACKLIGHT_PIN D2
+
+/* number of backlight levels */
+#define BACKLIGHT_LEVELS 3
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+/* #define DEBOUNCING_DELAY 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 */
+#define IS_COMMAND() (keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)))
+
+/* 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_HELP1 H
+//#define MAGIC_KEY_HELP2 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_ALT1 ESC
+//#define MAGIC_KEY_LAYER0_ALT2 GRAVE
+//#define MAGIC_KEY_LAYER0 0
+//#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 PAUSE
+//#define MAGIC_KEY_LOCK CAPS
+//#define MAGIC_KEY_EEPROM E
+//#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
+
+#endif
diff --git a/keyboards/mt40/i2c.c b/keyboards/mt40/i2c.c
new file mode 100644
index 0000000000..c27f3e3d17
--- /dev/null
+++ b/keyboards/mt40/i2c.c
@@ -0,0 +1,104 @@
+/*
+Copyright 2016 Luiz Ribeiro <luizribeiro@gmail.com>
+
+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 <avr/io.h>
+#include <util/twi.h>
+
+#include "i2c.h"
+
+void i2c_set_bitrate(uint16_t bitrate_khz) {
+ uint8_t bitrate_div = ((F_CPU / 1000l) / bitrate_khz);
+ if (bitrate_div >= 16) {
+ bitrate_div = (bitrate_div - 16) / 2;
+ }
+ TWBR = bitrate_div;
+}
+
+void i2c_init(void) {
+ // set pull-up resistors on I2C bus pins
+ PORTC |= 0b11;
+
+ i2c_set_bitrate(400);
+
+ // enable TWI (two-wire interface)
+ TWCR |= (1 << TWEN);
+
+ // enable TWI interrupt and slave address ACK
+ TWCR |= (1 << TWIE);
+ TWCR |= (1 << TWEA);
+}
+
+uint8_t i2c_start(uint8_t address) {
+ // reset TWI control register
+ TWCR = 0;
+
+ // begin transmission and wait for it to end
+ TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
+ while (!(TWCR & (1<<TWINT)));
+
+ // check if the start condition was successfully transmitted
+ if ((TWSR & 0xF8) != TW_START) {
+ return 1;
+ }
+
+ // transmit address and wait
+ TWDR = address;
+ TWCR = (1<<TWINT) | (1<<TWEN);
+ while (!(TWCR & (1<<TWINT)));
+
+ // check if the device has acknowledged the READ / WRITE mode
+ uint8_t twst = TW_STATUS & 0xF8;
+ if ((twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+void i2c_stop(void) {
+ TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
+}
+
+uint8_t i2c_write(uint8_t data) {
+ TWDR = data;
+
+ // transmit data and wait
+ TWCR = (1<<TWINT) | (1<<TWEN);
+ while (!(TWCR & (1<<TWINT)));
+
+ if ((TWSR & 0xF8) != TW_MT_DATA_ACK) {
+ return 1;
+ }
+
+ return 0;
+}
+
+uint8_t i2c_send(uint8_t address, uint8_t *data, uint16_t length) {
+ if (i2c_start(address)) {
+ return 1;
+ }
+
+ for (uint16_t i = 0; i < length; i++) {
+ if (i2c_write(data[i])) {
+ return 1;
+ }
+ }
+
+ i2c_stop();
+
+ return 0;
+}
diff --git a/keyboards/mt40/i2c.h b/keyboards/mt40/i2c.h
new file mode 100644
index 0000000000..27c9d3d050
--- /dev/null
+++ b/keyboards/mt40/i2c.h
@@ -0,0 +1,25 @@
+/*
+Copyright 2016 Luiz Ribeiro <luizribeiro@gmail.com>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __I2C_H__
+#define __I2C_H__
+
+void i2c_init(void);
+void i2c_set_bitrate(uint16_t bitrate_khz);
+uint8_t i2c_send(uint8_t address, uint8_t *data, uint16_t length);
+
+#endif
diff --git a/keyboards/mt40/keymaps/default/keymap.c b/keyboards/mt40/keymaps/default/keymap.c
new file mode 100644
index 0000000000..2da5dd6458
--- /dev/null
+++ b/keyboards/mt40/keymaps/default/keymap.c
@@ -0,0 +1,84 @@
+/* Copyright 2017 REPLACE_WITH_YOUR_NAME
+ *
+ * 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 "mt40.h"
+#include "action_layer.h"
+#include "rgblight.h"
+
+#define _______ KC_TRNS
+#define OOOOOOO KC_TRNS
+
+#define C_LCTL MT(MOD_LCTL, KC_QUOT)
+#define C_RCTL MT(MOD_RCTL, KC_GRV)
+
+#define C_LGUI MT(MOD_LGUI, KC_LBRC)
+#define C_RGUI MT(MOD_RGUI, KC_RBRC)
+
+#define C_ESC MT(MOD_LCTL, KC_ESC)
+#define C_ENT MT(MOD_RCTL, KC_ENT)
+
+
+/*
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab | Q | W | E | R | T | Y | U | I | O | P | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Esc | A | S | D | F | G | H | J | K | L | ; | " |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Brite| Ctrl | Alt | GUI |Lower | SPC | BSP |Raise | Left | Down | Up |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+ [0] = KEYMAP(
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
+ C_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, C_ENT, \
+ KC_LSPO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSPC, \
+ C_LCTL, C_LGUI, MOD_LALT, MO(3), MO(1), KC_SPC, KC_SPC, MO(2), MO(4), MOD_RALT, C_RGUI, C_RCTL),
+
+ [1] = KEYMAP(
+ _______, KC_F9, KC_F10, KC_F11, KC_F12, RGB_TOG, RGB_MOD, KC_P7, KC_P8, KC_P9, KC_PSLS, _______, \
+ _______, KC_F5, KC_F6, KC_F7, KC_F8, RGB_VAD, RGB_VAI, KC_P4, KC_P5, KC_P6, KC_PAST, _______, \
+ _______, KC_F1, KC_F2, KC_F3, KC_F4, BL_TOGG, BL_INC, KC_P1, KC_P2, KC_P3, KC_PMNS, KC_PGUP, \
+ _______, _______, _______, _______, OOOOOOO, _______, _______, KC_P0, KC_PDOT, KC_PENT, KC_PPLS, KC_PGDN),
+
+ [2] = KEYMAP(
+ _______, _______, _______, _______, _______, _______, _______, KC_QUOT, KC_EQL, KC_LBRC, KC_RBRC, KC_NUBS, \
+ KC_GRAVE, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, \
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, OOOOOOO, KC_HOME, KC_PGDOWN, KC_PGUP, KC_END),
+
+ [3] = KEYMAP(
+ _______, _______, _______, _______, _______, _______, KC_COPY, KC_PGUP, _______, _______, KC_PASTE, KC_DEL, \
+ _______, _______, _______, KC_PGDN, _______, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, _______, _______, \
+ _______, _______, KC_CUT, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
+ _______, _______, _______, OOOOOOO, _______, _______, _______, _______, _______, _______, _______, _______),
+
+ [4] = KEYMAP(
+ _______, _______, _______, _______, _______, _______, _______, KC_ACL0, KC_ACL1, KC_ACL2, _______, _______, \
+ KC_PSCR, KC_INS, KC_MUTE, KC_VOLD, KC_VOLU, _______, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, _______, _______, \
+ KC_CAPS, _______, KC_MPLY, KC_MRWD, KC_MFFD, _______, _______, _______, KC_BTN1, KC_BTN2, _______, _______, \
+ _______, _______, _______, _______, _______, _______, _______, _______, OOOOOOO, _______, _______, _______),
+
+
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+ [0] = ACTION_LAYER_MOMENTARY(1),
+ [1] = ACTION_LAYER_MOMENTARY(2),
+ [2] = ACTION_LAYER_MOMENTARY(3),
+ [3] = ACTION_LAYER_MOMENTARY(4),
+};
+
diff --git a/keyboards/mt40/keymaps/default/readme.md b/keyboards/mt40/keymaps/default/readme.md
new file mode 100644
index 0000000000..033b75fa29
--- /dev/null
+++ b/keyboards/mt40/keymaps/default/readme.md
@@ -0,0 +1,17 @@
+# Default Layout on a Planck Clone Keyboard
+
+## Base Layer
+[Imgur](https://i.imgur.com/XivfDS0.png)
+
+## FN1 Layer - Numpad and Function keys
+[Imgur](https://i.imgur.com/sXTYfAn.png)
+
+## FN2 Layer - Numbers and Symbols
+[Imgur](https://i.imgur.com/Z4Nqp7g.png)
+
+## FN3 Layer - Vim
+[Imgur](https://i.imgur.com/5whRGOx.png)
+
+## FN3 Layer - Multimedia
+[Imgur](https://i.imgur.com/K0jfHIO.png)
+
diff --git a/keyboards/mt40/matrix.c b/keyboards/mt40/matrix.c
new file mode 100644
index 0000000000..140026013f
--- /dev/null
+++ b/keyboards/mt40/matrix.c
@@ -0,0 +1,106 @@
+/*
+Copyright 2017 Luiz Ribeiro <luizribeiro@gmail.com>
+
+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 <avr/io.h>
+#include <util/delay.h>
+
+#include "matrix.h"
+
+#ifndef DEBOUNCE
+# define DEBOUNCE 5
+#endif
+
+static uint8_t debouncing = DEBOUNCE;
+
+static matrix_row_t matrix[MATRIX_ROWS];
+static matrix_row_t matrix_debouncing[MATRIX_ROWS];
+
+void matrix_init(void) {
+ // all outputs for rows high
+ DDRB = 0xFF;
+ PORTB = 0xFF;
+ // all inputs for columns
+ DDRA = 0x00;
+ DDRC &= ~(0x111111<<2);
+ DDRD &= ~(1<<PIND7);
+ // all columns are pulled-up
+ PORTA = 0xFF;
+ PORTC |= (0b111111<<2);
+ PORTD |= (1<<PIND7);
+
+ // initialize matrix state: all keys off
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ matrix[row] = 0x00;
+ matrix_debouncing[row] = 0x00;
+ }
+}
+
+void matrix_set_row_status(uint8_t row) {
+ DDRB = (1 << row);
+ PORTB = ~(1 << row);
+}
+
+uint8_t bit_reverse(uint8_t x) {
+ x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
+ x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
+ x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
+ return x;
+}
+
+uint8_t matrix_scan(void) {
+ for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
+ matrix_set_row_status(row);
+ _delay_us(5);
+
+ matrix_row_t cols = (
+ // cols 0..7, PORTA 0 -> 7
+ (~PINA) & 0xFF
+ ) | (
+ // cols 8..13, PORTC 7 -> 0
+ bit_reverse((~PINC) & 0xFF) << 8
+ ) | (
+ // col 14, PORTD 7
+ ((~PIND) & (1 << PIND7)) << 7
+ );
+
+ if (matrix_debouncing[row] != cols) {
+ matrix_debouncing[row] = cols;
+ debouncing = DEBOUNCE;
+ }
+ }
+
+ if (debouncing) {
+ if (--debouncing) {
+ _delay_ms(1);
+ } else {
+ for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
+ matrix[i] = matrix_debouncing[i];
+ }
+ }
+ }
+
+ matrix_scan_user();
+
+ return 1;
+}
+
+inline matrix_row_t matrix_get_row(uint8_t row) {
+ return matrix[row];
+}
+
+void matrix_print(void) {
+}
diff --git a/keyboards/mt40/mt40.c b/keyboards/mt40/mt40.c
new file mode 100644
index 0000000000..0e7a30d99f
--- /dev/null
+++ b/keyboards/mt40/mt40.c
@@ -0,0 +1,43 @@
+/* Copyright 2017 REPLACE_WITH_YOUR_NAME
+ *
+ * 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 "mt40.h"
+#include "rgblight.h"
+
+#include <avr/pgmspace.h>
+
+#include "action_layer.h"
+#include "i2c.h"
+#include "quantum.h"
+
+extern rgblight_config_t rgblight_config;
+
+void rgblight_set(void) {
+ if (!rgblight_config.enable) {
+ for (uint8_t i = 0; i < RGBLED_NUM; i++) {
+ led[i].r = 0;
+ led[i].g = 0;
+ led[i].b = 0;
+ }
+ }
+
+ i2c_init();
+ i2c_send(0xb0, (uint8_t*)led, 3 * RGBLED_NUM);
+}
+
+__attribute__ ((weak))
+void matrix_scan_user(void) {
+ rgblight_task();
+}
diff --git a/keyboards/mt40/mt40.h b/keyboards/mt40/mt40.h
new file mode 100644
index 0000000000..18cefd827b
--- /dev/null
+++ b/keyboards/mt40/mt40.h
@@ -0,0 +1,87 @@
+/* Copyright 2017 REPLACE_WITH_YOUR_NAME
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef MT40_H
+#define MT40_H
+
+#include "quantum_keycodes.h"
+#include "keycode.h"
+#include "action.h"
+
+// This a shortcut to help you visually see your layout.
+// The following is an example using the Planck MIT layout
+// The first section contains all of the arguments
+// The second converts the arguments into a two-dimensional array
+#define KEYMAP( \
+ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, \
+ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \
+ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, \
+ K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B \
+) { \
+ { K31, K32, K33, KC_NO, K34, K35, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, K37, KC_NO, KC_NO, KC_NO }, \
+ { K20, K21, K22, K23, K24, K25, KC_NO, KC_NO, KC_NO, KC_NO, K2A, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { K30, K11, K12, K13, K14, K15, KC_NO, KC_NO, KC_NO, KC_NO, K1A, K1B, KC_NO, KC_NO, KC_NO }, \
+ { K10, K01, K02, K03, K04, K05, KC_NO, KC_NO, KC_NO, KC_NO, K0A, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { K00, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, K0B }, \
+ { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO }, \
+ { KC_NO, KC_NO, K06, K16, K26, K36, K38, K3A, K39, K3B, KC_NO, KC_NO, K07, K17, K27 }, \
+ { KC_NO, KC_NO, K09, K19, K29, KC_NO, K2B, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, K08, K18, K28 } \
+}
+
+/* #define KC_KEYMAP( \ */
+/* k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, \ */
+/* k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, \ */
+/* k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, \ */
+/* k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b \ */
+/* ) \ */
+/* { \ */
+/* { KC_##k31, KC_##k32, KC_##k33, KC_NO, KC_##k34, KC_##k35, KC_NO, KC_NO, KC_NO, KC_NO, KC_##k37, KC_NO, KC_NO, KC_NO, KC_NO }, \ */
+/* { KC_##k20, KC_##k21, KC_##k22, KC_##k23, KC_##k24, KC_##k25, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_##k2a, KC_NO, KC_NO, KC_NO }, \ */
+/* { KC_##k30, KC_##k11, KC_##k12, KC_##k13, KC_##k14, KC_##k15, KC_NO, KC_NO, KC_NO, KC_NO, KC_##k1b, KC_##k1a, KC_NO, KC_NO, KC_NO }, \ */
+/* { KC_##k10, KC_##k01, KC_##k02, KC_##k03, KC_##k04, KC_##k05, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_##k0a, KC_NO, KC_NO, KC_NO }, \ */
+/* { KC_##k00, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_##k0b }, \ */
+/* { KC_NO, KC_NO, KC_##k06, KC_##k16, KC_##k26, KC_##k36, KC_##k38, KC_##k3a, KC_##k17, KC_##k07, KC_NO, KC_NO, KC_##k3b, KC_##k39, KC_##k27 } \ */
+/* { KC_NO, KC_NO, KC_##k09, KC_##k19, KC_##k29, KC_NO, KC_NO, KC_##k2b, KC_##k18, KC_##k08, KC_NO, KC_NO, KC_NO, KC_NO, KC_##k28 } \ */
+/* } */
+
+/* #define FR_A KC_A */
+/* #define FR_B KC_B */
+/* #define FR_C KC_C */
+/* #define FR_D KC_D */
+/* #define FR_E KC_E */
+/* #define FR_F KC_F */
+/* #define FR_G KC_G */
+/* #define FR_H KC_H */
+/* #define FR_I KC_I */
+/* #define FR_J KC_J */
+/* #define FR_K KC_K */
+/* #define FR_L KC_L */
+/* #define FR_M KC_M */
+/* #define FR_N KC_N */
+/* #define FR_O KC_O */
+/* #define FR_P KC_P */
+/* #define FR_Q KC_Q */
+/* #define FR_R KC_R */
+/* #define FR_S KC_S */
+/* #define FR_T KC_T */
+/* #define FR_U KC_U */
+/* #define FR_V KC_V */
+/* #define FR_W KC_W */
+/* #define FR_X KC_X */
+/* #define FR_Y KC_Y */
+/* #define FR_Z KC_Z */
+
+
+#endif
diff --git a/keyboards/mt40/program b/keyboards/mt40/program
new file mode 100755
index 0000000000..e8786f566d
--- /dev/null
+++ b/keyboards/mt40/program
@@ -0,0 +1,74 @@
+#!/usr/bin/env python2.7
+# Copyright 2017 Luiz Ribeiro <luizribeiro@gmail.com>
+#
+# 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/>.
+
+from __future__ import print_function
+
+import os
+import sys
+import time
+import usb
+
+if len(sys.argv) < 2:
+ print('Usage: %s <firmware.hex>' % sys.argv[0])
+ sys.exit(1)
+
+print('Searching for planck clone keyboard... ', end='')
+
+dev = usb.core.find(idVendor=0x20A0, idProduct=0x422D)
+if dev is None:
+ raise ValueError('Device not found')
+
+print('Found', end='\n\n')
+
+print('Device Information:')
+print(' idVendor: %d (0x%04x)' % (dev.idVendor, dev.idVendor))
+print(' idProduct: %d (0x%04x)' % (dev.idProduct, dev.idProduct))
+print('Manufacturer: %s' % (dev.iManufacturer))
+print('Serial: %s' % (dev.iSerialNumber))
+print('Product: %s' % (dev.iProduct), end='\n\n')
+
+print('Transferring control to bootloader... ', end='')
+
+dev.set_configuration()
+
+request_type = usb.util.build_request_type(
+ usb.util.CTRL_OUT,
+ usb.util.CTRL_TYPE_CLASS,
+ usb.util.CTRL_RECIPIENT_DEVICE)
+
+USBRQ_HID_SET_REPORT = 0x09
+HID_REPORT_OPTION = 0x0301
+
+
+try:
+ dev.ctrl_transfer(
+ request_type,
+ USBRQ_HID_SET_REPORT,
+ HID_REPORT_OPTION,
+ 0,
+ [0, 0, 0xFF] + [0] * 5
+ )
+except usb.core.USBError:
+ # for some reason I keep getting USBError, but it works!
+ pass
+
+# wait a bit until bootloader starts up
+time.sleep(2)
+
+print('OK')
+print('Programming...')
+if os.system('bootloadHID -r "%s"' % sys.argv[1]) == 0:
+ print('\nDone!')
diff --git a/keyboards/mt40/readme.md b/keyboards/mt40/readme.md
new file mode 100644
index 0000000000..aba5fa0d0c
--- /dev/null
+++ b/keyboards/mt40/readme.md
@@ -0,0 +1,16 @@
+# MT40: An 40% Ortholinear Keyboard
+
+## Program
+
+`make mt40:default:program`
+
+## Pictures
+
+[PCB](https://i.imgur.com/8BeeY07.jpg)
+[Backview of the PCB](https://i.imgur.com/0opsDkt.jpg)
+[Board with Sleeve](https://i.imgur.com/44FhPU8.jpg)
+
+## Buy
+
+https://world.taobao.com/item/548335974877.htm?fromSite=main&spm=a312a.7700824.w4002-6810221593.51.670e68a08mRh69
+
diff --git a/keyboards/mt40/rules.mk b/keyboards/mt40/rules.mk
new file mode 100644
index 0000000000..10023da0ee
--- /dev/null
+++ b/keyboards/mt40/rules.mk
@@ -0,0 +1,36 @@
+# MCU name
+MCU = atmega32a
+PROTOCOL = VUSB
+
+# unsupported features for now
+NO_UART = yes
+NO_SUSPEND_POWER_DOWN = yes
+
+# processor frequency
+F_CPU = 12000000
+
+# build options
+BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE ?= no # Mouse keys(+4700)
+EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
+CONSOLE_ENABLE ?= no # Console for debug(+400)
+COMMAND_ENABLE ?= no # Commands for debug and configuration
+NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ # nkro-doesnt-work
+BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
+MIDI_ENABLE ?= no # MIDI controls
+AUDIO_ENABLE ?= no # Audio output on port C6
+UNICODE_ENABLE ?= no # Unicode
+BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
+RGBLIGHT_ENABLE ?= yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
+RGBLIGHT_CUSTOM_DRIVER = yes
+TAP_DANCE_ENABLE = no
+
+OPT_DEFS = -DDEBUG_LEVEL=0
+OPT_DEFS += -DBOOTLOADER_SIZE=2048
+
+# custom matrix setup
+CUSTOM_MATRIX = yes
+SRC = matrix.c i2c.c
+
+# programming options
+PROGRAM_CMD = ./keyboards/mt40/program $(TARGET).hex
diff --git a/keyboards/mt40/usbconfig.h b/keyboards/mt40/usbconfig.h
new file mode 100644
index 0000000000..498b01fd9e
--- /dev/null
+++ b/keyboards/mt40/usbconfig.h
@@ -0,0 +1,396 @@
+/* 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.
+ */
+/* #d