summary refs log tree commit diff
diff options
context:
space:
mode:
authorDonald <itsaferbie@gmail.com>2017-07-23 16:37:31 -0400
committerJack Humbert <jack.humb@gmail.com>2017-07-28 10:45:34 -0400
commitc71b60c82a44f6d0c32e9f08831eec564df12421 (patch)
tree024a9e1306a4f00d8f63bcbee6cc4434251c595a
parent47c6d201aa595041c2fbbd957ef880db7f2d052d (diff)
Changed case of deltasplit75 to be lowercase.
To follow convention.
-rw-r--r--keyboards/deltasplit75/Makefile5
-rw-r--r--keyboards/deltasplit75/ProtoSplit/Makefile3
-rw-r--r--keyboards/deltasplit75/ProtoSplit/ProtoSplit.c32
-rw-r--r--keyboards/deltasplit75/ProtoSplit/ProtoSplit.h37
-rw-r--r--keyboards/deltasplit75/ProtoSplit/config.h90
-rw-r--r--keyboards/deltasplit75/ProtoSplit/rules.mk5
-rw-r--r--keyboards/deltasplit75/config.h29
-rw-r--r--keyboards/deltasplit75/deltasplit build guide.pdfbin0 -> 1330145 bytes
-rw-r--r--keyboards/deltasplit75/deltasplit75.c1
-rw-r--r--keyboards/deltasplit75/deltasplit75.h13
-rw-r--r--keyboards/deltasplit75/eeprom-lefthand.eep2
-rw-r--r--keyboards/deltasplit75/eeprom-righthand.eep2
-rw-r--r--keyboards/deltasplit75/i2c.c162
-rw-r--r--keyboards/deltasplit75/i2c.h31
-rw-r--r--keyboards/deltasplit75/keymaps/Default/config.h31
-rw-r--r--keyboards/deltasplit75/keymaps/Default/keymap.c31
-rw-r--r--keyboards/deltasplit75/keymaps/ProtoSplit/config.h31
-rw-r--r--keyboards/deltasplit75/keymaps/ProtoSplit/keymap.c31
-rw-r--r--keyboards/deltasplit75/keymaps/itsaferbie/config.h62
-rw-r--r--keyboards/deltasplit75/keymaps/itsaferbie/keymap.c90
-rw-r--r--keyboards/deltasplit75/matrix.c318
-rw-r--r--keyboards/deltasplit75/pro_micro.h362
-rw-r--r--keyboards/deltasplit75/readme.md126
-rw-r--r--keyboards/deltasplit75/rules.mk87
-rw-r--r--keyboards/deltasplit75/serial.c228
-rw-r--r--keyboards/deltasplit75/serial.h26
-rw-r--r--keyboards/deltasplit75/split_util.c81
-rw-r--r--keyboards/deltasplit75/split_util.h22
-rw-r--r--keyboards/deltasplit75/v2/Makefile3
-rw-r--r--keyboards/deltasplit75/v2/config.h90
-rw-r--r--keyboards/deltasplit75/v2/rules.mk5
-rw-r--r--keyboards/deltasplit75/v2/v2.c32
-rw-r--r--keyboards/deltasplit75/v2/v2.h37
33 files changed, 2029 insertions, 76 deletions
diff --git a/keyboards/deltasplit75/Makefile b/keyboards/deltasplit75/Makefile
new file mode 100644
index 0000000000..d1dec53302
--- /dev/null
+++ b/keyboards/deltasplit75/Makefile
@@ -0,0 +1,5 @@
+SUBPROJECT_DEFAULT = v2
+
+ifndef MAKEFILE_INCLUDED
+	include ../../Makefile
+endif
diff --git a/keyboards/deltasplit75/ProtoSplit/Makefile b/keyboards/deltasplit75/ProtoSplit/Makefile
new file mode 100644
index 0000000000..4e2a6f00fd
--- /dev/null
+++ b/keyboards/deltasplit75/ProtoSplit/Makefile
@@ -0,0 +1,3 @@
+ifndef MAKEFILE_INCLUDED
+	include ../../Makefile
+endif
\ No newline at end of file
diff --git a/keyboards/deltasplit75/ProtoSplit/ProtoSplit.c b/keyboards/deltasplit75/ProtoSplit/ProtoSplit.c
new file mode 100644
index 0000000000..a6ecc239f6
--- /dev/null
+++ b/keyboards/deltasplit75/ProtoSplit/ProtoSplit.c
@@ -0,0 +1,32 @@
+#include "DeltaSplit75.h"

+

+#ifdef AUDIO_ENABLE

+    float tone_startup[][2] = SONG(STARTUP_SOUND);

+    float tone_goodbye[][2] = SONG(GOODBYE_SOUND);

+#endif

+

+void matrix_init_kb(void) {

+

+    #ifdef AUDIO_ENABLE

+        _delay_ms(20); // gets rid of tick

+        PLAY_NOTE_ARRAY(tone_startup, false, 0);

+    #endif

+

+    // // green led on

+    // DDRD |= (1<<5);

+    // PORTD &= ~(1<<5);

+

+    // // orange led on

+    // DDRB |= (1<<0);

+    // PORTB &= ~(1<<0);

+

+	matrix_init_user();

+};

+

+void shutdown_user(void) {

+    #ifdef AUDIO_ENABLE

+        PLAY_NOTE_ARRAY(tone_goodbye, false, 0);

+	_delay_ms(150);

+	stop_all_notes();

+    #endif

+}

diff --git a/keyboards/deltasplit75/ProtoSplit/ProtoSplit.h b/keyboards/deltasplit75/ProtoSplit/ProtoSplit.h
new file mode 100644
index 0000000000..9c8af6e176
--- /dev/null
+++ b/keyboards/deltasplit75/ProtoSplit/ProtoSplit.h
@@ -0,0 +1,37 @@
+#ifndef ProtoSplit_H

+#define ProtoSplit_H

+

+#include "../DeltaSplit75.h"

+

+//void promicro_bootloader_jmp(bool program);

+#include "quantum.h"

+

+//void promicro_bootloader_jmp(bool program);

+//matrix is defined in a weird way here; the layout on both sides are asymmetrical, but the "matrix" is symmetrical but with empty gaps

+//the last column is defined as a separate row because the firmware currently doesnt support more than 8 columns (this layout has 9 columns per side) K45 and K110 are the Bs on both sides

+#define KEYMAP( \

+	K00,   K01,   K02,   K03,   K04,   K05,   K06,       K70,   K71,   K72,   K73,   K74,   K75,   K76,   K77,   K132, \

+	K10,   K11,   K12,   K13,   K14,   K15,   K16,       K80,   K81,   K82,   K83,   K84,   K85,   K86,   K87,   K133, \

+	K20,   K21,   K22,   K23,   K24,   K25,              K90,   K91,   K92,   K93,   K94,   K95,   K96,   K97,   K134, \

+	K30,   K31,   K32,   K33,   K34,   K35,              K100,  K101,  K102,  K103,  K104,  K105,         K107,  K135, \

+	K40,   K41,   K42,   K43,   K44,   K45,              K110,  K111,  K112,  K113,  K114,  K115,  K116,  K117,  K136, \

+	K50,   K51,   K52,          K54,   K55,              K120,  K121,  K122,  K123,                K126,  K127,  K137 \

+	) \

+	{ \

+		{ K00,   K01,   K02,   K03,   K04,   K05,   K06,   KC_NO}, \

+		{ K10,   K11,   K12,   K13,   K14,   K15,   K16,   KC_NO}, \

+		{ K20,   K21,   K22,   K23,   K24,   K25,   KC_NO, KC_NO}, \

+		{ K30,   K31,   K32,   K33,   K34,   K35,   KC_NO, KC_NO}, \

+		{ K40,   K41,   K42,   K43,   K44,   K45,   KC_NO, KC_NO}, \

+		{ K50,   K51,   K52,   KC_NO, K54,   K55,   KC_NO, KC_NO}, \

+		{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO}, \

+		{ K70  , K71,   K72,   K73,   K74,   K75,   K76,   K77}, \

+		{ K80,   K81,   K82,   K83,   K84,   K85,   K86,   K87}, \

+		{ K90,   K91,   K92,   K93,   K94,   K95,   K96,   K97}, \

+		{ K100,  K101,  K102,  K103,  K104,  K105,  KC_NO, K107}, \

+		{ K110,  K111,  K112,  K113,  K114,  K115,  K116,  K117}, \

+		{ K120,  K121,  K122,  K123,  KC_NO, KC_NO, K126,  K127}, \

+		{ KC_NO, KC_NO, K132,  K133,  K134,  K135,  K136,  K137} \

+	}

+

+#endif
\ No newline at end of file
diff --git a/keyboards/deltasplit75/ProtoSplit/config.h b/keyboards/deltasplit75/ProtoSplit/config.h
new file mode 100644
index 0000000000..d1f6f7966c
--- /dev/null
+++ b/keyboards/deltasplit75/ProtoSplit/config.h
@@ -0,0 +1,90 @@
+/*

+Copyright 2012 Jun Wako <wakojun@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 CONFIG_H

+#define CONFIG_H

+

+#include "config_common.h"

+

+/* USB Device descriptor parameter */

+#define VENDOR_ID       0xFEED

+#define PRODUCT_ID      0x3060

+#define DEVICE_VER      0x0001

+#define MANUFACTURER    xyxjj

+#define PRODUCT         DeltaSplit75

+#define DESCRIPTION     75% split keyboard

+

+/* key matrix size */

+// Rows are doubled-up

+#define MATRIX_ROWS 14

+#define MATRIX_COLS 8

+

+// wiring of each half

+#define MATRIX_ROW_PINS { F4, F5, F6, F7, B1, B3, B2 }

+#define MATRIX_COL_PINS { B6, B5, B4, E6, D7, C6, D4, D1}

+

+#define CATERINA_BOOTLOADER

+

+/* COL2ROW or ROW2COL */

+#define DIODE_DIRECTION COL2ROW

+

+/* define if matrix has ghost */

+//#define MATRIX_HAS_GHOST

+

+/* number of backlight levels */

+// #define BACKLIGHT_LEVELS 3

+

+/* Set 0 if debouncing isn't needed */

+#define DEBOUNCING_DELAY 5

+

+/* 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

+

+/* key combination for command */

+#define IS_COMMAND() ( \

+    keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \

+)

+

+/* ws2812 RGB LED */

+#define RGB_DI_PIN D3

+#define RGBLIGHT_TIMER

+#define RGBLED_NUM 12    // Number of LEDs

+#define ws2812_PORTREG  PORTD

+#define ws2812_DDRREG   DDRD

+

+/*

+ * 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

+

+

+#endif
\ No newline at end of file
diff --git a/keyboards/deltasplit75/ProtoSplit/rules.mk b/keyboards/deltasplit75/ProtoSplit/rules.mk
new file mode 100644
index 0000000000..80a942d06f
--- /dev/null
+++ b/keyboards/deltasplit75/ProtoSplit/rules.mk
@@ -0,0 +1,5 @@
+BACKLIGHT_ENABLE = no
+
+ifndef QUANTUM_DIR
+	include ../../../Makefile
+endif
diff --git a/keyboards/deltasplit75/config.h b/keyboards/deltasplit75/config.h
new file mode 100644
index 0000000000..ced8d320fe
--- /dev/null
+++ b/keyboards/deltasplit75/config.h
@@ -0,0 +1,29 @@
+/*

+Copyright 2012 Jun Wako <wakojun@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 CONFIG_H

+#define CONFIG_H

+

+#include "config_common.h"

+

+#ifdef SUBPROJECT_RightB

+    #include "RightB/config.h"

+#endif

+#ifdef SUBPROJECT_V2

+    #include "v2/config.h"

+#endif

+#endif

diff --git a/keyboards/deltasplit75/deltasplit build guide.pdf b/keyboards/deltasplit75/deltasplit build guide.pdf
new file mode 100644
index 0000000000..045b4a3985
--- /dev/null
+++ b/keyboards/deltasplit75/deltasplit build guide.pdf
Binary files differdiff --git a/keyboards/deltasplit75/deltasplit75.c b/keyboards/deltasplit75/deltasplit75.c
new file mode 100644
index 0000000000..6a73db4cd6
--- /dev/null
+++ b/keyboards/deltasplit75/deltasplit75.c
@@ -0,0 +1 @@
+#include "deltasplit75.h"
\ No newline at end of file
diff --git a/keyboards/deltasplit75/deltasplit75.h b/keyboards/deltasplit75/deltasplit75.h
new file mode 100644
index 0000000000..7ca898aa52
--- /dev/null
+++ b/keyboards/deltasplit75/deltasplit75.h
@@ -0,0 +1,13 @@
+#ifndef deltasplit75_H

+#define deltasplit75_H

+

+#ifdef SUBPROJECT_v2

+    #include "v2.h"

+#endif

+#ifdef SUBPROJECT_ProtoSplit

+    #include "ProtoSplit.h"

+#endif

+

+#include "quantum.h"

+

+#endif
\ No newline at end of file
diff --git a/keyboards/deltasplit75/eeprom-lefthand.eep b/keyboards/deltasplit75/eeprom-lefthand.eep
new file mode 100644
index 0000000000..b9666a74c0
--- /dev/null
+++ b/keyboards/deltasplit75/eeprom-lefthand.eep
@@ -0,0 +1,2 @@
+:0B0000000000000000000000000001F4

+:00000001FF

diff --git a/keyboards/deltasplit75/eeprom-righthand.eep b/keyboards/deltasplit75/eeprom-righthand.eep
new file mode 100644
index 0000000000..94cc5be7fc
--- /dev/null
+++ b/keyboards/deltasplit75/eeprom-righthand.eep
@@ -0,0 +1,2 @@
+:0B0000000000000000000000000000F5

+:00000001FF

diff --git a/keyboards/deltasplit75/i2c.c b/keyboards/deltasplit75/i2c.c
new file mode 100644
index 0000000000..af806c75b6
--- /dev/null
+++ b/keyboards/deltasplit75/i2c.c
@@ -0,0 +1,162 @@
+#include <util/twi.h>

+#include <avr/io.h>

+#include <stdlib.h>

+#include <avr/interrupt.h>

+#include <util/twi.h>

+#include <stdbool.h>

+#include "i2c.h"

+

+#ifdef USE_I2C

+

+// Limits the amount of we wait for any one i2c transaction.

+// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is

+// 9 bits, a single transaction will take around 90μs to complete.

+//

+// (F_CPU/SCL_CLOCK)  =>  # of μC cycles to transfer a bit

+// poll loop takes at least 8 clock cycles to execute

+#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8

+

+#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE)

+

+volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];

+

+static volatile uint8_t slave_buffer_pos;

+static volatile bool slave_has_register_set = false;

+

+// Wait for an i2c operation to finish

+inline static

+void i2c_delay(void) {

+  uint16_t lim = 0;

+  while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT)

+    lim++;

+

+  // easier way, but will wait slightly longer

+  // _delay_us(100);

+}

+

+// Setup twi to run at 100kHz

+void i2c_master_init(void) {

+  // no prescaler

+  TWSR = 0;

+  // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10.

+  // Check datasheets for more info.

+  TWBR = ((F_CPU/SCL_CLOCK)-16)/2;

+}

+

+// Start a transaction with the given i2c slave address. The direction of the

+// transfer is set with I2C_READ and I2C_WRITE.

+// returns: 0 => success

+//          1 => error

+uint8_t i2c_master_start(uint8_t address) {

+  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);

+

+  i2c_delay();

+

+  // check that we started successfully

+  if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))

+    return 1;

+

+  TWDR = address;

+  TWCR = (1<<TWINT) | (1<<TWEN);

+

+  i2c_delay();

+

+  if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) )

+    return 1; // slave did not acknowledge

+  else

+    return 0; // success

+}

+

+

+// Finish the i2c transaction.

+void i2c_master_stop(void) {

+  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

+

+  uint16_t lim = 0;

+  while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT)

+    lim++;

+}

+

+// Write one byte to the i2c slave.

+// returns 0 => slave ACK

+//         1 => slave NACK

+uint8_t i2c_master_write(uint8_t data) {

+  TWDR = data;

+  TWCR = (1<<TWINT) | (1<<TWEN);

+

+  i2c_delay();

+

+  // check if the slave acknowledged us

+  return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1;

+}

+

+// Read one byte from the i2c slave. If ack=1 the slave is acknowledged,

+// if ack=0 the acknowledge bit is not set.

+// returns: byte read from i2c device

+uint8_t i2c_master_read(int ack) {

+  TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA);

+

+  i2c_delay();

+  return TWDR;

+}

+

+void i2c_reset_state(void) {

+  TWCR = 0;

+}

+

+void i2c_slave_init(uint8_t address) {

+  TWAR = address << 0; // slave i2c address

+  // TWEN  - twi enable

+  // TWEA  - enable address acknowledgement

+  // TWINT - twi interrupt flag

+  // TWIE  - enable the twi interrupt

+  TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);

+}

+

+ISR(TWI_vect);

+

+ISR(TWI_vect) {

+  uint8_t ack = 1;

+  switch(TW_STATUS) {

+    case TW_SR_SLA_ACK:

+      // this device has been addressed as a slave receiver

+      slave_has_register_set = false;

+      break;

+

+    case TW_SR_DATA_ACK:

+      // this device has received data as a slave receiver

+      // The first byte that we receive in this transaction sets the location

+      // of the read/write location of the slaves memory that it exposes over

+      // i2c.  After that, bytes will be written at slave_buffer_pos, incrementing

+      // slave_buffer_pos after each write.

+      if(!slave_has_register_set) {

+        slave_buffer_pos = TWDR;

+        // don't acknowledge the master if this memory loctaion is out of bounds

+        if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) {

+          ack = 0;

+          slave_buffer_pos = 0;

+        }

+        slave_has_register_set = true;

+      } else {

+        i2c_slave_buffer[slave_buffer_pos] = TWDR;

+        BUFFER_POS_INC();

+      }

+      break;

+

+    case TW_ST_SLA_ACK:

+    case TW_ST_DATA_ACK:

+      // master has addressed this device as a slave transmitter and is

+      // requesting data.

+      TWDR = i2c_slave_buffer[slave_buffer_pos];

+      BUFFER_POS_INC();

+      break;

+

+    case TW_BUS_ERROR: // something went wrong, reset twi state

+      TWCR = 0;

+    default:

+      break;

+  }

+  // Reset everything, so we are ready for the next TWI interrupt

+  TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN);

+}

+#endif

diff --git a/keyboards/deltasplit75/i2c.h b/keyboards/deltasplit75/i2c.h
new file mode 100644
index 0000000000..cc3910806c
--- /dev/null
+++ b/keyboards/deltasplit75/i2c.h
@@ -0,0 +1,31 @@
+#ifndef I2C_H

+#define I2C_H

+

+#include <stdint.h>

+

+#ifndef F_CPU

+#define F_CPU 16000000UL

+#endif

+

+#define I2C_READ 1

+#define I2C_WRITE 0

+

+#define I2C_ACK 1

+#define I2C_NACK 0

+

+#define SLAVE_BUFFER_SIZE 0x10

+

+// i2c SCL clock frequency

+#define SCL_CLOCK  100000L

+

+extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];

+

+void i2c_master_init(void);

+uint8_t i2c_master_start(uint8_t address);

+void i2c_master_stop(void);

+uint8_t i2c_master_write(uint8_t data);

+uint8_t i2c_master_read(int);

+void i2c_reset_state(void);

+void i2c_slave_init(uint8_t address);

+

+#endif

diff --git a/keyboards/deltasplit75/keymaps/Default/config.h b/keyboards/deltasplit75/keymaps/Default/config.h
new file mode 100644
index 0000000000..28206d6533
--- /dev/null
+++ b/keyboards/deltasplit75/keymaps/Default/config.h
@@ -0,0 +1,31 @@
+/*

+Copyright 2012 Jun Wako <wakojun@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/>.

+*/

+

+

+#define USE_SERIAL

+

+#define MASTER_LEFT

+// #define _MASTER_RIGHT

+// #define EE_HANDS

+

+

+#ifdef SUBPROJECT_v2

+    #include "../../v2/config.h"

+#endif

+#ifdef SUBPROJECT_ProtoSplit

+    #include "../../ProtoSplit/config.h"

+#endif

diff --git a/keyboards/deltasplit75/keymaps/Default/keymap.c b/keyboards/deltasplit75/keymaps/Default/keymap.c
new file mode 100644
index 0000000000..bfb6ac29e3
--- /dev/null
+++ b/keyboards/deltasplit75/keymaps/Default/keymap.c
@@ -0,0 +1,31 @@
+#include "deltasplit75.h"

+#include "action_layer.h"

+#include "eeconfig.h"

+

+extern keymap_config_t keymap_config;

+

+// Each layer gets a name for readability, which is then used in the keymap matrix below.

+// The underscores don't mean anything - you can have a layer called STUFF or any other name.

+// Layer names don't all need to be of the same length, obviously, and you can also skip them

+// entirely and just use numbers.

+

+// Fillers to make layering more clear

+

+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {	

+	KEYMAP(

+		KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_HOME, KC_PGUP, 

+		KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_DEL, KC_END, KC_PGDN, 

+		KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, KC_SLCK, 

+		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_TRNS, KC_ENT, KC_PAUS,  //modify KC_TRNS to enable ISO Support

+		KC_LSFT, KC_TRNS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LSFT, KC_UP, KC_PSCR, //modify KC_TRNS to enable ISO Support

+		KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_SPC, KC_RALT, KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),

+

+	KEYMAP(

+		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, 

+		KC_BSLS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		KC_TRNS, KC_VOLU, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		M(1), KC_LEFT, KC_DOWN, KC_RGHT, KC_PAUS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		KC_TRNS, KC_TRNS, KC_VOLD, M(0), KC_PSCR, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),

+

+};
\ No newline at end of file
diff --git a/keyboards/deltasplit75/keymaps/ProtoSplit/config.h b/keyboards/deltasplit75/keymaps/ProtoSplit/config.h
new file mode 100644
index 0000000000..d079b5cd3f
--- /dev/null
+++ b/keyboards/deltasplit75/keymaps/ProtoSplit/config.h
@@ -0,0 +1,31 @@
+/*

+Copyright 2012 Jun Wako <wakojun@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/>.

+*/

+

+

+#define USE_SERIAL

+

+#define MASTER_LEFT

+// #define _MASTER_RIGHT

+// #define EE_HANDS

+

+

+#ifdef SUBPROJECT_V2

+    #include "../../V2/config.h"

+#endif

+#ifdef SUBPROJECT_ProtoSplit

+    #include "../../ProtoSplit/config.h"

+#endif

diff --git a/keyboards/deltasplit75/keymaps/ProtoSplit/keymap.c b/keyboards/deltasplit75/keymaps/ProtoSplit/keymap.c
new file mode 100644
index 0000000000..3c81cf4261
--- /dev/null
+++ b/keyboards/deltasplit75/keymaps/ProtoSplit/keymap.c
@@ -0,0 +1,31 @@
+#include "DeltaSplit75.h"

+#include "action_layer.h"

+#include "eeconfig.h"

+

+extern keymap_config_t keymap_config;

+

+// Each layer gets a name for readability, which is then used in the keymap matrix below.

+// The underscores don't mean anything - you can have a layer called STUFF or any other name.

+// Layer names don't all need to be of the same length, obviously, and you can also skip them

+// entirely and just use numbers.

+

+// Fillers to make layering more clear

+

+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {	

+	KEYMAP(

+		KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_INS, KC_HOME, KC_PGUP, 

+		KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_DEL, KC_END, KC_PGDN, 

+		KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, KC_SLCK, 

+		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_ENT, KC_PAUS,

+		KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LSFT, KC_UP, KC_PSCR,

+		KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), KC_SPC, KC_RALT, KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),

+

+	KEYMAP(

+		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, 

+		KC_BSLS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		KC_TRNS, KC_VOLU, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		M(1), KC_LEFT, KC_DOWN, KC_RGHT, KC_PAUS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		KC_TRNS, KC_VOLD, M(0), KC_PSCR, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),

+

+};
\ No newline at end of file
diff --git a/keyboards/deltasplit75/keymaps/itsaferbie/config.h b/keyboards/deltasplit75/keymaps/itsaferbie/config.h
index 56df3f1607..28206d6533 100644
--- a/keyboards/deltasplit75/keymaps/itsaferbie/config.h
+++ b/keyboards/deltasplit75/keymaps/itsaferbie/config.h
@@ -1,31 +1,31 @@
-/*
-Copyright 2012 Jun Wako <wakojun@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/>.
-*/
-
-
-#define USE_SERIAL
-
-#define MASTER_LEFT
-// #define _MASTER_RIGHT
-// #define EE_HANDS
-
-
-#ifdef SUBPROJECT_v2
-    #include "../../v2/config.h"
-#endif
-#ifdef SUBPROJECT_ProtoSplit
-    #include "../../ProtoSplit/config.h"
-#endif
+/*

+Copyright 2012 Jun Wako <wakojun@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/>.

+*/

+

+

+#define USE_SERIAL

+

+#define MASTER_LEFT

+// #define _MASTER_RIGHT

+// #define EE_HANDS

+

+

+#ifdef SUBPROJECT_v2

+    #include "../../v2/config.h"

+#endif

+#ifdef SUBPROJECT_ProtoSplit

+    #include "../../ProtoSplit/config.h"

+#endif

diff --git a/keyboards/deltasplit75/keymaps/itsaferbie/keymap.c b/keyboards/deltasplit75/keymaps/itsaferbie/keymap.c
index 37bc25ffc0..df46d717e2 100644
--- a/keyboards/deltasplit75/keymaps/itsaferbie/keymap.c
+++ b/keyboards/deltasplit75/keymaps/itsaferbie/keymap.c
@@ -1,46 +1,46 @@
-#include "deltasplit75.h"
-#include "action_layer.h"
-#include "eeconfig.h"
-
-extern keymap_config_t keymap_config;
-
-// Each layer gets a name for readability, which is then used in the keymap matrix below.
-// The underscores don't mean anything - you can have a layer called STUFF or any other name.
-// Layer names don't all need to be of the same length, obviously, and you can also skip them
-// entirely and just use numbers.
-
-// Fillers to make layering more clear
-
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {	
-	/* Layer 0: Default Layer
-     *,-----------------------------------------------------------------------.
-     * |Esc| F1| F2| F3| F4| F5| F6|    F7| F8| F9| F10| F11| F12|Prnt|Ins|Del| 
-	 * |----------------------------------------------------------------------|
-     * |  `|  1|  2|  3|  4|  5|  6|    7|  8|  9|  0|  -|  =| Bakspace | Home|
-     * |----------------------------------------------------------------------|
-     * |Tab  |  Q|  W|  E|  R|  T|      Y|  U|  I|  O|  P|  [|  ]|  \|    PgUp|
-     * |----------------------------------------------------------------------|
-     * |Ctrl|  A|  S|  D|  F|  G|       H|  J|  K|  L|  ;|  '|Enter  |  PgDown|
-     * |----------------------------------------------------------------------|
-     * |Shif|   |  Z|  X|  C|  V|  B|   N|  M|  ,|  .|  /|Shift |      Up| End|
-     * |----------------------------------------------------------------------|
-     * |CapsLo|Gui |Alt |Sp |Mod |      Sp| Alt| Gui| Ctrl|    | Lef| Dow| Rig|
-     * `----------------------------------------------------------------------'
-     */
-	KEYMAP(
-		KC_ESC,  KC_F1,   KC_F2,   KC_F3,  KC_F4, KC_F5,  KC_F6,            KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_PSCR,  KC_INS,  KC_DEL, 
-		KC_GRV,  KC_1,    KC_2,    KC_3,   KC_4,  KC_5,   KC_6,             KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,  KC_BSPC,  KC_BSPC, KC_HOME, 
-		KC_TAB,  KC_Q,    KC_W,    KC_E,   KC_R,  KC_T,                     KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC,  KC_BSLS, KC_PGUP, 
-		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_TRNS,  KC_ENT,  KC_PGDN,  
-		KC_LSFT, KC_TRNS, KC_Z,    KC_X,   KC_C,  KC_V,   KC_B,             KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT,  KC_UP,   KC_END, 
-		KC_CAPS, KC_LGUI, KC_LALT,         KC_SPC, MO(1),                   KC_SPC,  KC_RALT, KC_RGUI, KC_RCTL,                   KC_LEFT,  KC_DOWN, KC_RGHT),
-
-	KEYMAP(
-		RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, KC_TRNS, KC_TRNS, KC_TRNS,      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, 
-		RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS,      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 
-		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,               KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 
-		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,               KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU, 
-		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_VOLD, 
-		KC_TRNS, KC_TRNS, KC_TRNS,          KC_TRNS, KC_TRNS,               KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,                   KC_MPRV, KC_STOP, KC_MNXT),
-
+#include "deltasplit75.h"

+#include "action_layer.h"

+#include "eeconfig.h"

+

+extern keymap_config_t keymap_config;

+

+// Each layer gets a name for readability, which is then used in the keymap matrix below.

+// The underscores don't mean anything - you can have a layer called STUFF or any other name.

+// Layer names don't all need to be of the same length, obviously, and you can also skip them

+// entirely and just use numbers.

+

+// Fillers to make layering more clear

+

+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {	

+	/* Layer 0: Default Layer

+     *,-----------------------------------------------------------------------.

+     * |Esc| F1| F2| F3| F4| F5| F6|    F7| F8| F9| F10| F11| F12|Prnt|Ins|Del| 

+	 * |----------------------------------------------------------------------|

+     * |  `|  1|  2|  3|  4|  5|  6|    7|  8|  9|  0|  -|  =| Bakspace | Home|

+     * |----------------------------------------------------------------------|

+     * |Tab  |  Q|  W|  E|  R|  T|      Y|  U|  I|  O|  P|  [|  ]|  \|    PgUp|

+     * |----------------------------------------------------------------------|

+     * |Ctrl|  A|  S|  D|  F|  G|       H|  J|  K|  L|  ;|  '|Enter  |  PgDown|

+     * |----------------------------------------------------------------------|

+     * |Shif|   |  Z|  X|  C|  V|  B|   N|  M|  ,|  .|  /|Shift |      Up| End|

+     * |----------------------------------------------------------------------|

+     * |CapsLo|Gui |Alt |Sp |Mod |      Sp| Alt| Gui| Ctrl|    | Lef| Dow| Rig|

+     * `----------------------------------------------------------------------'

+     */

+	KEYMAP(

+		KC_ESC,  KC_F1,   KC_F2,   KC_F3,  KC_F4, KC_F5,  KC_F6,            KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_PSCR,  KC_INS,  KC_DEL, 

+		KC_GRV,  KC_1,    KC_2,    KC_3,   KC_4,  KC_5,   KC_6,             KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,  KC_BSPC,  KC_BSPC, KC_HOME, 

+		KC_TAB,  KC_Q,    KC_W,    KC_E,   KC_R,  KC_T,                     KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC,  KC_BSLS, KC_PGUP, 

+		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_TRNS,  KC_ENT,  KC_PGDN,  

+		KC_LSFT, KC_TRNS, KC_Z,    KC_X,   KC_C,  KC_V,   KC_B,             KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT,  KC_UP,   KC_END, 

+		KC_CAPS, KC_LGUI, KC_LALT,         KC_SPC, MO(1),                   KC_SPC,  KC_RALT, KC_RGUI, KC_RCTL,                   KC_LEFT,  KC_DOWN, KC_RGHT),

+

+	KEYMAP(

+		RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, KC_TRNS, KC_TRNS, KC_TRNS,      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, 

+		RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS,      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,               KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, 

+		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,               KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU, 

+		KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,      KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_VOLD, 

+		KC_TRNS, KC_TRNS, KC_TRNS,          KC_TRNS, KC_TRNS,               KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,                   KC_MPRV, KC_STOP, KC_MNXT),

+

 };
\ No newline at end of file
diff --git a/keyboards/deltasplit75/matrix.c b/keyboards/deltasplit75/matrix.c
new file mode 100644
index 0000000000..c3bb0b058c
--- /dev/null
+++ b/keyboards/deltasplit75/matrix.c
@@ -0,0 +1,318 @@
+/*

+Copyright 2012 Jun Wako <wakojun@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/>.

+*/

+

+/*

+ * scan matrix

+ */

+#include <stdint.h>

+#include <stdbool.h>

+#include <avr/io.h>

+#include <avr/wdt.h>

+#include <avr/interrupt.h>

+#include <util/delay.h>

+#include "print.h"

+#include "debug.h"

+#include "util.h"

+#include "matrix.h"

+#include "split_util.h"

+#include "pro_micro.h"

+#include "config.h"

+

+#ifdef USE_I2C

+#  include "i2c.h"

+#else // USE_SERIAL

+#  include "serial.h"

+#endif

+

+#ifndef DEBOUNCE

+#  define DEBOUNCE	5

+#endif

+

+#define ERROR_DISCONNECT_COUNT 5

+

+static uint8_t debouncing = DEBOUNCE;

+static const int ROWS_PER_HAND = MATRIX_ROWS/2;

+static uint8_t error_count = 0;

+

+static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;

+static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;

+

+/* matrix state(1:on, 0:off) */

+static matrix_row_t matrix[MATRIX_ROWS];

+static matrix_row_t matrix_debouncing[MATRIX_ROWS];

+

+static matrix_row_t read_cols(void);

+static void init_cols(void);

+static void unselect_rows(void);

+static void select_row(uint8_t row);

+

+__attribute__ ((weak))

+void matrix_init_quantum(void) {

+    matrix_init_kb();

+}

+

+__attribute__ ((weak))

+void matrix_scan_quantum(void) {

+    matrix_scan_kb();

+}

+

+__attribute__ ((weak))

+void matrix_init_kb(void) {

+    matrix_init_user();

+}

+

+__attribute__ ((weak))

+void matrix_scan_kb(void) {

+    matrix_scan_user();

+}

+

+__attribute__ ((weak))

+void matrix_init_user(void) {

+}

+

+__attribute__ ((weak))

+void matrix_scan_user(void) {

+}

+

+inline

+uint8_t matrix_rows(void)

+{

+    return MATRIX_ROWS;

+}

+

+inline

+uint8_t matrix_cols(void)

+{

+    return MATRIX_COLS;

+}

+

+void matrix_init(void)

+{

+    debug_enable = true;

+    debug_matrix = true;

+    debug_mouse = true;

+    // initialize row and col

+    unselect_rows();

+    init_cols();

+

+    TX_RX_LED_INIT;

+

+    // initialize matrix state: all keys off

+    for (uint8_t i=0; i < MATRIX_ROWS; i++) {

+        matrix[i] = 0;

+        matrix_debouncing[i] = 0;

+    }

+

+    matrix_init_quantum();

+}

+

+uint8_t _matrix_scan(void)

+{

+    // Right hand is stored after the left in the matirx so, we need to offset it

+    int offset = isLeftHand ? 0 : (ROWS_PER_HAND);

+

+    for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {

+        select_row(i);

+        _delay_us(30);  // without this wait read unstable value.

+        matrix_row_t cols = read_cols();

+        if (matrix_debouncing[i+offset] != cols) {

+            matrix_debouncing[i+offset] = cols;

+            debouncing = DEBOUNCE;

+        }

+        unselect_rows();

+    }

+

+    if (debouncing) {

+        if (--debouncing) {

+            _delay_ms(1);

+        } else {

+            for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {

+                matrix[i+offset] = matrix_debouncing[i+offset];

+            }

+        }

+    }

+

+    return 1;

+}

+

+#ifdef USE_I2C

+

+// Get rows from other half over i2c

+int i2c_transaction(void) {

+    int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;

+

+    int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);

+    if (err) goto i2c_error;

+

+    // start of matrix stored at 0x00

+    err = i2c_master_write(0x00);

+    if (err) goto i2c_error;

+

+    // Start read

+    err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);

+    if (err) goto i2c_error;

+

+    if (!err) {

+        int i;

+        for (i = 0; i < ROWS_PER_HAND-1; ++i) {

+            matrix[slaveOffset+i] = i2c_master_read(I2C_ACK);

+        }

+        matrix[slaveOffset+i] = i2c_master_read(I2C_NACK);

+        i2c_master_stop();

+    } else {

+i2c_error: // the cable is disconnceted, or something else went wrong

+        i2c_reset_state();

+        return err;

+    }

+

+    return 0;

+}

+

+#else // USE_SERIAL

+

+int serial_transaction(void) {

+    int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;

+

+    if (serial_update_buffers()) {

+        return 1;

+    }

+

+    for (int i = 0; i < ROWS_PER_HAND; ++i) {

+        matrix[slaveOffset+i] = serial_slave_buffer[i];

+    }

+    return 0;

+}

+#endif

+

+uint8_t matrix_scan(void)

+{

+    int ret = _matrix_scan();

+

+

+

+#ifdef USE_I2C

+    if( i2c_transaction() ) {

+#else // USE_SERIAL

+    if( serial_transaction() ) {

+#endif

+        // turn on the indicator led when halves are disconnected

+        TXLED1;

+

+        error_count++;

+

+        if (error_count > ERROR_DISCONNECT_COUNT) {

+            // reset other half if disconnected

+            int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;

+            for (int i = 0; i < ROWS_PER_HAND; ++i) {

+                matrix[slaveOffset+i] = 0;

+            }

+        }

+    } else {

+        // turn off the indicator led on no error

+        TXLED0;

+        error_count = 0;

+    }

+

+    matrix_scan_quantum();

+

+    return ret;

+}

+

+void matrix_slave_scan(void) {

+    _matrix_scan();

+

+    int offset = (isLeftHand) ? 0 : (MATRIX_ROWS / 2);

+

+#ifdef USE_I2C

+    for (int i = 0; i < ROWS_PER_HAND; ++i) {

+        /* i2c_slave_buffer[i] = matrix[offset+i]; */

+        i2c_slave_buffer[i] = matrix[offset+i];

+    }

+#else // USE_SERIAL

+    for (int i = 0; i < ROWS_PER_HAND; ++i) {

+        serial_slave_buffer[i] = matrix[offset+i];

+    }

+#endif

+}

+

+bool matrix_is_modified(void)

+{

+    if (debouncing) return false;

+    return true;

+}

+

+inline

+bool matrix_is_on(uint8_t row, uint8_t col)

+{

+    return (matrix[row] & ((matrix_row_t)1<<col));

+}

+

+inline

+matrix_row_t matrix_get_row(uint8_t row)

+{

+    return matrix[row];

+}

+

+void matrix_print(void)

+{

+    print("\nr/c 0123456789ABCDEF\n");

+    for (uint8_t row = 0; row < MATRIX_ROWS; row++) {

+        phex(row); print(": ");

+        pbin_reverse16(matrix_get_row(row));

+        print("\n");

+    }

+}

+

+uint8_t matrix_key_count(void)

+{

+    uint8_t count = 0;

+    for (uint8_t i = 0; i < MATRIX_ROWS; i++) {

+        count += bitpop16(matrix[i]);

+    }

+    return count;

+}

+

+static void  init_cols(void)

+{

+    for(int x = 0; x < MATRIX_COLS; x++) {

+        _SFR_IO8((col_pins[x] >> 4) + 1) &=  ~_BV(col_pins[x] & 0xF);

+        _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF);

+    }

+}

+

+static matrix_row_t read_cols(void)

+{

+    matrix_row_t result = 0;

+    for(int x = 0; x < MATRIX_COLS; x++) {

+        result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x);

+    }

+    return result;

+}

+

+static void unselect_rows(void)

+{

+    for(int x = 0; x < ROWS_PER_HAND; x++) {

+        _SFR_IO8((row_pins[x] >> 4) + 1) &=  ~_BV(row_pins[x] & 0xF);

+        _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF);

+    }

+}

+

+static void select_row(uint8_t row)

+{

+    _SFR_IO8((row_pins[row] >> 4) + 1) |=  _BV(row_pins[row] & 0xF);

+    _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF);

+}

diff --git a/keyboards/deltasplit75/pro_micro.h b/keyboards/deltasplit75/pro_micro.h
new file mode 100644
index 0000000000..2bda8c290d
--- /dev/null
+++ b/keyboards/deltasplit75/pro_micro.h
@@ -0,0 +1,362 @@
+/*

+  pins_arduino.h - Pin definition functions for Arduino

+  Part of Arduino - http://www.arduino.cc/

+

+  Copyright (c) 2007 David A. Mellis

+

+  This library is free software; you can redistribute it and/or

+  modify it under the terms of the GNU Lesser General Public

+  License as published by the Free Software Foundation; either

+  version 2.1 of the License, or (at your option) any later version.

+

+  This library 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

+  Lesser General Public License for more details.

+

+  You should have received a copy of the GNU Lesser General

+  Public License along with this library; if not, write to the

+  Free Software Foundation, Inc., 59 Temple Place, Suite 330,

+  Boston, MA  02111-1307  USA

+

+  $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $

+*/

+

+#ifndef Pins_Arduino_h

+#define Pins_Arduino_h

+

+#include <avr/pgmspace.h>

+

+// Workaround for wrong definitions in "iom32u4.h".

+// This should be fixed in the AVR toolchain.

+#undef UHCON

+#undef UHINT

+#undef UHIEN

+#undef UHADDR

+#undef UHFNUM

+#undef UHFNUML

+#undef UHFNUMH

+#undef UHFLEN

+#undef UPINRQX

+#undef UPINTX

+#undef UPNUM

+#undef UPRST

+#undef UPCONX

+#undef UPCFG0X

+#undef UPCFG1X

+#undef UPSTAX

+#undef UPCFG2X

+#undef UPIENX

+#undef UPDATX

+#undef TCCR2A

+#undef WGM20

+#undef WGM21

+#undef COM2B0

+#undef COM2B1

+#undef COM2A0

+#undef COM2A1

+#undef TCCR2B

+#undef CS20

+#undef CS21

+#undef CS22

+#undef WGM22

+#undef FOC2B

+#undef FOC2A

+#undef TCNT2

+#undef TCNT2_0

+#undef TCNT2_1

+#undef TCNT2_2

+#undef TCNT2_3

+#undef TCNT2_4

+#undef TCNT2_5

+#undef TCNT2_6

+#undef TCNT2_7

+#undef OCR2A

+#undef OCR2_0

+#undef OCR2_1

+#undef OCR2_2

+#undef OCR2_3

+#undef OCR2_4

+#undef OCR2_5

+#undef OCR2_6

+#undef OCR2_7

+#undef OCR2B

+#undef OCR2_0

+#undef OCR2_1

+#undef OCR2_2

+#undef OCR2_3

+#undef OCR2_4

+#undef OCR2_5

+#undef OCR2_6

+#undef OCR2_7

+

+#define NUM_DIGITAL_PINS  30

+#define NUM_ANALOG_INPUTS 12

+

+#define TX_RX_LED_INIT  DDRD |= (1<<5), DDRB |= (1<<0)

+#define TXLED0          PORTD |= (1<<5)

+#define TXLED1          PORTD &= ~(1<<5)

+#define RXLED0          PORTB |= (1<<0)

+#define RXLED1          PORTB &= ~(1<<0)

+

+static const uint8_t SDA = 2;

+static const uint8_t SCL = 3;

+#define LED_BUILTIN 13

+

+// Map SPI port to 'new' pins D14..D17

+static const uint8_t SS   = 17;

+static const uint8_t MOSI = 16;

+static const uint8_t MISO = 14;

+static const uint8_t SCK  = 15;

+

+// Mapping of analog pins as digital I/O

+// A6-A11 share with digital pins

+static const uint8_t ADC0 = 18;

+static const uint8_t ADC1 = 19;

+static const uint8_t ADC2 = 20;

+static const uint8_t ADC3 = 21;

+static const uint8_t ADC4 = 22;

+static const uint8_t ADC5 = 23;

+static const uint8_t ADC6 = 24;   // D4

+static const uint8_t ADC7 = 25;   // D6

+static const uint8_t ADC8 = 26;   // D8

+static const uint8_t ADC9 = 27;   // D9

+static const uint8_t ADC10 = 28;  // D10

+static const uint8_t ADC11 = 29;  // D12

+

+#define digitalPinToPCICR(p)    ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))

+#define digitalPinToPCICRbit(p) 0

+#define digitalPinToPCMSK(p)    ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))

+#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4))))))

+

+//  __AVR_ATmega32U4__ has an unusual mapping of pins to channels

+extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];

+#define analogPinToChannel(P)  ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )

+

+#define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT)))))

+

+#ifdef ARDUINO_MAIN

+

+// On the Arduino board, digital pins are also used

+// for the analog output (software PWM).  Analog input

+// pins are a separate set.

+

+// ATMEL ATMEGA32U4 / ARDUINO LEONARDO

+//

+// D0               PD2                 RXD1/INT2

+// D1               PD3                 TXD1/INT3

+// D2               PD1     SDA         SDA/INT1

+// D3#              PD0     PWM8/SCL    OC0B/SCL/INT0

+// D4       A6      PD4                 ADC8

+// D5#              PC6     ???         OC3A/#OC4A

+// D6#      A7      PD7     FastPWM     #OC4D/ADC10

+// D7               PE6                 INT6/AIN0

+//

+// D8       A8      PB4                 ADC11/PCINT4

+// D9#      A9      PB5     PWM16       OC1A/#OC4B/ADC12/PCINT5

+// D10#     A10     PB6     PWM16       OC1B/0c4B/ADC13/PCINT6

+// D11#             PB7     PWM8/16     0C0A/OC1C/#RTS/PCINT7

+// D12      A11     PD6                 T1/#OC4D/ADC9

+// D13#             PC7     PWM10       CLK0/OC4A

+//

+// A0       D18     PF7                 ADC7

+// A1       D19     PF6                 ADC6

+// A2       D20     PF5                 ADC5

+// A3       D21     PF4                 ADC4

+// A4       D22     PF1                 ADC1

+// A5       D23     PF0                 ADC0

+//

+// New pins D14..D17 to map SPI port to digital pins

+//

+// MISO     D14     PB3                 MISO,PCINT3

+// SCK      D15     PB1                 SCK,PCINT1

+// MOSI     D16     PB2                 MOSI,PCINT2

+// SS       D17     PB0                 RXLED,SS/PCINT0

+//

+// Connected LEDs on board for TX and RX

+// TXLED    D24     PD5                 XCK1

+// RXLED    D17     PB0

+// HWB              PE2                 HWB

+

+// these arrays map port names (e.g. port B) to the

+// appropriate addresses for various functions (e.g. reading

+// and writing)

+const uint16_t PROGMEM port_to_mode_PGM[] = {

+    NOT_A_PORT,

+    NOT_A_PORT,

+    (uint16_t) &DDRB,

+    (uint16_t) &DDRC,

+    (uint16_t) &DDRD,

+    (uint16_t) &DDRE,

+    (uint16_t) &DDRF,

+};

+

+const uint16_t PROGMEM port_to_output_PGM[] = {

+    NOT_A_PORT,

+    NOT_A_PORT,

+    (uint16_t) &PORTB,

+    (uint16_t) &PORTC,

+    (uint16_t) &PORTD,

+    (uint16_t) &PORTE,

+    (uint16_t) &PORTF,

+};

+

+const uint16_t PROGMEM port_to_input_PGM[] = {

+    NOT_A_PORT,

+    NOT_A_PORT,

+    (uint16_t) &PINB,

+    (uint16_t) &PINC,

+    (uint16_t) &PIND,

+    (uint16_t) &PINE,

+    (uint16_t) &PINF,

+};

+

+const uint8_t PROGMEM digital_pin_to_port_PGM[] = {

+    PD, // D0 - PD2

+    PD, // D1 - PD3

+    PD, // D2 - PD1

+    PD, // D3 - PD0

+    PD, // D4 - PD4

+    PC, // D5 - PC6

+    PD, // D6 - PD7

+    PE, // D7 - PE6

+

+    PB, // D8 - PB4

+    PB, // D9 - PB5

+    PB, // D10 - PB6

+    PB, // D11 - PB7

+    PD, // D12 - PD6

+    PC, // D13 - PC7

+

+    PB, // D14 - MISO - PB3

+    PB, // D15 - SCK - PB1

+    PB, // D16 - MOSI - PB2

+    PB, // D17 - SS - PB0

+

+    PF, // D18 - A0 - PF7

+    PF, // D19 - A1 - PF6

+    PF, // D20 - A2 - PF5

+    PF, // D21 - A3 - PF4

+    PF, // D22 - A4 - PF1

+    PF, // D23 - A5 - PF0

+

+    PD, // D24 - PD5

+    PD, // D25 / D6 - A7 - PD7

+    PB, // D26 / D8 - A8 - PB4

+    PB, // D27 / D9 - A9 - PB5

+    PB, // D28 / D10 - A10 - PB6

+    PD, // D29 / D12 - A11 - PD6

+};

+

+const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {

+    _BV(2), // D0 - PD2

+    _BV(3), // D1 - PD3

+    _BV(1), // D2 - PD1

+    _BV(0), // D3 - PD0

+    _BV(4), // D4 - PD4

+    _BV(6), // D5 - PC6

+    _BV(7), // D6 - PD7

+    _BV(6), // D7 - PE6

+

+    _BV(4), // D8 - PB4

+    _BV(5), // D9 - PB5

+    _BV(6), // D10 - PB6

+    _BV(7), // D11 - PB7

+    _BV(6), // D12 - PD6

+    _BV(7), // D13 - PC7

+

+    _BV(3), // D14 - MISO - PB3

+    _BV(1), // D15 - SCK - PB1

+    _BV(2), // D16 - MOSI - PB2

+    _BV(0), // D17 - SS - PB0

+

+    _BV(7), // D18 - A0 - PF7

+    _BV(6), // D19 - A1 - PF6

+    _BV(5), // D20 - A2 - PF5

+    _BV(4), // D21 - A3 - PF4

+    _BV(1), // D22 - A4 - PF1

+    _BV(0), // D23 - A5 - PF0

+

+    _BV(5), // D24 - PD5

+    _BV(7), // D25 / D6 - A7 - PD7

+    _BV(4), // D26 / D8 - A8 - PB4

+    _BV(5), // D27 / D9 - A9 - PB5

+    _BV(6), // D28 / D10 - A10 - PB6

+    _BV(6), // D29 / D12 - A11 - PD6

+};

+

+const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    TIMER0B,        /* 3 */

+    NOT_ON_TIMER,

+    TIMER3A,        /* 5 */

+    TIMER4D,        /* 6 */

+    NOT_ON_TIMER,

+

+    NOT_ON_TIMER,

+    TIMER1A,        /* 9 */

+    TIMER1B,        /* 10 */

+    TIMER0A,        /* 11 */

+

+    NOT_ON_TIMER,

+    TIMER4A,        /* 13 */

+

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+    NOT_ON_TIMER,

+};

+

+const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {

+    7,  // A0               PF7                 ADC7

+    6,  // A1               PF6                 ADC6

+    5,  // A2               PF5                 ADC5

+    4,  // A3               PF4                 ADC4

+    1,  // A4               PF1                 ADC1

+    0,  // A5               PF0                 ADC0

+    8,  // A6       D4      PD4                 ADC8

+    10, // A7       D6      PD7                 ADC10

+    11, // A8       D8      PB4                 ADC11

+    12, // A9       D9      PB5                 ADC12

+    13, // A10      D10     PB6                 ADC13

+    9   // A11      D12     PD6                 ADC9

+};

+

+#endif /* ARDUINO_MAIN */

+

+// These serial port names are intended to allow libraries and architecture-neutral

+// sketches to automatically default to the correct port name for a particular type

+// of use.  For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,

+// the first hardware serial port whose RX/TX pins are not dedicated to another use.

+//

+// SERIAL_PORT_MONITOR        Port which normally prints to the Arduino Serial Monitor

+//

+// SERIAL_PORT_USBVIRTUAL     Port which is USB virtual serial

+//

+// SERIAL_PORT_LINUXBRIDGE    Port which connects to a Linux system via Bridge library

+//

+// SERIAL_PORT_HARDWARE       Hardware serial port, physical RX & TX pins.

+//

+// SERIAL_PORT_HARDWARE_OPEN  Hardware serial ports which are open for use.  Their RX & TX

+//                            pins are NOT connected to anything by default.

+#define SERIAL_PORT_MONITOR        Serial

+#define SERIAL_PORT_USBVIRTUAL     Serial

+#define SERIAL_PORT_HARDWARE       Serial1

+#define SERIAL_PORT_HARDWARE_OPEN  Serial1

+

+#endif /* Pins_Arduino_h */

diff --git a/keyboards/deltasplit75/readme.md b/keyboards/deltasplit75/readme.md
new file mode 100644
index 0000000000..6932c556bf
--- /dev/null
+++ b/keyboards/deltasplit75/readme.md
@@ -0,0 +1,126 @@
+DeltaSplit75

+======

+

+This readme and most of the code are from https://github.com/ahtn/tmk_keyboard/ and https://github.com/qmk/qmk_firmware/tree/master/keyboards/lets_split

+

+Credit to ahtn and wootpatoot for work on the split keyboard firmware

+

+Split keyboard firmware for Arduino Pro Micro or other ATmega32u4

+based boards.

+

+## Case Files

+Files are available here: https://github.com/xyxjj/DeltaSplit75-Case-files

+

+

+## First Time Setup

+

+Download or clone the whole firmware and navigate to the keyboards/DeltaSplit75 directory. Once your dev env is setup, you'll be able to generate the default .hex using:

+

+```

+make V2

+

+or

+

+make ProtoSplit-ProtoSplit (if you have one of the prototype PCBs)

+```

+

+You will see a lot of output and if everything worked correctly you will see the built hex files:

+

+```

+DeltaSplit75_ProtoSplit_ProtoSplit.hex

+

+or

+

+DeltaSplit75_V2_Default.hex

+

+```

+

+

+For more information on customizing keymaps, take a look at the primary documentation for [Customizing Your Keymap](/readme.md##customizing-your-keymap) in the main readme.md.

+

+### DeltaSplit75 V2

+The PCBs available in groupbuy are all v2, if you've bought one of my prototype PCBs (it says DeltaSplit65 on the silkscreen instead of 75), use the code make ProtoSplit-ProtoSplit instead

+

+Features

+--------

+

+For the full Quantum Mechanical Keyboard feature list, see [the parent readme.md](/readme.md).

+

+Some features supported by the firmware:

+

+* Either half can connect to the computer via USB, or both halves can be used

+  independently.

+* 75% formfactor

+* Support for multiple Bottom Rows

+* RGB underglow support

+* Split Backspace and ISO support

+

+

+Flashing

+-------

+I personally use xLoader to upload my hex files to the keyboard, though any other working software is fine too

+

+

+Choosing which board to plug the USB cable into (choosing Master)

+--------

+Because the two boards are identical, the firmware has logic to differentiate the left and right board.

+

+It uses two strategies to figure things out: look at the EEPROM (memory on the chip) or looks if the current board has the usb cable.

+

+The EEPROM approach requires additional setup (flashing the eeeprom) but allows you to swap the usb cable to either side.

+

+The USB cable approach is easier to setup and if you just want the usb cable on the left board, you do not need to do anything extra.

+

+### Setting the left hand as master

+If you always plug the usb cable into the left board, nothing extra is needed as this is the default. Comment out `EE_HANDS` and comment out `I2C_MASTER_RIGHT` or `MASTER_RIGHT` if for some reason it was set.

+

+### Setting the right hand as master

+If you always plug the usb cable into the right board, add an extra flag to your `config.h`

+```

+ #define MASTER_RIGHT

+```

+

+### Setting EE_hands to use either hands as master

+If you define `EE_HANDS` in your `config.h`, you will need to set the

+EEPROM for the left and right halves.

+

+The EEPROM is used to store whether the

+half is left handed or right handed. This makes it so that the same firmware

+file will run on both hands instead of having to flash left and right handed

+versions of the firmware to each half. To flash the EEPROM file for the left

+half run:

+```

+avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-lefthand.eep

+// or the equivalent in dfu-programmer

+

+```

+and similarly for right half

+```

+avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-righhand.eep

+// or the equivalent in dfu-programmer

+```

+

+NOTE: replace `$(COM_PORT)` with the port of your device (e.g. `/dev/ttyACM0`)

+

+After you have flashed the EEPROM, you then need to set `EE_HANDS` in your config.h, rebuild the hex files and reflash.

+

+Note that you need to program both halves, but you have the option of using

+different keymaps for each half. You could program the left half with a QWERTY

+layout and the right half with a Colemak layout using bootmagic's default layout option.

+Then if you connect the left half to a computer by USB the keyboard will use QWERTY and Colemak when the

+right half is connected.

+

+

+Notes on Using Pro Micro 3.3V

+-----------------------------

+

+Do update the `F_CPU` parameter in `rules.mk` to `8000000` which reflects

+the frequency on the 3.3V board.

+

+Also, if the slave board is producing weird characters in certain columns,

+update the following line in `matrix.c` to the following:

+

+```

+// _delay_us(30);  // without this wait read unstable value.

+_delay_us(300);  // without this wait read unstable value.

+```

diff --git a/keyboards/deltasplit75/rules.mk b/keyboards/deltasplit75/rules.mk
new file mode 100644
index 0000000000..0efa785505
--- /dev/null
+++ b/keyboards/deltasplit75/rules.mk
@@ -0,0 +1,87 @@
+SRC += matrix.c \
+	   i2c.c \
+	   split_util.c \
+	   serial.c
+
+# MCU name
+#MCU = at90usb1287
+MCU = atmega32u4
+
+# Processor frequency.
+#     This will define a symbol, F_CPU, in all source code files equal to the
+#     processor frequency in Hz. You can then use this symbol in your source code to
+#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+#     automatically to create a 32-bit value in your source code.
+#
+#     This will be an integer division of F_USB below, as it is sourced by
+#     F_USB after it has run through any CPU prescalers. Note that this value
+#     does not *change* the processor frequency - it should merely be updated to
+#     reflect the processor speed set externally so that the code can use accurate
+#     software delays.
+F_CPU = 16000000
+
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+#     This will define a symbol, F_USB, in all source code files equal to the
+#     input clock frequency (before any prescaling is performed) in Hz. This value may
+#     differ from F_CPU if prescaling is used on the latter, and is required as the
+#     raw input clock is fed directly to the PLL sections of the AVR for high speed
+#     clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+#     at the end, this will be done automatically to create a 32-bit value in your
+#     source code.
+#
+#     If no clock division is performed on the input clock inside the AVR (via the
+#     CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+
+# Boot Section Size in *bytes*
+#   Teensy halfKay   512
+#   Teensy++ halfKay 1024
+#   Atmel DFU loader 4096
+#   LUFA bootloader  4096
+#   USBaspLoader     2048
+OPT_DEFS += -DBOOTLOADER_SIZE=4096
+
+# Build Options
+#   change to "no" to disable the options, or define them in the Makefile in
+#   the appropriate keymap folder that will get included automatically
+#
+BOOTMAGIC_ENABLE ?= no       # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE ?= yes       # Mouse keys(+4700)
+EXTRAKEY_ENABLE ?= yes       # Audio control and System control(+450)
+CONSOLE_ENABLE ?= no         # Console for debug(+400)
+COMMAND_ENABLE ?= yes        # 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 ?= no      # 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 ?= no       # Enable WS2812 RGB underlight.  Do not enable this with audio at the same time.
+SUBPROJECT_rev1 ?= yes
+USE_I2C ?= yes
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE ?= no    # Breathing sleep LED during USB suspend
+
+CUSTOM_MATRIX = yes
+
+avrdude: build
+	ls /dev/tty* > /tmp/1; \
+	echo "Reset your Pro Micro now"; \
+	while [[ -z $$USB ]]; do \
+	  sleep 1; \
+	  ls /dev/tty* > /tmp/2; \
+	  USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \
+	done; \
+	avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex
+
+.PHONY: avrdude
diff --git a/keyboards/deltasplit75/serial.c b/keyboards/deltasplit75/serial.c
new file mode 100644
index 0000000000..898ef7d426
--- /dev/null
+++ b/keyboards/deltasplit75/serial.c
@@ -0,0 +1,228 @@
+/*

+ * WARNING: be careful changing this code, it is very timing dependent

+ */

+

+#ifndef F_CPU

+#define F_CPU 16000000

+#endif

+

+#include <avr/io.h>

+#include <avr/interrupt.h>

+#include <util/delay.h>

+#include <stdbool.h>

+#include "serial.h"

+

+#ifdef USE_SERIAL

+

+// Serial pulse period in microseconds. Its probably a bad idea to lower this

+// value.

+#define SERIAL_DELAY 24

+

+uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};

+uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};

+

+#define SLAVE_DATA_CORRUPT (1<<0)

+volatile uint8_t status = 0;

+

+inline static

+void serial_delay(void) {

+  _delay_us(SERIAL_DELAY);

+}

+

+inline static

+void serial_output(void) {

+  SERIAL_PIN_DDR |= SERIAL_PIN_MASK;

+}

+

+// make the serial pin an input with pull-up resistor

+inline static

+void serial_input(void) {

+  SERIAL_PIN_DDR  &= ~SERIAL_PIN_MASK;

+  SERIAL_PIN_PORT |= SERIAL_PIN_MASK;

+}

+

+inline static

+uint8_t serial_read_pin(void) {

+  return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);

+}

+

+inline static

+void serial_low(void) {

+  SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;

+}

+

+inline static

+void serial_high(void) {

+  SERIAL_PIN_PORT |= SERIAL_PIN_MASK;

+}

+

+void serial_master_init(void) {

+  serial_output();

+  serial_high();

+}

+

+void serial_slave_init(void) {

+  serial_input();

+

+  // Enable INT0

+  EIMSK |= _BV(INT0);

+  // Trigger on falling edge of INT0

+  EICRA &= ~(_BV(ISC00) | _BV(ISC01));

+}

+

+// Used by the master to synchronize timing with the slave.

+static

+void sync_recv(void) {

+  serial_input();

+  // This shouldn't hang if the slave disconnects because the

+  // serial line will float to high if the slave does disconnect.

+  while (!serial_read_pin());

+  serial_delay();

+}

+

+// Used by the slave to send a synchronization signal to the master.

+static

+void sync_send(void) {

+  serial_output();

+

+  serial_low();

+  serial_delay();

+

+  serial_high();

+}

+

+// Reads a byte from the serial line

+static

+uint8_t serial_read_byte(void) {

+  uint8_t byte = 0;

+  serial_input();

+  for ( uint8_t i = 0; i < 8; ++i) {

+    byte = (byte << 1) | serial_read_pin();

+    serial_delay();

+    _delay_us(1);

+  }

+

+  return byte;

+}

+

+// Sends a byte with MSB ordering

+static

+void serial_write_byte(uint8_t data) {

+  uint8_t b = 8;

+  serial_output();

+  while( b-- ) {

+    if(data & (1 << b)) {

+      serial_high();

+    } else {

+      serial_low();

+    }

+    serial_delay();

+  }

+}

+

+// interrupt handle to be used by the slave device

+ISR(SERIAL_PIN_INTERRUPT) {

+  sync_send();

+

+  uint8_t checksum = 0;

+  for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {

+    serial_write_byte(serial_slave_buffer[i]);

+    sync_send();

+    checksum += serial_slave_buffer[i];

+  }

+  serial_write_byte(checksum);

+  sync_send();

+

+  // wait for the sync to finish sending

+  serial_delay();

+

+  // read the middle of pulses

+  _delay_us(SERIAL_DELAY/2);

+

+  uint8_t checksum_computed = 0;

+  for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {

+    serial_master_buffer[i] = serial_read_byte();

+    sync_send();

+    checksum_computed += serial_master_buffer[i];

+  }

+  uint8_t checksum_received = serial_read_byte();

+  sync_send();

+

+  serial_input(); // end transaction

+

+  if ( checksum_computed != checksum_received ) {

+    status |= SLAVE_DATA_CORRUPT;

+  } else {

+    status &= ~SLAVE_DATA_CORRUPT;

+  }

+}

+

+inline

+bool serial_slave_DATA_CORRUPT(void) {

+  return status & SLAVE_DATA_CORRUPT;

+}

+

+// Copies the serial_slave_buffer to the master and sends the

+// serial_master_buffer to the slave.

+//

+// Returns:

+// 0 => no error

+// 1 => slave did not respond

+int serial_update_buffers(void) {

+  // this code is very time dependent, so we need to disable interrupts

+  cli();

+

+  // signal to the slave that we want to start a transaction

+  serial_output();

+  serial_low();

+  _delay_us(1);

+

+  // wait for the slaves response

+  serial_input();

+  serial_high();

+  _delay_us(SERIAL_DELAY);

+

+  // check if the slave is present

+  if (serial_read_pin()) {

+    // slave failed to pull the line low, assume not present

+    sei();

+    return 1;

+  }

+

+  // if the slave is present syncronize with it

+  sync_recv();

+

+  uint8_t checksum_computed = 0;

+  // receive data from the slave

+  for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {

+    serial_slave_buffer[i] = serial_read_byte();

+    sync_recv();

+    checksum_computed += serial_slave_buffer[i];

+  }

+  uint8_t checksum_received = serial_read_byte();

+  sync_recv();

+

+  if (checksum_computed != checksum_received) {

+    sei();

+    return 1;

+  }

+

+  uint8_t checksum = 0;

+  // send data to the slave

+  for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {

+    serial_write_byte(serial_master_buffer[i]);

+    sync_recv();

+    checksum += serial_master_buffer[i];

+  }

+  serial_write_byte(checksum);

+  sync_recv();

+

+  // always, release the line when not in use

+  serial_output();

+  serial_high();

+

+  sei();

+  return 0;

+}

+

+#endif

diff --git a/keyboards/deltasplit75/serial.h b/keyboards/deltasplit75/serial.h
new file mode 100644
index 0000000000..ab2ea0a096
--- /dev/null
+++ b/keyboards/deltasplit75/serial.h
@@ -0,0 +1,26 @@
+#ifndef MY_SERIAL_H

+#define MY_SERIAL_H

+

+#include "config.h"

+#include <stdbool.h>

+

+/* TODO:  some defines for interrupt setup */

+#define SERIAL_PIN_DDR DDRD

+#define SERIAL_PIN_PORT PORTD

+#define SERIAL_PIN_INPUT PIND

+#define SERIAL_PIN_MASK _BV(PD0)

+#define SERIAL_PIN_INTERRUPT INT0_vect

+

+#define SERIAL_SLAVE_BUFFER_LENGTH ((MATRIX_COLS+7)/8 *MATRIX_ROWS/2)

+#define SERIAL_MASTER_BUFFER_LENGTH 1

+

+// Buffers for master - slave communication

+extern volatile uint8_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];

+extern volatile uint8_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];

+

+void serial_master_init(void);

+void serial_slave_init(void);

+int serial_update_buffers(void);

+bool serial_slave_data_corrupt(void);

+

+#endif

diff --git a/keyboards/deltasplit75/split_util.c b/keyboards/deltasplit75/split_util.c
new file mode 100644
index 0000000000..a636f60dbf
--- /dev/null
+++ b/keyboards/deltasplit75/split_util.c
@@ -0,0 +1,81 @@
+#include <avr/io.h>

+#include <avr/wdt.h>

+#include <avr/power.h>

+#include <avr/interrupt.h>

+#include <util/delay.h>

+#include <avr/eeprom.h>

+#include "split_util.h"

+#include "matrix.h"

+#include "keyboard.h"

+#include "config.h"

+

+#ifdef USE_I2C

+#  include "i2c.h"

+#else

+#  include "serial.h"

+#endif

+

+volatile bool isLeftHand = true;

+

+static void setup_handedness(void) {

+  #ifdef EE_HANDS

+    isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);

+  #else

+    // I2C_MASTER_RIGHT is deprecated use MASTER_RIGHT instead since this works for both serial and i2c

+    #if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)

+      isLeftHand = !has_usb();

+    #else

+      isLeftHand = has_usb();

+    #endif

+  #endif

+}

+

+static void keyboard_master_setup(void) {

+#ifdef USE_I2C

+    i2c_master_init();

+#else

+    serial_master_init();

+#endif

+}

+

+static void keyboard_slave_setup(void) {

+#ifdef USE_I2C

+    i2c_slave_init(SLAVE_I2C_ADDRESS);

+#else

+    serial_slave_init();

+#endif

+}

+

+bool has_usb(void) {

+   USBCON |= (1 << OTGPADE); //enables VBUS pad

+   _delay_us(5);

+   return (USBSTA & (1<<VBUS));  //checks state of VBUS

+}

+

+void split_keyboard_setup(void) {

+   setup_handedness();

+

+   if (has_usb()) {

+      keyboard_master_setup();

+   } else {

+      keyboard_slave_setup();

+   }

+   sei();

+}

+

+void keyboard_slave_loop(void) {

+   matrix_init();

+

+   while (1) {

+      matrix_slave_scan();

+   }

+}

+

+// this code runs before the usb and keyboard is initialized

+void matrix_setup(void) {

+    split_keyboard_setup();

+

+    if (!has_usb()) {

+        keyboard_slave_loop();

+    }

+}

diff --git a/keyboards/deltasplit75/split_util.h b/keyboards/deltasplit75/split_util.h
new file mode 100644
index 0000000000..a1b0447bbd
--- /dev/null
+++ b/keyboards/deltasplit75/split_util.h
@@ -0,0 +1,22 @@
+#ifndef SPLIT_KEYBOARD_UTIL_H

+#define SPLIT_KEYBOARD_UTIL_H

+

+#include <stdbool.h>

+

+#ifdef EE_HANDS

+	#define EECONFIG_BOOTMAGIC_END      (uint8_t *)10

+	#define EECONFIG_HANDEDNESS         EECONFIG_BOOTMAGIC_END

+#endif

+

+#define SLAVE_I2C_ADDRESS           0x32

+

+extern volatile bool isLeftHand;

+

+// slave version of matix scan, defined in matrix.c

+void matrix_slave_scan(void);

+

+void split_keyboard_setup(void);

+bool has_usb(void);

+void keyboard_slave_loop(void);

+

+#endif

diff --git a/keyboards/deltasplit75/v2/Makefile b/keyboards/deltasplit75/v2/Makefile
new file mode 100644
index 0000000000..4e2a6f00fd
--- /dev/null
+++ b/keyboards/deltasplit75/v2/Makefile
@@ -0,0 +1,3 @@
+ifndef MAKEFILE_INCLUDED
+	include ../../Makefile
+endif
\ No newline at end of file
diff --git a/keyboards/deltasplit75/v2/config.h b/keyboards/deltasplit75/v2/config.h
new file mode 100644
index 0000000000..d1f6f7966c
--- /dev/null
+++ b/keyboards/deltasplit75/v2/config.h
@@ -0,0 +1,90 @@
+/*

+Copyright 2012 Jun Wako <wakojun@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 CONFIG_H

+#define CONFIG_H

+

+#include "config_common.h"

+

+/* USB Device descriptor parameter */

+#define VENDOR_ID       0xFEED

+#define PRODUCT_ID      0x3060

+#define DEVICE_VER      0x0001

+#define MANUFACTURER    xyxjj

+#define PRODUCT         DeltaSplit75

+#define DESCRIPTION     75% split keyboard

+

+/* key matrix size */

+// Rows are doubled-up

+#define MATRIX_ROWS 14

+#define MATRIX_COLS 8

+

+// wiring of each half

+#define MATRIX_ROW_PINS { F4, F5, F6, F7, B1, B3, B2 }

+#define MATRIX_COL_PINS { B6, B5, B4, E6, D7, C6, D4, D1}

+

+#define CATERINA_BOOTLOADER

+

+/* COL2ROW or ROW2COL */

+#define DIODE_DIRECTION COL2ROW

+

+/* define if matrix has ghost */

+//#define MATRIX_HAS_GHOST

+

+/* number of backlight levels */

+// #define BACKLIGHT_LEVELS 3

+

+/* Set 0 if debouncing isn't needed */

+#define DEBOUNCING_DELAY 5

+

+/* 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

+

+/* key combination for command */

+#define IS_COMMAND() ( \

+    keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \

+)

+

+/* ws2812 RGB LED */

+#define RGB_DI_PIN D3

+#define RGBLIGHT_TIMER

+#define RGBLED_NUM 12    // Number of LEDs

+#define ws2812_PORTREG  PORTD

+#define ws2812_DDRREG   DDRD

+

+/*

+ * 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

+

+

+#endif
\ No newline at end of file
diff --git a/keyboards/deltasplit75/v2/rules.mk b/keyboards/deltasplit75/v2/rules.mk
new file mode 100644
index 0000000000..80a942d06f
--- /dev/null
+++ b/keyboards/deltasplit75/v2/rules.mk
@@ -0,0 +1,5 @@
+BACKLIGHT_ENABLE = no
+
+ifndef QUANTUM_DIR
+	include ../../../Makefile
+endif
diff --git a/keyboards/deltasplit75/v2/v2.c b/keyboards/deltasplit75/v2/v2.c
new file mode 100644
index 0000000000..a4b54dcfce
--- /dev/null
+++ b/keyboards/deltasplit75/v2/v2.c
@@ -0,0 +1,32 @@
+#include "deltasplit75.h"

+

+#ifdef AUDIO_ENABLE

+    float tone_startup[][2] = SONG(STARTUP_SOUND);

+    float tone_goodbye[][2] = SONG(GOODBYE_SOUND);

+#endif

+

+void matrix_init_kb(void) {

+

+    #ifdef AUDIO_ENABLE

+        _delay_ms(20); // gets rid of tick

+        PLAY_NOTE_ARRAY(tone_startup, false, 0);

+    #endif

+

+    // // green led on

+    // DDRD |= (1<<5);

+    // PORTD &= ~(1<<5);

+

+    // // orange led on

+    // DDRB |= (1<<0);

+    // PORTB &= ~(1<<0);

+

+	matrix_init_user();

+};

+

+void shutdown_user(void) {

+    #ifdef AUDIO_ENABLE

+        PLAY_NOTE_ARRAY(tone_goodbye, false, 0);

+	_delay_ms(150);

+	stop_all_notes();

+    #endif

+}

diff --git a/keyboards/deltasplit75/v2/v2.h b/keyboards/deltasplit75/v2/v2.h
new file mode 100644
index 0000000000..239995ffe6
--- /dev/null
+++ b/keyboards/deltasplit75/v2/v2.h
@@ -0,0 +1,37 @@
+#ifndef v2_H

+#define v2_H

+

+#include "../deltasplit75.h"

+

+//void promicro_bootloader_jmp(bool program);

+#include "quantum.h"

+

+//void promicro_bootloader_jmp(bool program);

+//matrix is defined in a weird way here; the layout on both sides are asymmetrical, but the "matrix" is symmetrical but with empty gaps

+//the last column is defined as a separate row because the firmware currently doesnt support more than 8 columns (this layout has 9 columns per side) K45 and K110 are the Bs on both sides; K53 and K106 are extra keys for ISO

+#define KEYMAP( \

+	K00,   K01,   K02,   K03,   K04,   K05,   K06,       K70,   K71,   K72,   K73,   K74,   K75,   K76,   K77,   K132, \

+	K10,   K11,   K12,   K13,   K14,   K15,   K16,       K80,   K81,   K82,   K83,   K84,   K85,   K86,   K87,   K133, \

+	K20,   K21,   K22,   K23,   K24,   K25,              K90,   K91,   K92,   K93,   K94,   K95,   K96,   K97,   K134, \

+	K30,   K31,   K32,   K33,   K34,   K35,              K100,  K101,  K102,  K103,  K104,  K105,  K106,  K107,  K135, \

+	K40,   K53,   K41,   K42,   K43,   K44,   K45,              K110,  K111,  K112,  K113,  K114,  K115,  K116,  K117,  K136, \

+	K50,   K51,   K52,          K54,   K55,              K120,  K121,  K122,  K123,                K126,  K127,  K137 \

+	) \

+	{ \

+		{ K00,   K01,   K02,   K03,   K04,   K05,   K06,   KC_NO}, \

+		{ K10,   K11,   K12,   K13,   K14,   K15,   K16,   KC_NO}, \

+		{ K20,   K21,   K22,   K23,   K24,   K25,   KC_NO, KC_NO}, \

+		{ K30,   K31,   K32,   K33,   K34,   K35,   KC_NO, KC_NO}, \

+		{ K40,   K41,   K42,   K43,   K44,   K45,   KC_NO, KC_NO}, \

+		{ K50,   K51,   K52,   K53,   K54,   K55,   KC_NO, KC_NO}, \

+		{ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO}, \

+		{ K70  , K71,   K72,   K73,   K74,   K75,   K76,   K77}, \

+		{ K80,   K81,   K82,   K83,   K84,   K85,   K86,   K87}, \

+		{ K90,   K91,   K92,   K93,   K94,   K95,   K96,   K97}, \

+		{ K100,  K101,  K102,  K103,  K104,  K105,  K106, K107}, \

+		{ K110,  K111,  K112,  K113,  K114,  K115,  K116,  K117}, \

+		{ K120,  K121,  K122,  K123,  KC_NO, KC_NO, K126,  K127}, \

+		{ KC_NO, KC_NO, K132,  K133,  K134,  K135,  K136,  K137} \

+	}

+

+#endif
\ No newline at end of file