Browse Source

Keyboard: Fixing spelling, updating code, finalizing keymap for Dichotomy (#4539)

* Fixing spelling, updating code, finalizing keymap for Dichotomy

* Fixing requested changes in PR

* Further PR-requested changes for convention

* Making macros functionable, removing unecessary defs

* Fixing keymap to properly use previously-changed macros
Snipeye 7 years ago
parent
commit
57678238a9

+ 0 - 67
keyboards/dichotemy/dichotemy.h

@@ -1,67 +0,0 @@
-#ifndef DICHOTEMY_H
-#define DICHOTEMY_H
-
-#include "quantum.h"
-#include "matrix.h"
-#include "backlight.h"
-#include <stddef.h>
-
-#define red_led_off   PORTF |= (1<<5)
-#define red_led_on    PORTF &= ~(1<<5)
-#define blu_led_off   PORTF |= (1<<4)
-#define blu_led_on    PORTF &= ~(1<<4)
-#define grn_led_off   PORTD |= (1<<1)
-#define grn_led_on    PORTD &= ~(1<<1)
-
-#define set_led_off     red_led_off; grn_led_off; blu_led_off
-#define set_led_red     red_led_on;  grn_led_off; blu_led_off
-#define set_led_blue    red_led_off; grn_led_off; blu_led_on
-#define set_led_green   red_led_off; grn_led_on;  blu_led_off
-#define set_led_yellow  red_led_on;  grn_led_on;  blu_led_off
-#define set_led_magenta red_led_on;  grn_led_off; blu_led_on
-#define set_led_cyan    red_led_off; grn_led_on;  blu_led_on
-#define set_led_white   red_led_on;  grn_led_on;  blu_led_on
-
-/*
-#define LED_B 5
-#define LED_R 6
-#define LED_G 7
-
-#define all_leds_off PORTF &= ~(1<<LED_B) & ~(1<<LED_R) & ~(1<<LED_G)
-
-#define red_led_on   PORTF |= (1<<LED_R)
-#define red_led_off  PORTF &= ~(1<<LED_R)
-#define grn_led_on   PORTF |= (1<<LED_G)
-#define grn_led_off  PORTF &= ~(1<<LED_G)
-#define blu_led_on   PORTF |= (1<<LED_B)
-#define blu_led_off  PORTF &= ~(1<<LED_B)
-
-#define set_led_off     PORTF &= ~(1<<LED_B) & ~(1<<LED_R) & ~(1<<LED_G)
-#define set_led_red     PORTF = PORTF & ~(1<<LED_B) & ~(1<<LED_G) | (1<<LED_R)
-#define set_led_blue    PORTF = PORTF & ~(1<<LED_G) & ~(1<<LED_R) | (1<<LED_B)
-#define set_led_green   PORTF = PORTF & ~(1<<LED_B) & ~(1<<LED_R) | (1<<LED_G)
-#define set_led_yellow  PORTF = PORTF & ~(1<<LED_B) | (1<<LED_R) | (1<<LED_G)
-#define set_led_magenta PORTF = PORTF & ~(1<<LED_G) | (1<<LED_R) | (1<<LED_B)
-#define set_led_cyan    PORTF = PORTF & ~(1<<LED_R) | (1<<LED_B) | (1<<LED_G)
-#define set_led_white   PORTF |= (1<<LED_B) | (1<<LED_R) | (1<<LED_G)
-*/
-
-// This a shortcut to help you visually see your layout.
-// The first section contains all of the arguements
-// The second converts the arguments into a two-dimensional array
-#define LAYOUT( \
-  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, \
-                 k33, k34, k35,      k36, k37, k38,      \
-                 k43, k44, k45,      k46, k47, k48       \
-) \
-{ \
-	{ 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   }, \
-	{ KC_NO, KC_NO, KC_NO, k33,   k34,   k35,      k36,   k37,   k38,   KC_NO, KC_NO, KC_NO }, \
-	{ KC_NO, KC_NO, KC_NO, k43,   k44,   k45,      k46,   k47,   k48,   KC_NO, KC_NO, KC_NO }  \
-}
-
-#endif

+ 0 - 394
keyboards/dichotemy/keymaps/default/keymap.c

@@ -1,394 +0,0 @@
-// this is the style you want to emulate.
-// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
-
-#include QMK_KEYBOARD_H
-#include "pointing_device.h"
-
-// 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.
-enum dichotemy_layers
-{
-	_BS,
-	_SF,
-	_NM,
-	_NS,
-	_MS
-};
-
-#define LONGPRESS_COUNT 4
-
-enum dichotemy_keycodes
-{
-  CK_1G = SAFE_RANGE,
-  CK_BSPE,
-  CK_QE,
-  CK_TE, //these 4 CK_XXXX keys are special "alternate long-press" keys controlled with unique timers.  Make sure you understand them before you mess with them.
-  NS_HYPH,
-  NS_EQU,
-  NUMKEY,
-  SFTKEY,
-  MOUSE,
-  MS_BTN1,
-  MS_BTN2
-  //MS_BTN3
-};
-
-// Macro definitions for readability
-enum dichotemy_macros
-{
-	VOLU,
-	VOLD,
-	ESCM
-};
-
-#define LONGPRESS_DELAY 150
-#define MAX_TOGGLE_LENGTH 300
-#define TAPPING_TOGGLE 1
-
-// Fillers to make layering more clear
-#define _______ KC_TRNS
-#define XXXXXXX KC_NO
-
-const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
-
-  [_BS] = LAYOUT( /* Base layout, nearly qwerty but with modifications because it's not a full keyboard. Obviously. */
-    CK_TE,   KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,           KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC,
-    NUMKEY,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,           KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, CK_QE,
-    SFTKEY,  KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,           KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, MOUSE,
-                               KC_LCTL, KC_LALT, KC_LGUI,        KC_RGUI, KC_RALT, KC_RCTL,
-                               KC_LBRC, KC_LPRN, KC_QUOT,        KC_SPC,  KC_RPRN, KC_RBRC
-  ),
-
-  [_SF] = LAYOUT( /* Shifted layout, small changes (because angle brackets have been moved to thumb cluster buttons) */
-    _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
-    _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
-    _______, _______, _______, _______, _______, _______,        _______, _______, NS_HYPH, KC_UNDS, _______, _______,
-                               _______, _______, _______,        _______, _______, _______,
-                               _______, KC_LABK, _______,        _______, KC_RABK, _______
-  ),
-
-  [_NM] = LAYOUT( /* Number layout, basically the main function layer */
-    _______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,          KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  _______,
-    _______, CK_1G,   KC_2,    KC_3,    KC_4,    KC_5,           KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    CK_BSPE,
-    _______, KC_F11,  KC_F12,  KC_F13,  KC_F14,  KC_F15,         KC_F16,  KC_F17,  KC_F18,  KC_F19,  KC_F20,  _______,
-                               _______, _______, _______,        _______, _______, _______,
-                               _______, _______, _______,        _______, _______, _______
-  ),
-
-  [_NS] = LAYOUT( /* Shifted number/function layout, for per-key control.  Only active when shift is held, and number is toggled or held */
-    _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
-    _______, _______, _______, _______, _______, _______,        _______, _______, _______, KC_PLUS, NS_EQU,  _______,
-    _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
-                               _______, _______, _______,        _______, _______, _______,
-                               _______, _______, _______,        _______, _______, _______
-  ),
-
-  [_MS] = LAYOUT( /* Mouse layer, including buttons for clicking. */
-    _______, _______, _______, _______, _______, _______,        KC_VOLU, KC_HOME, KC_PGUP, _______, _______, _______,
-    _______, _______, _______, _______, _______, _______,        _______, MS_BTN1, MS_BTN2, _______, _______, _______,
-    _______, _______, _______, _______, _______, _______,        KC_VOLD, KC_END,  KC_PGDN, _______, _______, _______,
-                               _______, _______, _______,        _______, KC_UP,   _______,
-                               _______, _______, _______,        KC_LEFT, KC_DOWN, KC_RGHT
-  )
-
-};
-
-
-const uint16_t PROGMEM fn_actions[] = {
-
-};
-
-static uint16_t special_timers[LONGPRESS_COUNT] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
-static bool special_key_states[LONGPRESS_COUNT] = {0,0,0,0};
-
-static uint16_t shift_timer;
-static uint16_t num_timer;
-static uint16_t mouse_timer;
-
-static bool shift_singular_key = false;
-static bool number_singular_key = false;
-static bool mouse_singular_key = false;
-
-static bool shift_held = false;
-static bool shift_suspended = false;
-report_mouse_t currentReport = {};
-
-bool process_record_user(uint16_t keycode, keyrecord_t *record) {
-
-	//uint8_t layer;
-	//layer = biton32(layer_state);  // get the current layer  //Or don't, I didn't use it.
-
-	 //custom layer handling for tri_layer,
-	switch (keycode) {
-		case NUMKEY:
-			if (record->event.pressed) {
-				num_timer = timer_read();
-				number_singular_key = true;
-				layer_invert(_NM);
-			} else {
-				if (timer_elapsed(num_timer) < MAX_TOGGLE_LENGTH && number_singular_key) {
-					//do nothing, the layer has already been inverted
-				} else {
-					layer_invert(_NM);
-				}
-			}
-			update_tri_layer(_NM, _SF, _NS);
-			return false;
-		break;
-		//SHIFT is handled as LSHIFT in the general case - 'toggle' shoudl activate caps, while the layer is only active when shift is held.
-		case SFTKEY:
-			if (record->event.pressed) {
-				shift_held = true;
-				shift_suspended = false;
-				shift_timer = timer_read();
-				shift_singular_key = true;
-				layer_on(_SF);
-				register_code(KC_LSFT);
-			} else {
-				shift_held = false;
-				if (timer_elapsed(shift_timer) < MAX_TOGGLE_LENGTH && shift_singular_key) {
-					//this was basically a toggle, so activate/deactivate caps lock.
-					SEND_STRING(SS_TAP(X_CAPSLOCK));
-				}
-				layer_off(_SF);
-				unregister_code(KC_LSFT);
-			}
-			update_tri_layer(_NM, _SF, _NS);
-			return false;
-		break;
-		//MOUSE layer needs to be handled the same way as NUMKEY, but differently from shift
-		case MOUSE:
-			if (record->event.pressed) {
-				mouse_timer = timer_read();
-				mouse_singular_key = true;
-				layer_invert(_MS);
-			} else {
-				if (timer_elapsed(mouse_timer) < MAX_TOGGLE_LENGTH && number_singular_key){
-					//do nothing, it was a toggle (and it's already been toggled)
-				} else {
-					layer_invert(_MS);
-				}
-			}
-			return false;
-		break;
-		//Custom macros for strange keys with different long-tap behavior
-		case CK_1G:
-			if (shift_held && shift_suspended){
-				register_code(KC_LSFT);
-				shift_suspended = false;
-			}
-			shift_singular_key = false;
-			number_singular_key = false;
-			mouse_singular_key = false;
-			if (record->event.pressed) {
-				special_timers[CK_1G-SAFE_RANGE] = timer_read();
-			} else {
-				if (special_key_states[CK_1G-SAFE_RANGE]){
-					//key was activated after longpress_delay, need to close those keycodes
-					special_key_states[CK_1G-SAFE_RANGE] = 0;
-					unregister_code(KC_GRAVE);
-				} else {
-					//key was not activated, return macro activating proper, pre-long-tap key
-					SEND_STRING(SS_TAP(X_1));
-				}
-				special_timers[CK_1G-SAFE_RANGE] = 0xFFFF;
-			}
-		break;
-		case CK_BSPE:
-			if (shift_held && shift_suspended){
-				register_code(KC_LSFT);
-				shift_suspended = false;
-			}
-			shift_singular_key = false;
-			number_singular_key = false;
-			mouse_singular_key = false;
-			if (record->event.pressed) {
-				special_timers[CK_BSPE-SAFE_RANGE] = timer_read();
-			} else {
-				if (special_key_states[CK_BSPE-SAFE_RANGE]){
-					//key was activated after longpress_delay, need to close those keycodes
-					special_key_states[CK_BSPE-SAFE_RANGE] = 0;
-					unregister_code(KC_ENTER);
-				} else {
-					//key was not activated, return macro activating proper, pre-long-tap key
-					SEND_STRING(SS_TAP(X_BSLASH));
-				}
-				special_timers[CK_BSPE-SAFE_RANGE] = 0xFFFF;
-			}
-		break;
-		case CK_QE:
-			if (shift_held && shift_suspended){
-				register_code(KC_LSFT);
-				shift_suspended = false;
-			}
-			shift_singular_key = false;
-			number_singular_key = false;
-			mouse_singular_key = false;
-			if (record->event.pressed) {
-				special_timers[CK_QE-SAFE_RANGE] = timer_read();
-			} else {
-				if (special_key_states[CK_QE-SAFE_RANGE]){
-					//key was activated after longpress_delay, need to close those keycodes
-					special_key_states[CK_QE-SAFE_RANGE] = 0;
-					unregister_code(KC_ENTER);
-				} else {
-					//key was not activated, return macro activating proper, pre-long-tap key
-					SEND_STRING(SS_TAP(X_QUOTE));
-				}
-				special_timers[CK_QE-SAFE_RANGE] = 0xFFFF;
-			}
-		break;
-		case CK_TE:
-			if (shift_held && shift_suspended){
-				register_code(KC_LSFT);
-				shift_suspended = false;
-			}
-			if (record->event.pressed) {
-				special_timers[CK_TE-SAFE_RANGE] = timer_read();
-			} else {
-				if (special_key_states[CK_TE-SAFE_RANGE]){
-					//key was activated after longpress_delay, need to close those keycodes
-					special_key_states[CK_TE-SAFE_RANGE] = 0;
-					unregister_code(KC_ENTER);
-				} else {
-					//key was not activated, return macro activating proper, pre-long-tap key
-					SEND_STRING(SS_TAP(X_TAB));
-				}
-				special_timers[CK_TE-SAFE_RANGE] = 0xFFFF;
-			}
-		break;
-		//No-shift keys, they unregister the KC_LSFT code so they can send
-		//unshifted values - but they don't change the bool. if any other
-		//key is pressed and the bool is set, KC_LSFT is registered again.
-		case NS_HYPH:
-			if (record->event.pressed) {
-				shift_suspended = true;
-				unregister_code(KC_LSFT);
-				register_code(KC_MINS);
-			} else {
-				unregister_code(KC_MINS);
-				if (shift_held && shift_suspended){
-					register_code(KC_LSFT);
-					shift_suspended = false;
-				}
-			}
-		break;
-		case NS_EQU:
-			if (record->event.pressed) {
-				shift_suspended = true;
-				unregister_code(KC_LSFT);
-				register_code(KC_EQUAL);
-			} else {
-				unregister_code(KC_EQUAL);
-				if (shift_held && shift_suspended){
-					register_code(KC_LSFT);
-					shift_suspended = false;
-				}
-			}
-		break;
-
-		//mouse buttons, for 1-3, to update the mouse report:
-		case MS_BTN1:
-			currentReport = pointing_device_get_report();
-			if (record->event.pressed) {
-				if (shift_held && shift_suspended){
-					register_code(KC_LSFT);
-					shift_suspended = false;
-				}
-				//update mouse report here
-				currentReport.buttons |= MOUSE_BTN1; //MOUSE_BTN1 is a const defined in report.h
-			} else {
-				//update mouse report here
-				currentReport.buttons &= ~MOUSE_BTN1;
-			}
-			pointing_device_set_report(currentReport);
-		break;
-		case MS_BTN2:
-			currentReport = pointing_device_get_report();
-			if (record->event.pressed) {
-				if (shift_held && shift_suspended){
-					register_code(KC_LSFT);
-					shift_suspended = false;
-				}
-				//update mouse report here
-				currentReport.buttons |= MOUSE_BTN2; //MOUSE_BTN2 is a const defined in report.h
-			} else {
-				//update mouse report here
-			}
-			pointing_device_set_report(currentReport);
-		break;
-		//there is a case for button 3, but that's handled in dichotemy.c, and this is being
-		//disabled to avoid any conflict.
-		/*case MS_BTN3:
-			currentReport = pointing_device_get_report();
-			if (record->event.pressed) {
-				if (shift_held && shift_suspended){
-					register_code(KC_LSFT);
-					shift_suspended = false;
-				}
-				//update mouse report here
-				currentReport.buttons |= MOUSE_BTN3; //MOUSE_BTN2 is a const defined in report.h
-			} else {
-				//update mouse report here
-			}
-			pointing_device_set_report(currentReport);
-		break;*/
-
-		//If any other key was pressed during the layer mod hold period,
-		//then the layer mod was used momentarily, and should block latching
-		//Additionally, if NS_ keys are in use, then shift may be held (but is
-		//disabled for the unshifted keycodes to be send.  Check the bool and
-		//register shift as necessary.
-		default:
-			if (shift_held){
-				register_code(KC_LSFT);
-			}
-			shift_singular_key = false;
-			number_singular_key = false;
-			mouse_singular_key = false;
-		break;
-	}
-	return true;
-};
-
-void matrix_scan_user(void) {
-    uint8_t layer = biton32(layer_state);
-    for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
-		if (timer_elapsed(special_timers[i]) >= LONGPRESS_DELAY && !special_key_states[i]){
-			switch (i + SAFE_RANGE){
-				case CK_1G:
-					register_code(KC_GRAVE);
-				break;
-				case CK_BSPE:
-					register_code(KC_ENTER);
-				break;
-				case CK_QE:
-					register_code(KC_ENTER);
-				break;
-				case CK_TE:
-					register_code(KC_ESCAPE);
-				break;
-			}
-			special_key_states[i] = 1;
-		}
-	}
-    switch (layer) {
-    	case _BS:
-    		set_led_off;
-    		break;
-        case _NM:
-            set_led_blue;
-            break;
-        case _SF:
-            set_led_red;
-            break;
-        case _NS:
-        	set_led_green;
-        	break;
-        default:
-            break;
-    }
-};
-

+ 4 - 4
keyboards/dichotemy/config.h

@@ -24,10 +24,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #define VENDOR_ID       0xFEED
 #define PRODUCT_ID      0xACC7
-#define DEVICE_VER      0x0001
-#define MANUFACTURER    unknown
-#define PRODUCT         Dichotemy
-#define DESCRIPTION     q.m.k. keyboard firmware for Dichotemy
+#define DEVICE_VER      0x0002
+#define MANUFACTURER    Broekhuijsen
+#define PRODUCT         Dichotomy
+#define DESCRIPTION     q.m.k. keyboard firmware for Dichotomy
 
 /* key matrix size */
 #define MATRIX_ROWS 5

+ 15 - 12
keyboards/dichotemy/dichotemy.c

@@ -1,13 +1,11 @@
-#include "dichotemy.h"
-#include "pointing_device.h"
-#include "report.h"
+#include "dichotomy.h"
 
 void uart_init(void) {
 	SERIAL_UART_INIT();
 }
 
 void pointing_device_task(void){
-	report_mouse_t currentReport = {};
+	/*report_mouse_t currentReport = {};
     SERIAL_UART_INIT();
     uint32_t timeout = 0;
 
@@ -25,28 +23,31 @@ void pointing_device_task(void){
         while(!SERIAL_UART_RXD_PRESENT){
             timeout++;
             if (timeout > 10000){
+		xprintf("\r\nTIMED OUT");
                 break;
             }
-        } 
+        }
+	xprintf("\r\nGOT DATA for %d",i);
         uart_data[i] = SERIAL_UART_DATA;
     }
 
-    //check for the end packet, bits 1-4 are movement and scroll
-    //but bit 5 has bits 0-3 for the scroll button state
+    //check for the end packet, bytes 1-4 are movement and scroll
+    //but byte 5 has bits 0-3 for the scroll button state
 	//(1000 if pressed, 0000 if not) and bits 4-7 are always 1
 	//We can use this to verify the report sent properly.
     if (uart_data[4] == 0x0F || uart_data[4] == 0x8F)
     {
+	xprintf("\r\nREQUESTED MOUSE, RECEIVED %i, %i, %i, %i, %i",uart_data[0],uart_data[1],uart_data[2],uart_data[3],uart_data[4]);
 		currentReport = pointing_device_get_report();
         //shifting and transferring the info to the mouse report varaible
         //mouseReport.x = 127 max -127 min
-		currentReport.x = uart_data[0];
+		currentReport.x = (int8_t) uart_data[0];
         //mouseReport.y = 127 max -127 min
-		currentReport.y = uart_data[1];
+		currentReport.y = (int8_t) uart_data[1];
         //mouseReport.v = 127 max -127 min (scroll vertical)
-		currentReport.v = uart_data[2];
+		currentReport.v = (int8_t) uart_data[2];
         //mouseReport.h = 127 max -127 min (scroll horizontal)
-		currentReport.h = uart_data[3];
+		currentReport.h = (int8_t) uart_data[3];
         //mouseReport.buttons = 0x31 max (bitmask for mouse buttons 1-5) 0x00 min
 		//mouse buttons 1 and 2 are handled by the keymap, but not 3
 		if (uart_data[4] == 0x0F) { //then 3 is not pressed
@@ -55,7 +56,9 @@ void pointing_device_task(void){
 			currentReport.buttons |= MOUSE_BTN3;
 		}
 		pointing_device_set_report(currentReport);
-    }
+    } else {
+	xprintf("\r\nRequested packet, data 4 was %d",uart_data[4]);
+    }*/
     pointing_device_send();
 }
 

+ 46 - 0
keyboards/dichotomy/dichotomy.h

@@ -0,0 +1,46 @@
+#ifndef DICHOTOMY_H
+#define DICHOTOMY_H
+
+#include QMK_KEYBOARD_H
+#include "report.h"
+#include "pointing_device.h"
+#include "quantum.h"
+#include "matrix.h"
+#include "backlight.h"
+#include <stddef.h>
+
+#define red_led_off()   PORTF |= (1<<6)
+#define red_led_on()    PORTF &= ~(1<<6)
+#define blu_led_off()   PORTF |= (1<<5)
+#define blu_led_on()    PORTF &= ~(1<<5)
+#define grn_led_off()   PORTD |= (1<<1)
+#define grn_led_on()    PORTD &= ~(1<<1)
+
+#define set_led_off()     red_led_off(); grn_led_off(); blu_led_off()
+#define set_led_red()     red_led_on();  grn_led_off(); blu_led_off()
+#define set_led_blue()    red_led_off(); grn_led_off(); blu_led_on()
+#define set_led_green()   red_led_off(); grn_led_on();  blu_led_off()
+#define set_led_yellow()  red_led_on();  grn_led_on();  blu_led_off()
+#define set_led_magenta() red_led_on();  grn_led_off(); blu_led_on()
+#define set_led_cyan()    red_led_off(); grn_led_on();  blu_led_on()
+#define set_led_white()   red_led_on();  grn_led_on();  blu_led_on()
+
+// This a shortcut to help you visually see your layout.
+// The first section contains all of the arguements
+// The second converts the arguments into a two-dimensional array
+#define LAYOUT( \
+  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, \
+                 k33, k34, k35,      k36, k37, k38,      \
+            k42, k43, k44, k45,      k46, k47, k48, k49  \
+) \
+{ \
+	{ 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   }, \
+	{ KC_NO, KC_NO, KC_NO, k33,   k34,   k35,      k36,   k37,   k38,   KC_NO, KC_NO, KC_NO }, \
+	{ KC_NO, KC_NO, k42,   k43,   k44,   k45,      k46,   k47,   k48,   k49,   KC_NO, KC_NO }  \
+}
+
+#endif

+ 1 - 1
keyboards/dichotemy/info.json

@@ -1,5 +1,5 @@
 {
-  "keyboard_name": "Dichotemy",
+  "keyboard_name": "Dichotomy",
   "url": "",
   "maintainer": "qmk",
   "width": 13,

+ 506 - 0
keyboards/dichotomy/keymaps/default/keymap.c

@@ -0,0 +1,506 @@
+// this is the style you want to emulate.
+// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
+
+#include "dichotomy.h"
+
+// 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.
+enum dichotomy_layers {
+	_BS,
+	_SF,
+	_NM,
+	_NS,
+	_MS
+};
+
+#define LONGPRESS_COUNT 4
+
+enum dichotomy_keycodes
+{
+  CK_1G = SAFE_RANGE,
+  CK_BSPE,
+  CK_QE,
+  CK_TE, //these 4 CK_XXXX keys are special "alternate long-press" keys controlled with unique timers.  Make sure you understand them before you mess with them.
+  NS_HYPH,
+  NS_EQU,
+  NUMKEY,
+  SFTKEY,
+  MOUKEY,
+  MS_BTN1,
+  MS_BTN2,
+  MS_BTN3
+};
+
+#define CUSTOM_LONGPRESS 150
+#define CUSTOM_TOGGLE_TIME 300
+
+#define RED_BRIGHTNESS 3
+#define GREEN_BRIGHTNESS 2
+#define BLUE_BRIGHTNESS 2
+
+// Fillers to make layering more clear
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+[_BS] = LAYOUT( /* Base layout, nearly qwerty but with modifications because it's not a full keyboard. Obviously. */
+  CK_TE,   KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,           KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC,
+  NUMKEY,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,           KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, CK_QE,
+  SFTKEY,  KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,           KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, MOUKEY,
+                             KC_LCTL, KC_LALT, KC_LGUI,        KC_RGUI, KC_RALT, KC_RCTL,
+                    MS_BTN3, KC_LBRC, KC_LPRN, KC_SPC,         KC_SPC,  KC_RPRN, KC_RBRC, MS_BTN3
+),
+
+[_SF] = LAYOUT( /* Shifted layout, small changes (because angle brackets have been moved to thumb cluster buttons) */
+  _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
+  _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
+  _______, _______, _______, _______, _______, _______,        _______, _______, NS_HYPH, KC_UNDS, _______, _______,
+                             _______, _______, _______,        _______, _______, _______,
+                    _______, _______, KC_LABK, _______,        _______, KC_RABK, _______, _______
+),
+
+[_NM] = LAYOUT( /* Number layout, basically the main function layer */
+  _______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,          KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  _______,
+  _______, CK_1G,   KC_2,    KC_3,    KC_4,    KC_5,           KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    CK_BSPE,
+  _______, KC_F11,  KC_F12,  KC_F13,  KC_F14,  KC_F15,         KC_F16,  KC_F17,  KC_F18,  KC_F19,  KC_F20,  _______,
+                             _______, _______, _______,        _______, _______, _______,
+                    _______, _______, _______, _______,        _______, _______, _______, _______
+),
+
+[_NS] = LAYOUT( /* Shifted number/function layout, for per-key control.  Only active when shift is held, and number is toggled or held */
+  _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
+  _______, _______, _______, _______, _______, _______,        _______, _______, _______, KC_PLUS, NS_EQU,  _______,
+  _______, _______, _______, _______, _______, _______,        _______, _______, _______, _______, _______, _______,
+  							 _______, _______, _______,        _______, _______, _______,
+					_______, _______, _______, _______,        _______, _______, _______, _______
+),
+
+[_MS] = LAYOUT( /* Mouse layer, including buttons for clicking. */
+  _______, _______, _______, _______, _______, _______,        KC_VOLU, KC_HOME, KC_PGUP, _______, _______, _______,
+  _______, _______, _______, _______, _______, _______,        _______, MS_BTN1, MS_BTN2, _______, _______, _______,
+  _______, _______, _______, _______, _______, _______,        KC_VOLD, KC_END,  KC_PGDN, _______, _______, _______,
+  							 _______, _______, _______,        _______, KC_UP,   _______,
+					_______, _______, _______, _______,        KC_LEFT, KC_DOWN, KC_RGHT, _______
+)
+
+};
+
+
+const uint16_t PROGMEM fn_actions[] = {
+
+};
+
+static uint16_t special_timers[LONGPRESS_COUNT] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
+static bool special_key_states[LONGPRESS_COUNT] = {0,0,0,0};
+static bool special_key_pressed[LONGPRESS_COUNT] = {0,0,0,0};
+
+static uint16_t shift_timer;
+static uint16_t num_timer;
+static uint16_t mouse_timer;
+
+static uint8_t red_timer;
+static uint8_t green_timer;
+static uint8_t blue_timer;
+
+static bool shift_singular_key = false;
+static bool number_singular_key = false;
+static bool mouse_singular_key = false;
+static bool capsLED = false;
+static bool shiftLED = false;
+static bool numLED = false;
+static bool mouseLED = false;
+
+static bool shift_held = false;
+static bool shift_suspended = false;
+report_mouse_t currentReport = {};
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+	//uint8_t layer;
+	//layer = biton32(layer_state);  // get the current layer  //Or don't, I didn't use it.
+	bool returnVal = true; //this is to determine if more key processing is needed.
+
+	 //custom layer handling for tri_layer,
+	switch (keycode) {
+		case NUMKEY:
+			if (record->event.pressed) {
+				num_timer = timer_read();
+				number_singular_key = true;
+				layer_invert(_NM);
+				numLED = !numLED;
+			} else {
+				if (timer_elapsed(num_timer) < CUSTOM_TOGGLE_TIME && number_singular_key) {
+					//do nothing, the layer has already been inverted
+				} else {
+					layer_invert(_NM);
+					numLED = !numLED;
+				}
+			}
+			update_tri_layer(_NM, _SF, _NS);
+			returnVal = false;
+		break;
+		//SHIFT is handled as LSHIFT in the general case - 'toggle' shoudl activate caps, while the layer is only active when shift is held.
+		case SFTKEY:
+			if (record->event.pressed) {
+				shift_held = true;
+				shiftLED = true;
+				shift_suspended = false;
+				shift_timer = timer_read();
+				shift_singular_key = true;
+				layer_on(_SF);
+				register_code(KC_LSFT);
+			} else {
+				shift_held = false;
+				shiftLED = false;
+				if (timer_elapsed(shift_timer) < CUSTOM_TOGGLE_TIME && shift_singular_key) {
+					//this was basically a toggle, so activate/deactivate caps lock.
+					SEND_STRING(SS_TAP(X_CAPSLOCK));
+					capsLED = !capsLED;
+				}
+				layer_off(_SF);
+				unregister_code(KC_LSFT);
+			}
+			update_tri_layer(_NM, _SF, _NS);
+			returnVal = false;
+		break;
+		//MOUSE layer needs to be handled the same way as NUMKEY, but differently from shift
+		case MOUKEY:
+			if (record->event.pressed) {
+				mouse_timer = timer_read();
+				mouse_singular_key = true;
+				layer_invert(_MS);
+				mouseLED = !mouseLED;
+			} else {
+				if (timer_elapsed(mouse_timer) < CUSTOM_TOGGLE_TIME && mouse_singular_key){
+					//do nothing, it was a toggle (and it's already been toggled)
+				} else {
+					layer_invert(_MS);
+					mouseLED = !mouseLED;
+				}
+			}
+			returnVal = false;
+		break;
+		//Custom macros for strange keys with different long-tap behavior
+		case CK_1G:
+			if (shift_held && shift_suspended){
+				register_code(KC_LSFT);
+				shift_suspended = false;
+			}
+			if (record->event.pressed) {
+				special_timers[CK_1G-SAFE_RANGE] = timer_read();
+				special_key_pressed[CK_1G-SAFE_RANGE] = 1;
+			} else {
+				if (special_key_states[CK_1G-SAFE_RANGE]){
+					//key was activated after custom_longpress, need to close those keycodes
+					special_key_states[CK_1G-SAFE_RANGE] = 0;
+					unregister_code(KC_GRAVE);
+				} else {
+					if (special_key_pressed[CK_1G-SAFE_RANGE]){
+						//key was not activated, return macro activating proper, pre-long-tap key
+						SEND_STRING(SS_TAP(X_1));
+						special_key_pressed[CK_1G-SAFE_RANGE] = 0;
+					} else {
+						//the short key was already sent, because another key was pressed.
+						//Do nothing.
+					}
+
+				}
+			}
+			returnVal = false;
+		break;
+		case CK_BSPE:
+			if (shift_held && shift_suspended){
+				register_code(KC_LSFT);
+				shift_suspended = false;
+			}
+			if (record->event.pressed) {
+				special_timers[CK_BSPE-SAFE_RANGE] = timer_read();
+				special_key_pressed[CK_BSPE-SAFE_RANGE] = 1;
+			} else {
+				if (special_key_states[CK_BSPE-SAFE_RANGE]){
+					//key was activated after custom_longpress, need to close those keycodes
+					special_key_states[CK_BSPE-SAFE_RANGE] = 0;
+					unregister_code(KC_ENTER);
+				} else {
+					if (special_key_pressed[CK_BSPE-SAFE_RANGE]){
+						//key was not activated, return macro activating proper, pre-long-tap key
+						SEND_STRING(SS_TAP(X_BSLASH));
+						special_key_pressed[CK_BSPE-SAFE_RANGE] = 0;
+					} else {
+						//the short key was already sent, because another key was pressed.
+						//Do nothing.
+					}
+				}
+			}
+			returnVal = false;
+		break;
+		case CK_QE:
+			if (shift_held && shift_suspended){
+				register_code(KC_LSFT);
+				shift_suspended = false;
+			}
+			if (record->event.pressed) {
+				special_timers[CK_QE-SAFE_RANGE] = timer_read();
+				special_key_pressed[CK_QE-SAFE_RANGE] = 1;
+			} else {
+				if (special_key_states[CK_QE-SAFE_RANGE]){
+					//key was activated after custom_longpress, need to close those keycodes
+					special_key_states[CK_QE-SAFE_RANGE] = 0;
+					unregister_code(KC_ENTER);
+				} else {
+					if (special_key_pressed[CK_QE-SAFE_RANGE]){
+						//the long-press key was not activated, return macro activating proper, pre-long-tap key
+						SEND_STRING(SS_TAP(X_QUOTE));
+						special_key_pressed[CK_QE-SAFE_RANGE] = 0;
+					} else {
+						//the short key was already sent, because another key was pressed.
+						//Do nothing.
+					}
+				}
+			}
+			returnVal = false;
+		break;
+		case CK_TE:
+			if (shift_held && shift_suspended){
+				register_code(KC_LSFT);
+				shift_suspended = false;
+			}
+			if (record->event.pressed) {
+				special_timers[CK_TE-SAFE_RANGE] = timer_read();
+				special_key_pressed[CK_TE-SAFE_RANGE] = 1;
+			} else {
+				if (special_key_states[CK_TE-SAFE_RANGE]){
+					//key was activated after custom_longpress, need to close those keycodes
+					special_key_states[CK_TE-SAFE_RANGE] = 0;
+					unregister_code(KC_ESCAPE);
+				} else {
+					if (special_key_pressed[CK_TE-SAFE_RANGE]){
+						//the long-press key was not activated, return macro activating proper, pre-long-tap key
+						SEND_STRING(SS_TAP(X_TAB));
+						special_key_pressed[CK_TE-SAFE_RANGE] = 0;
+					} else {
+						//the short key was already sent, because another key was pressed.
+						//Do nothing.
+					}
+				}
+			}
+			returnVal = false;
+		break;
+		//No-shift keys, they unregister the KC_LSFT code so they can send
+		//unshifted values - but they don't change the bool. if any other
+		//key is pressed and the bool is set, KC_LSFT is registered again.
+		case NS_HYPH:
+			if (record->event.pressed) {
+				shift_suspended = true;
+				unregister_code(KC_LSFT);
+				register_code(KC_MINS);
+			} else {
+				unregister_code(KC_MINS);
+				if (shift_held && shift_suspended){
+					register_code(KC_LSFT);
+					shift_suspended = false;
+				}
+			}
+			returnVal = false;
+		break;
+		case NS_EQU:
+			if (record->event.pressed) {
+				shift_suspended = true;
+				unregister_code(KC_LSFT);
+				register_code(KC_EQUAL);
+			} else {
+				unregister_code(KC_EQUAL);
+				if (shift_held && shift_suspended){
+					register_code(KC_LSFT);
+					shift_suspended = false;
+				}
+			}
+			returnVal = false;
+		break;
+
+		//mouse buttons, for 1-3, to update the mouse report:
+		case MS_BTN1:
+			currentReport = pointing_device_get_report();
+			if (record->event.pressed) {
+				if (shift_held && shift_suspended){
+					register_code(KC_LSFT);
+					shift_suspended = false;
+				}
+				//update mouse report here
+				currentReport.buttons |= MOUSE_BTN1; //MOUSE_BTN1 is a const defined in report.h
+			} else {
+				//update mouse report here
+				currentReport.buttons &= ~MOUSE_BTN1;
+			}
+			pointing_device_set_report(currentReport);
+			returnVal = false;
+		break;
+		case MS_BTN2:
+			currentReport = pointing_device_get_report();
+			if (record->event.pressed) {
+				if (shift_held && shift_suspended){
+					register_code(KC_LSFT);
+					shift_suspended = false;
+				}
+				//update mouse report here
+				currentReport.buttons |= MOUSE_BTN2; //MOUSE_BTN2 is a const defined in report.h
+			} else {
+				//update mouse report here
+				currentReport.buttons &= ~MOUSE_BTN2;
+			}
+			pointing_device_set_report(currentReport);
+			returnVal = false;
+		break;
+		case MS_BTN3:
+			currentReport = pointing_device_get_report();
+			if (record->event.pressed) {
+				if (shift_held && shift_suspended){
+					register_code(KC_LSFT);
+					shift_suspended = false;
+				}
+				//update mouse report here
+				currentReport.buttons |= MOUSE_BTN3; //MOUSE_BTN3 is a const defined in report.h
+			} else {
+				//update mouse report here
+				currentReport.buttons &= ~MOUSE_BTN3;
+			}
+			pointing_device_set_report(currentReport);
+			returnVal = false;
+		break;
+		//Additionally, if NS_ keys are in use, then shift may be held (but is
+		//disabled for the unshifted keycodes to be send.  Check the bool and
+		//register shift as necessary.
+		default:
+			if (shift_held){
+				register_code(KC_LSFT);
+			}
+		break;
+	}
+	switch (keycode){
+		case KC_BSPC:
+		case KC_NO:
+		case NUMKEY:
+		case SFTKEY:
+		case MOUKEY:
+			//don't want to reset single key variables
+		break;
+		default:
+			//If any other key was pressed during the layer mod hold period,
+			//then the layer mod was used momentarily, and should block latching
+			shift_singular_key = false;
+			number_singular_key = false;
+			mouse_singular_key = false;
+		break;
+	}
+	switch (keycode){
+		case KC_BSPC:
+		case KC_NO:
+		case NUMKEY:
+		case SFTKEY:
+		case MOUKEY:
+		case MOUSE_BTN1:
+		case MOUSE_BTN2:
+		case MOUSE_BTN3:
+		case KC_LCTL:
+		case KC_LALT:
+		case KC_LGUI:
+		case KC_RCTL:
+		case KC_RALT:
+		case KC_RGUI:
+		case CK_1G:
+		case CK_BSPE:
+		case CK_QE:
+		case CK_TE:
+			//Do nothing, don't want to trigger the timer key rollover
+		break;
+		default:
+			//Now we're checking to see if any of the special timer keys are pressed
+			//if so, we need to activate their short-press features
+			if (record->event.pressed) {
+				for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
+					if ((!special_key_states[i]) && special_key_pressed[i]){
+						switch (i + SAFE_RANGE){
+							case CK_1G:
+								SEND_STRING(SS_TAP(X_1));
+							break;
+							case CK_BSPE:
+								SEND_STRING(SS_TAP(X_BSLASH));
+							break;
+							case CK_QE:
+								SEND_STRING(SS_TAP(X_QUOTE));
+							break;
+							case CK_TE:
+								SEND_STRING(SS_TAP(X_TAB));
+							break;
+						}
+						special_key_pressed[i] = 0;
+					}
+				}
+			} else {
+				//do nothing, we don't want to trigger short presses on key releases.
+			}
+		break;
+	}
+	return returnVal;
+};
+
+void matrix_scan_user(void) {
+	//uint8_t layer = biton32(layer_state);
+	for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
+		if ((timer_elapsed(special_timers[i]) >= CUSTOM_LONGPRESS) && (!special_key_states[i]) && special_key_pressed[i]){
+			switch (i + SAFE_RANGE){
+				case CK_1G:
+					register_code(KC_GRAVE);
+				break;
+				case CK_BSPE:
+					register_code(KC_ENTER);
+				break;
+				case CK_QE:
+					register_code(KC_ENTER);
+				break;
+				case CK_TE:
+					register_code(KC_ESCAPE);
+				break;
+			}
+			special_key_pressed[i] = 0;
+			special_key_states[i] = 1;
+		}
+	}
+    if (shiftLED || capsLED){
+		red_timer++;
+		if (red_timer < RED_BRIGHTNESS){
+			red_led_on();
+		} else {
+			red_timer = 0;
+			red_led_off();
+		}
+    } else {
+		red_timer = 0;
+		red_led_off();
+    }
+    if (numLED){
+		green_timer++;
+		if (green_timer < GREEN_BRIGHTNESS){
+			grn_led_on();
+		} else {
+			green_timer = 0;
+			grn_led_off();
+		}
+    } else {
+		green_timer = 0;
+		grn_led_off();
+    }
+    if (mouseLED){
+		blue_timer++;
+		if (blue_timer < BLUE_BRIGHTNESS){
+			blu_led_on();
+		} else {
+			blue_timer = 0;
+			blu_led_off();
+		}
+    } else {
+		blue_timer = 0;
+		blu_led_off();
+    }
+};

+ 69 - 9
keyboards/dichotemy/matrix.c

@@ -26,6 +26,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "util.h"
 #include "matrix.h"
 #include "timer.h"
+#include "dichotomy.h"
+#include "pointing_device.h"
+#include "report.h"
 
 #if (MATRIX_COLS <= 8)
 #    define print_matrix_header()  print("\nr/c 01234567\n")
@@ -45,12 +48,22 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #endif
 
 #define MAIN_ROWMASK 0xFFF0;
-#define LOWER_ROWMASK 0x1F80;
+#define LOWER_ROWMASK 0x3FC0;
 
 /* matrix state(1:on, 0:off) */
 static matrix_row_t matrix[MATRIX_ROWS];
 
 __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();
 }
@@ -79,13 +92,16 @@ uint8_t matrix_cols(void) {
 }
 
 void matrix_init(void) {
-
+    DDRF |= (1<<6);
+    DDRF |= (1<<5);
+    DDRD |= (1<<1);
     matrix_init_quantum();
 }
 
 uint8_t matrix_scan(void)
 {
     SERIAL_UART_INIT();
+    //xprintf("\r\nTRYING TO SCAN");
 
     uint32_t timeout = 0;
 
@@ -93,25 +109,35 @@ uint8_t matrix_scan(void)
     SERIAL_UART_DATA = 's';
 
     //trust the external keystates entirely, erase the last data
-    uint8_t uart_data[7] = {0};
+    uint8_t uart_data[11] = {0};
 
     //there are 10 bytes corresponding to 10 columns, and an end byte
-    for (uint8_t i = 0; i < 7; i++) {
+    for (uint8_t i = 0; i < 11; i++) {
         //wait for the serial data, timeout if it's been too long
         //this only happened in testing with a loose wire, but does no
         //harm to leave it in here
         while(!SERIAL_UART_RXD_PRESENT){
             timeout++;
             if (timeout > 10000){
+		xprintf("\r\nTime out in keyboard.");
                 break;
             }
-        } 
+        }
         uart_data[i] = SERIAL_UART_DATA;
     }
 
     //check for the end packet, the key state bytes use the LSBs, so 0xE0
     //will only show up here if the correct bytes were recieved
-    if (uart_data[6] == 0x96) { //this is an arbitrary binary checksum (10010110)
+            uint8_t checksum = 0x00;
+            for (uint8_t z=0; z<10; z++){
+                checksum = checksum^uart_data[z];
+            }
+            checksum = checksum ^ (uart_data[10] & 0xF0);
+            // Smash the checksum from 1 byte into 4 bits
+            checksum = (checksum ^ ((checksum & 0xF0)>>4)) & 0x0F;
+//xprintf("\r\nGOT RAW PACKET: \r\n%d\r\n%d\r\n%d\r\n%d\r\n%d\r\n%d\r\n%d\r\n%d\r\n%d\r\n%d\r\n%d\r\n%d",uart_data[0],uart_data[1],uart_data[2],uart_data[3],uart_data[4],uart_data[5],uart_data[6],uart_data[7],uart_data[8],uart_data[9],uart_data[10],checksum);
+    if ((uart_data[10] & 0x0F) == checksum) { //this is an arbitrary binary checksum (1001) (that would be 0x9.)
+	//xprintf("\r\nGOT PACKET: \r\n%d\r\n%d\r\n%d\r\n%d\r\n%d\r\n%d",uart_data[0],uart_data[1],uart_data[2],uart_data[3],uart_data[4],uart_data[5]);
         //shifting and transferring the keystates to the QMK matrix variable
 		//bits 1-12 are row 1, 13-24 are row 2, 25-36 are row 3,
 		//bits 37-42 are row 4 (only 6 wide, 1-3 are 0, and 10-12 are 0)
@@ -121,15 +147,49 @@ uint8_t matrix_scan(void)
 		matrix[1] = ((uint16_t) uart_data[1] << 12) | ((uint16_t) uart_data[2] << 4);
 		matrix[2] = (((uint16_t) uart_data[3] << 8) | ((uint16_t) uart_data[4])) & MAIN_ROWMASK;
 		matrix[3] = (((uint16_t) uart_data[4] << 9) | ((uint16_t) uart_data[5] << 1)) & LOWER_ROWMASK;
-		matrix[4] = ((uint16_t) uart_data[5] << 7) & LOWER_ROWMASK;
+		matrix[4] = (((uint16_t) uart_data[5] << 7) | ((uart_data[10] & 1<<7) ? 1:0) << 13 | ((uart_data[10] & 1<<6) ? 1:0) << 6) & LOWER_ROWMASK;
 		/* OK, TURNS OUT THAT WAS A BAD ASSUMPTION */
         for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
 			//I've unpacked these into the mirror image of what QMK expects them to be, so...
-			matrix[i] = ((matrix[i] * 0x0802LU & 0x22110LU) | (matrix[i] * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
+			/*uint8_t halfOne = (matrix[i]>>8);
+			uint8_t halfTwo = (matrix[i] & 0xFF);
+			halfOne = ((halfOne * 0x0802LU & 0x22110LU) | (halfOne * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
+			halfTwo = ((halfTwo * 0x0802LU & 0x22110LU) | (halfTwo * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
+			matrix[i] = ((halfTwo<<8) & halfOne);*/
+			//matrix[i] = ((matrix[i] * 0x0802LU & 0x22110LU) | (matrix[i] * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
+			matrix[i] = bitrev16(matrix[i]);
 			//bithack mirror!  Doesn't make any sense, but works - and efficiently.
         }
+	//if (uart_data[6]!=0 || uart_data[7]!=0){
+	//if (maxCount<101){
+	//	xprintf("\r\nMouse data: x=%d, y=%d",(int8_t)uart_data[6],(int8_t)uart_data[7]);
+	//}
+	report_mouse_t currentReport = {};
+        //check for the end packet, bytes 1-4 are movement and scroll
+        //but byte 5 has bits 0-3 for the scroll button state
+	//(1000 if pressed, 0000 if not) and bits 4-7 are always 1
+	//We can use this to verify the report sent properly.
+
+	currentReport = pointing_device_get_report();
+        //shifting and transferring the info to the mouse report varaible
+        //mouseReport.x = 127 max -127 min
+	currentReport.x = (int8_t) uart_data[6];
+        //mouseReport.y = 127 max -127 min
+	currentReport.y = (int8_t) uart_data[7];
+        //mouseReport.v = 127 max -127 min (scroll vertical)
+	currentReport.v = (int8_t) uart_data[8];
+        //mouseReport.h = 127 max -127 min (scroll horizontal)
+	currentReport.h = (int8_t) uart_data[9];
+	/*
+	currentReport.x = 0;
+	currentReport.y = 0;
+	currentReport.v = 0;
+	currentReport.h = 0;*/
+	pointing_device_set_report(currentReport);
+    } else {
+	//xprintf("\r\nRequested packet, data 10 was %d but checksum was %d",(uart_data[10] & 0x0F), (checksum & 0x0F));
     }
-
+    //matrix_print();
 
     matrix_scan_quantum();
     return 1;

File diff suppressed because it is too large
+ 1 - 1
keyboards/dichotemy/readme.md


+ 9 - 7
keyboards/dichotemy/rules.mk

@@ -1,6 +1,6 @@
 
-OPT_DEFS += -DDICHOTEMY_PROMICRO
-DICHOTEMY_UPLOAD_COMMAND = while [ ! -r $(USB) ]; do sleep 1; done; \
+OPT_DEFS += -DDICHOTOMY_PROMICRO
+DICHOTOMY_UPLOAD_COMMAND = while [ ! -r $(USB) ]; do sleep 1; done; \
                          avrdude -p $(MCU) -c avr109 -U flash:w:$(TARGET).hex -P $(USB)
 
 # # project specific files
@@ -24,6 +24,8 @@ MCU = atmega32u4
 #     software delays.
 F_CPU = 16000000
 
+
+#
 # LUFA specific
 #
 # Target architecture (see library "Board Types" documentation).
@@ -43,10 +45,10 @@ ARCH = AVR8
 F_USB = $(F_CPU)
 
 # Bootloader
-#     This definition is optional, and if your keyboard supports multiple bootloaders of
-#     different sizes, comment this out, and the correct address will be loaded 
-#     automatically (+60). See bootloader.mk for all options.
-BOOTLOADER = caterina
+ #     This definition is optional, and if your keyboard supports multiple bootloaders of
+ #     different sizes, comment this out, and the correct address will be loaded
+ #     automatically (+60). See bootloader.mk for all options.
+ BOOTLOADER = caterina
 
 # Interrupt driven control endpoint task(+60)
 OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
@@ -72,4 +74,4 @@ UNICODE_ENABLE = YES 		# Unicode
 USB = /dev/ttyACM0
 
 #upload: build
-#	$(DICHOTEMY_UPLOAD_COMMAND)
+#	$(DICHOTOMY_UPLOAD_COMMAND)