aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keyboards/dichotemy/dichotemy.h67
-rw-r--r--keyboards/dichotemy/keymaps/default/keymap.c394
-rwxr-xr-x[-rw-r--r--]keyboards/dichotomy/config.h (renamed from keyboards/dichotemy/config.h)8
-rwxr-xr-x[-rw-r--r--]keyboards/dichotomy/dichotomy.c (renamed from keyboards/dichotemy/dichotemy.c)27
-rwxr-xr-xkeyboards/dichotomy/dichotomy.h46
-rw-r--r--keyboards/dichotomy/info.json (renamed from keyboards/dichotemy/info.json)2
-rwxr-xr-xkeyboards/dichotomy/keymaps/default/keymap.c506
-rwxr-xr-x[-rw-r--r--]keyboards/dichotomy/matrix.c (renamed from keyboards/dichotemy/matrix.c)78
-rwxr-xr-x[-rw-r--r--]keyboards/dichotomy/readme.md (renamed from keyboards/dichotemy/readme.md)2
-rwxr-xr-x[-rw-r--r--]keyboards/dichotomy/rules.mk (renamed from keyboards/dichotemy/rules.mk)16
10 files changed, 651 insertions, 495 deletions
diff --git a/keyboards/dichotemy/dichotemy.h b/keyboards/dichotemy/dichotemy.h
deleted file mode 100644
index 1d617d91c..000000000
--- a/keyboards/dichotemy/dichotemy.h
+++ /dev/null
@@ -1,67 +0,0 @@
1#ifndef DICHOTEMY_H
2#define DICHOTEMY_H
3
4#include "quantum.h"
5#include "matrix.h"
6#include "backlight.h"
7#include <stddef.h>
8
9#define red_led_off PORTF |= (1<<5)
10#define red_led_on PORTF &= ~(1<<5)
11#define blu_led_off PORTF |= (1<<4)
12#define blu_led_on PORTF &= ~(1<<4)
13#define grn_led_off PORTD |= (1<<1)
14#define grn_led_on PORTD &= ~(1<<1)
15
16#define set_led_off red_led_off; grn_led_off; blu_led_off
17#define set_led_red red_led_on; grn_led_off; blu_led_off
18#define set_led_blue red_led_off; grn_led_off; blu_led_on
19#define set_led_green red_led_off; grn_led_on; blu_led_off
20#define set_led_yellow red_led_on; grn_led_on; blu_led_off
21#define set_led_magenta red_led_on; grn_led_off; blu_led_on
22#define set_led_cyan red_led_off; grn_led_on; blu_led_on
23#define set_led_white red_led_on; grn_led_on; blu_led_on
24
25/*
26#define LED_B 5
27#define LED_R 6
28#define LED_G 7
29
30#define all_leds_off PORTF &= ~(1<<LED_B) & ~(1<<LED_R) & ~(1<<LED_G)
31
32#define red_led_on PORTF |= (1<<LED_R)
33#define red_led_off PORTF &= ~(1<<LED_R)
34#define grn_led_on PORTF |= (1<<LED_G)
35#define grn_led_off PORTF &= ~(1<<LED_G)
36#define blu_led_on PORTF |= (1<<LED_B)
37#define blu_led_off PORTF &= ~(1<<LED_B)
38
39#define set_led_off PORTF &= ~(1<<LED_B) & ~(1<<LED_R) & ~(1<<LED_G)
40#define set_led_red PORTF = PORTF & ~(1<<LED_B) & ~(1<<LED_G) | (1<<LED_R)
41#define set_led_blue PORTF = PORTF & ~(1<<LED_G) & ~(1<<LED_R) | (1<<LED_B)
42#define set_led_green PORTF = PORTF & ~(1<<LED_B) & ~(1<<LED_R) | (1<<LED_G)
43#define set_led_yellow PORTF = PORTF & ~(1<<LED_B) | (1<<LED_R) | (1<<LED_G)
44#define set_led_magenta PORTF = PORTF & ~(1<<LED_G) | (1<<LED_R) | (1<<LED_B)
45#define set_led_cyan PORTF = PORTF & ~(1<<LED_R) | (1<<LED_B) | (1<<LED_G)
46#define set_led_white PORTF |= (1<<LED_B) | (1<<LED_R) | (1<<LED_G)
47*/
48
49// This a shortcut to help you visually see your layout.
50// The first section contains all of the arguements
51// The second converts the arguments into a two-dimensional array
52#define LAYOUT( \
53 k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, \
54 k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, \
55 k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, \
56 k33, k34, k35, k36, k37, k38, \
57 k43, k44, k45, k46, k47, k48 \
58) \
59{ \
60 { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B }, \
61 { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B }, \
62 { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B }, \
63 { KC_NO, KC_NO, KC_NO, k33, k34, k35, k36, k37, k38, KC_NO, KC_NO, KC_NO }, \
64 { KC_NO, KC_NO, KC_NO, k43, k44, k45, k46, k47, k48, KC_NO, KC_NO, KC_NO } \
65}
66
67#endif
diff --git a/keyboards/dichotemy/keymaps/default/keymap.c b/keyboards/dichotemy/keymaps/default/keymap.c
deleted file mode 100644
index 8742116f1..000000000
--- a/keyboards/dichotemy/keymaps/default/keymap.c
+++ /dev/null
@@ -1,394 +0,0 @@
1// this is the style you want to emulate.
2// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
3
4#include QMK_KEYBOARD_H
5#include "pointing_device.h"
6
7// Each layer gets a name for readability, which is then used in the keymap matrix below.
8// The underscores don't mean anything - you can have a layer called STUFF or any other name.
9// Layer names don't all need to be of the same length, obviously, and you can also skip them
10// entirely and just use numbers.
11enum dichotemy_layers
12{
13 _BS,
14 _SF,
15 _NM,
16 _NS,
17 _MS
18};
19
20#define LONGPRESS_COUNT 4
21
22enum dichotemy_keycodes
23{
24 CK_1G = SAFE_RANGE,
25 CK_BSPE,
26 CK_QE,
27 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.
28 NS_HYPH,
29 NS_EQU,
30 NUMKEY,
31 SFTKEY,
32 MOUSE,
33 MS_BTN1,
34 MS_BTN2
35 //MS_BTN3
36};
37
38// Macro definitions for readability
39enum dichotemy_macros
40{
41 VOLU,
42 VOLD,
43 ESCM
44};
45
46#define LONGPRESS_DELAY 150
47#define MAX_TOGGLE_LENGTH 300
48#define TAPPING_TOGGLE 1
49
50// Fillers to make layering more clear
51#define _______ KC_TRNS
52#define XXXXXXX KC_NO
53
54const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
55
56 [_BS] = LAYOUT( /* Base layout, nearly qwerty but with modifications because it's not a full keyboard. Obviously. */
57 CK_TE, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
58 NUMKEY, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, CK_QE,
59 SFTKEY, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MOUSE,
60 KC_LCTL, KC_LALT, KC_LGUI, KC_RGUI, KC_RALT, KC_RCTL,
61 KC_LBRC, KC_LPRN, KC_QUOT, KC_SPC, KC_RPRN, KC_RBRC
62 ),
63
64 [_SF] = LAYOUT( /* Shifted layout, small changes (because angle brackets have been moved to thumb cluster buttons) */
65 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
66 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
67 _______, _______, _______, _______, _______, _______, _______, _______, NS_HYPH, KC_UNDS, _______, _______,
68 _______, _______, _______, _______, _______, _______,
69 _______, KC_LABK, _______, _______, KC_RABK, _______
70 ),
71
72 [_NM] = LAYOUT( /* Number layout, basically the main function layer */
73 _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______,
74 _______, CK_1G, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, CK_BSPE,
75 _______, KC_F11, KC_F12, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, _______,
76 _______, _______, _______, _______, _______, _______,
77 _______, _______, _______, _______, _______, _______
78 ),
79
80 [_NS] = LAYOUT( /* Shifted number/function layout, for per-key control. Only active when shift is held, and number is toggled or held */
81 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
82 _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PLUS, NS_EQU, _______,
83 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
84 _______, _______, _______, _______, _______, _______,
85 _______, _______, _______, _______, _______, _______
86 ),
87
88 [_MS] = LAYOUT( /* Mouse layer, including buttons for clicking. */
89 _______, _______, _______, _______, _______, _______, KC_VOLU, KC_HOME, KC_PGUP, _______, _______, _______,
90 _______, _______, _______, _______, _______, _______, _______, MS_BTN1, MS_BTN2, _______, _______, _______,
91 _______, _______, _______, _______, _______, _______, KC_VOLD, KC_END, KC_PGDN, _______, _______, _______,
92 _______, _______, _______, _______, KC_UP, _______,
93 _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT
94 )
95
96};
97
98
99const uint16_t PROGMEM fn_actions[] = {
100
101};
102
103static uint16_t special_timers[LONGPRESS_COUNT] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
104static bool special_key_states[LONGPRESS_COUNT] = {0,0,0,0};
105
106static uint16_t shift_timer;
107static uint16_t num_timer;
108static uint16_t mouse_timer;
109
110static bool shift_singular_key = false;
111static bool number_singular_key = false;
112static bool mouse_singular_key = false;
113
114static bool shift_held = false;
115static bool shift_suspended = false;
116report_mouse_t currentReport = {};
117
118bool process_record_user(uint16_t keycode, keyrecord_t *record) {
119
120 //uint8_t layer;
121 //layer = biton32(layer_state); // get the current layer //Or don't, I didn't use it.
122
123 //custom layer handling for tri_layer,
124 switch (keycode) {
125 case NUMKEY:
126 if (record->event.pressed) {
127 num_timer = timer_read();
128 number_singular_key = true;
129 layer_invert(_NM);
130 } else {
131 if (timer_elapsed(num_timer) < MAX_TOGGLE_LENGTH && number_singular_key) {
132 //do nothing, the layer has already been inverted
133 } else {
134 layer_invert(_NM);
135 }
136 }
137 update_tri_layer(_NM, _SF, _NS);
138 return false;
139 break;
140 //SHIFT is handled as LSHIFT in the general case - 'toggle' shoudl activate caps, while the layer is only active when shift is held.
141 case SFTKEY:
142 if (record->event.pressed) {
143 shift_held = true;
144 shift_suspended = false;
145 shift_timer = timer_read();
146 shift_singular_key = true;
147 layer_on(_SF);
148 register_code(KC_LSFT);
149 } else {
150 shift_held = false;
151 if (timer_elapsed(shift_timer) < MAX_TOGGLE_LENGTH && shift_singular_key) {
152 //this was basically a toggle, so activate/deactivate caps lock.
153 SEND_STRING(SS_TAP(X_CAPSLOCK));
154 }
155 layer_off(_SF);
156 unregister_code(KC_LSFT);
157 }
158 update_tri_layer(_NM, _SF, _NS);
159 return false;
160 break;
161 //MOUSE layer needs to be handled the same way as NUMKEY, but differently from shift
162 case MOUSE:
163 if (record->event.pressed) {
164 mouse_timer = timer_read();
165 mouse_singular_key = true;
166 layer_invert(_MS);
167 } else {
168 if (timer_elapsed(mouse_timer) < MAX_TOGGLE_LENGTH && number_singular_key){
169 //do nothing, it was a toggle (and it's already been toggled)
170 } else {
171 layer_invert(_MS);
172 }
173 }
174 return false;
175 break;
176 //Custom macros for strange keys with different long-tap behavior
177 case CK_1G:
178 if (shift_held && shift_suspended){
179 register_code(KC_LSFT);
180 shift_suspended = false;
181 }
182 shift_singular_key = false;
183 number_singular_key = false;
184 mouse_singular_key = false;
185 if (record->event.pressed) {
186 special_timers[CK_1G-SAFE_RANGE] = timer_read();
187 } else {
188 if (special_key_states[CK_1G-SAFE_RANGE]){
189 //key was activated after longpress_delay, need to close those keycodes
190 special_key_states[CK_1G-SAFE_RANGE] = 0;
191 unregister_code(KC_GRAVE);
192 } else {
193 //key was not activated, return macro activating proper, pre-long-tap key
194 SEND_STRING(SS_TAP(X_1));
195 }
196 special_timers[CK_1G-SAFE_RANGE] = 0xFFFF;
197 }
198 break;
199 case CK_BSPE:
200 if (shift_held && shift_suspended){
201 register_code(KC_LSFT);
202 shift_suspended = false;
203 }
204 shift_singular_key = false;
205 number_singular_key = false;
206 mouse_singular_key = false;
207 if (record->event.pressed) {
208 special_timers[CK_BSPE-SAFE_RANGE] = timer_read();
209 } else {
210 if (special_key_states[CK_BSPE-SAFE_RANGE]){
211 //key was activated after longpress_delay, need to close those keycodes
212 special_key_states[CK_BSPE-SAFE_RANGE] = 0;
213 unregister_code(KC_ENTER);
214 } else {
215 //key was not activated, return macro activating proper, pre-long-tap key
216 SEND_STRING(SS_TAP(X_BSLASH));
217 }
218 special_timers[CK_BSPE-SAFE_RANGE] = 0xFFFF;
219 }
220 break;
221 case CK_QE:
222 if (shift_held && shift_suspended){
223 register_code(KC_LSFT);
224 shift_suspended = false;
225 }
226 shift_singular_key = false;
227 number_singular_key = false;
228 mouse_singular_key = false;
229 if (record->event.pressed) {
230 special_timers[CK_QE-SAFE_RANGE] = timer_read();
231 } else {
232 if (special_key_states[CK_QE-SAFE_RANGE]){
233 //key was activated after longpress_delay, need to close those keycodes
234 special_key_states[CK_QE-SAFE_RANGE] = 0;
235 unregister_code(KC_ENTER);
236 } else {
237 //key was not activated, return macro activating proper, pre-long-tap key
238 SEND_STRING(SS_TAP(X_QUOTE));
239 }
240 special_timers[CK_QE-SAFE_RANGE] = 0xFFFF;
241 }
242 break;
243 case CK_TE:
244 if (shift_held && shift_suspended){
245 register_code(KC_LSFT);
246 shift_suspended = false;
247 }
248 if (record->event.pressed) {
249 special_timers[CK_TE-SAFE_RANGE] = timer_read();
250 } else {
251 if (special_key_states[CK_TE-SAFE_RANGE]){
252 //key was activated after longpress_delay, need to close those keycodes
253 special_key_states[CK_TE-SAFE_RANGE] = 0;
254 unregister_code(KC_ENTER);
255 } else {
256 //key was not activated, return macro activating proper, pre-long-tap key
257 SEND_STRING(SS_TAP(X_TAB));
258 }
259 special_timers[CK_TE-SAFE_RANGE] = 0xFFFF;
260 }
261 break;
262 //No-shift keys, they unregister the KC_LSFT code so they can send
263 //unshifted values - but they don't change the bool. if any other
264 //key is pressed and the bool is set, KC_LSFT is registered again.
265 case NS_HYPH:
266 if (record->event.pressed) {
267 shift_suspended = true;
268 unregister_code(KC_LSFT);
269 register_code(KC_MINS);
270 } else {
271 unregister_code(KC_MINS);
272 if (shift_held && shift_suspended){
273 register_code(KC_LSFT);
274 shift_suspended = false;
275 }
276 }
277 break;
278 case NS_EQU:
279 if (record->event.pressed) {
280 shift_suspended = true;
281 unregister_code(KC_LSFT);
282 register_code(KC_EQUAL);
283 } else {
284 unregister_code(KC_EQUAL);
285 if (shift_held && shift_suspended){
286 register_code(KC_LSFT);
287 shift_suspended = false;
288 }
289 }
290 break;
291
292 //mouse buttons, for 1-3, to update the mouse report:
293 case MS_BTN1:
294 currentReport = pointing_device_get_report();
295 if (record->event.pressed) {
296 if (shift_held && shift_suspended){
297 register_code(KC_LSFT);
298 shift_suspended = false;
299 }
300 //update mouse report here
301 currentReport.buttons |= MOUSE_BTN1; //MOUSE_BTN1 is a const defined in report.h
302 } else {
303 //update mouse report here
304 currentReport.buttons &= ~MOUSE_BTN1;
305 }
306 pointing_device_set_report(currentReport);
307 break;
308 case MS_BTN2:
309 currentReport = pointing_device_get_report();
310 if (record->event.pressed) {
311 if (shift_held && shift_suspended){
312 register_code(KC_LSFT);
313 shift_suspended = false;
314 }
315 //update mouse report here
316 currentReport.buttons |= MOUSE_BTN2; //MOUSE_BTN2 is a const defined in report.h
317 } else {
318 //update mouse report here
319 }
320 pointing_device_set_report(currentReport);
321 break;
322 //there is a case for button 3, but that's handled in dichotemy.c, and this is being
323 //disabled to avoid any conflict.
324 /*case MS_BTN3:
325 currentReport = pointing_device_get_report();
326 if (record->event.pressed) {
327 if (shift_held && shift_suspended){
328 register_code(KC_LSFT);
329 shift_suspended = false;
330 }
331 //update mouse report here
332 currentReport.buttons |= MOUSE_BTN3; //MOUSE_BTN2 is a const defined in report.h
333 } else {
334 //update mouse report here
335 }
336 pointing_device_set_report(currentReport);
337 break;*/
338
339 //If any other key was pressed during the layer mod hold period,
340 //then the layer mod was used momentarily, and should block latching
341 //Additionally, if NS_ keys are in use, then shift may be held (but is
342 //disabled for the unshifted keycodes to be send. Check the bool and
343 //register shift as necessary.
344 default:
345 if (shift_held){
346 register_code(KC_LSFT);
347 }
348 shift_singular_key = false;
349 number_singular_key = false;
350 mouse_singular_key = false;
351 break;
352 }
353 return true;
354};
355
356void matrix_scan_user(void) {
357 uint8_t layer = biton32(layer_state);
358 for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
359 if (timer_elapsed(special_timers[i]) >= LONGPRESS_DELAY && !special_key_states[i]){
360 switch (i + SAFE_RANGE){
361 case CK_1G:
362 register_code(KC_GRAVE);
363 break;
364 case CK_BSPE:
365 register_code(KC_ENTER);
366 break;
367 case CK_QE:
368 register_code(KC_ENTER);
369 break;
370 case CK_TE:
371 register_code(KC_ESCAPE);
372 break;
373 }
374 special_key_states[i] = 1;
375 }
376 }
377 switch (layer) {
378 case _BS:
379 set_led_off;
380 break;
381 case _NM:
382 set_led_blue;
383 break;
384 case _SF:
385 set_led_red;
386 break;
387 case _NS:
388 set_led_green;
389 break;
390 default:
391 break;
392 }
393};
394
diff --git a/keyboards/dichotemy/config.h b/keyboards/dichotomy/config.h
index 1d92cf74e..f0847ec52 100644..100755
--- a/keyboards/dichotemy/config.h
+++ b/keyboards/dichotomy/config.h
@@ -24,10 +24,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
24 24
25#define VENDOR_ID 0xFEED 25#define VENDOR_ID 0xFEED
26#define PRODUCT_ID 0xACC7 26#define PRODUCT_ID 0xACC7
27#define DEVICE_VER 0x0001 27#define DEVICE_VER 0x0002
28#define MANUFACTURER unknown 28#define MANUFACTURER Broekhuijsen
29#define PRODUCT Dichotemy 29#define PRODUCT Dichotomy
30#define DESCRIPTION q.m.k. keyboard firmware for Dichotemy 30#define DESCRIPTION q.m.k. keyboard firmware for Dichotomy
31 31
32/* key matrix size */ 32/* key matrix size */
33#define MATRIX_ROWS 5 33#define MATRIX_ROWS 5
diff --git a/keyboards/dichotemy/dichotemy.c b/keyboards/dichotomy/dichotomy.c
index 080c2654c..41e12090c 100644..100755
--- a/keyboards/dichotemy/dichotemy.c
+++ b/keyboards/dichotomy/dichotomy.c
@@ -1,13 +1,11 @@
1#include "dichotemy.h" 1#include "dichotomy.h"
2#include "pointing_device.h"
3#include "report.h"
4 2
5void uart_init(void) { 3void uart_init(void) {
6 SERIAL_UART_INIT(); 4 SERIAL_UART_INIT();
7} 5}
8 6
9void pointing_device_task(void){ 7void pointing_device_task(void){
10 report_mouse_t currentReport = {}; 8 /*report_mouse_t currentReport = {};
11 SERIAL_UART_INIT(); 9 SERIAL_UART_INIT();
12 uint32_t timeout = 0; 10 uint32_t timeout = 0;
13 11
@@ -25,28 +23,31 @@ void pointing_device_task(void){
25 while(!SERIAL_UART_RXD_PRESENT){ 23 while(!SERIAL_UART_RXD_PRESENT){
26 timeout++; 24 timeout++;
27 if (timeout > 10000){ 25 if (timeout > 10000){
26 xprintf("\r\nTIMED OUT");
28 break; 27 break;
29 } 28 }
30 } 29 }
30 xprintf("\r\nGOT DATA for %d",i);
31 uart_data[i] = SERIAL_UART_DATA; 31 uart_data[i] = SERIAL_UART_DATA;
32 } 32 }
33 33
34 //check for the end packet, bits 1-4 are movement and scroll 34 //check for the end packet, bytes 1-4 are movement and scroll
35 //but bit 5 has bits 0-3 for the scroll button state 35 //but byte 5 has bits 0-3 for the scroll button state
36 //(1000 if pressed, 0000 if not) and bits 4-7 are always 1 36 //(1000 if pressed, 0000 if not) and bits 4-7 are always 1
37 //We can use this to verify the report sent properly. 37 //We can use this to verify the report sent properly.
38 if (uart_data[4] == 0x0F || uart_data[4] == 0x8F) 38 if (uart_data[4] == 0x0F || uart_data[4] == 0x8F)
39 { 39 {
40 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]);
40 currentReport = pointing_device_get_report(); 41 currentReport = pointing_device_get_report();
41 //shifting and transferring the info to the mouse report varaible 42 //shifting and transferring the info to the mouse report varaible
42 //mouseReport.x = 127 max -127 min 43 //mouseReport.x = 127 max -127 min
43 currentReport.x = uart_data[0]; 44 currentReport.x = (int8_t) uart_data[0];
44 //mouseReport.y = 127 max -127 min 45 //mouseReport.y = 127 max -127 min
45 currentReport.y = uart_data[1]; 46 currentReport.y = (int8_t) uart_data[1];
46 //mouseReport.v = 127 max -127 min (scroll vertical) 47 //mouseReport.v = 127 max -127 min (scroll vertical)
47 currentReport.v = uart_data[2]; 48 currentReport.v = (int8_t) uart_data[2];
48 //mouseReport.h = 127 max -127 min (scroll horizontal) 49 //mouseReport.h = 127 max -127 min (scroll horizontal)
49 currentReport.h = uart_data[3]; 50 currentReport.h = (int8_t) uart_data[3];
50 //mouseReport.buttons = 0x31 max (bitmask for mouse buttons 1-5) 0x00 min 51 //mouseReport.buttons = 0x31 max (bitmask for mouse buttons 1-5) 0x00 min
51 //mouse buttons 1 and 2 are handled by the keymap, but not 3 52 //mouse buttons 1 and 2 are handled by the keymap, but not 3
52 if (uart_data[4] == 0x0F) { //then 3 is not pressed 53 if (uart_data[4] == 0x0F) { //then 3 is not pressed
@@ -55,7 +56,9 @@ void pointing_device_task(void){
55 currentReport.buttons |= MOUSE_BTN3; 56 currentReport.buttons |= MOUSE_BTN3;
56 } 57 }
57 pointing_device_set_report(currentReport); 58 pointing_device_set_report(currentReport);
58 } 59 } else {
60 xprintf("\r\nRequested packet, data 4 was %d",uart_data[4]);
61 }*/
59 pointing_device_send(); 62 pointing_device_send();
60} 63}
61 64
diff --git a/keyboards/dichotomy/dichotomy.h b/keyboards/dichotomy/dichotomy.h
new file mode 100755
index 000000000..030209ff0
--- /dev/null
+++ b/keyboards/dichotomy/dichotomy.h
@@ -0,0 +1,46 @@
1#ifndef DICHOTOMY_H
2#define DICHOTOMY_H
3
4#include QMK_KEYBOARD_H
5#include "report.h"
6#include "pointing_device.h"
7#include "quantum.h"
8#include "matrix.h"
9#include "backlight.h"
10#include <stddef.h>
11
12#define red_led_off() PORTF |= (1<<6)
13#define red_led_on() PORTF &= ~(1<<6)
14#define blu_led_off() PORTF |= (1<<5)
15#define blu_led_on() PORTF &= ~(1<<5)
16#define grn_led_off() PORTD |= (1<<1)
17#define grn_led_on() PORTD &= ~(1<<1)
18
19#define set_led_off() red_led_off(); grn_led_off(); blu_led_off()
20#define set_led_red() red_led_on(); grn_led_off(); blu_led_off()
21#define set_led_blue() red_led_off(); grn_led_off(); blu_led_on()
22#define set_led_green() red_led_off(); grn_led_on(); blu_led_off()
23#define set_led_yellow() red_led_on(); grn_led_on(); blu_led_off()
24#define set_led_magenta() red_led_on(); grn_led_off(); blu_led_on()
25#define set_led_cyan() red_led_off(); grn_led_on(); blu_led_on()
26#define set_led_white() red_led_on(); grn_led_on(); blu_led_on()
27
28// This a shortcut to help you visually see your layout.
29// The first section contains all of the arguements
30// The second converts the arguments into a two-dimensional array
31#define LAYOUT( \
32 k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, \
33 k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, \
34 k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, \
35 k33, k34, k35, k36, k37, k38, \
36 k42, k43, k44, k45, k46, k47, k48, k49 \
37) \
38{ \
39 { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B }, \
40 { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B }, \
41 { k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B }, \
42 { KC_NO, KC_NO, KC_NO, k33, k34, k35, k36, k37, k38, KC_NO, KC_NO, KC_NO }, \
43 { KC_NO, KC_NO, k42, k43, k44, k45, k46, k47, k48, k49, KC_NO, KC_NO } \
44}
45
46#endif
diff --git a/keyboards/dichotemy/info.json b/keyboards/dichotomy/info.json
index fc4390cdd..aeb00edce 100644
--- a/keyboards/dichotemy/info.json
+++ b/keyboards/dichotomy/info.json
@@ -1,5 +1,5 @@
1{ 1{
2 "keyboard_name": "Dichotemy", 2 "keyboard_name": "Dichotomy",
3 "url": "", 3 "url": "",
4 "maintainer": "qmk", 4 "maintainer": "qmk",
5 "width": 13, 5 "width": 13,
diff --git a/keyboards/dichotomy/keymaps/default/keymap.c b/keyboards/dichotomy/keymaps/default/keymap.c
new file mode 100755
index 000000000..e44bd21d9
--- /dev/null
+++ b/keyboards/dichotomy/keymaps/default/keymap.c
@@ -0,0 +1,506 @@
1// this is the style you want to emulate.
2// This is the canonical layout file for the Quantum project. If you want to add another keyboard,
3
4#include "dichotomy.h"
5
6// Each layer gets a name for readability, which is then used in the keymap matrix below.
7// The underscores don't mean anything - you can have a layer called STUFF or any other name.
8// Layer names don't all need to be of the same length, obviously, and you can also skip them
9// entirely and just use numbers.
10enum dichotomy_layers {
11 _BS,
12 _SF,
13 _NM,
14 _NS,
15 _MS
16};
17
18#define LONGPRESS_COUNT 4
19
20enum dichotomy_keycodes
21{
22 CK_1G = SAFE_RANGE,
23 CK_BSPE,
24 CK_QE,
25 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.
26 NS_HYPH,
27 NS_EQU,
28 NUMKEY,
29 SFTKEY,
30 MOUKEY,
31 MS_BTN1,
32 MS_BTN2,
33 MS_BTN3
34};
35
36#define CUSTOM_LONGPRESS 150
37#define CUSTOM_TOGGLE_TIME 300
38
39#define RED_BRIGHTNESS 3
40#define GREEN_BRIGHTNESS 2
41#define BLUE_BRIGHTNESS 2
42
43// Fillers to make layering more clear
44#define _______ KC_TRNS
45#define XXXXXXX KC_NO
46
47const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
48[_BS] = LAYOUT( /* Base layout, nearly qwerty but with modifications because it's not a full keyboard. Obviously. */
49 CK_TE, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
50 NUMKEY, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, CK_QE,
51 SFTKEY, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MOUKEY,
52 KC_LCTL, KC_LALT, KC_LGUI, KC_RGUI, KC_RALT, KC_RCTL,
53 MS_BTN3, KC_LBRC, KC_LPRN, KC_SPC, KC_SPC, KC_RPRN, KC_RBRC, MS_BTN3
54),
55
56[_SF] = LAYOUT( /* Shifted layout, small changes (because angle brackets have been moved to thumb cluster buttons) */
57 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
58 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
59 _______, _______, _______, _______, _______, _______, _______, _______, NS_HYPH, KC_UNDS, _______, _______,
60 _______, _______, _______, _______, _______, _______,
61 _______, _______, KC_LABK, _______, _______, KC_RABK, _______, _______
62),
63
64[_NM] = LAYOUT( /* Number layout, basically the main function layer */
65 _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______,
66 _______, CK_1G, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, CK_BSPE,
67 _______, KC_F11, KC_F12, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, _______,
68 _______, _______, _______, _______, _______, _______,
69 _______, _______, _______, _______, _______, _______, _______, _______
70),
71
72[_NS] = LAYOUT( /* Shifted number/function layout, for per-key control. Only active when shift is held, and number is toggled or held */
73 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
74 _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_PLUS, NS_EQU, _______,
75 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
76 _______, _______, _______, _______, _______, _______,
77 _______, _______, _______, _______, _______, _______, _______, _______
78),
79
80[_MS] = LAYOUT( /* Mouse layer, including buttons for clicking. */
81 _______, _______, _______, _______, _______, _______, KC_VOLU, KC_HOME, KC_PGUP, _______, _______, _______,
82 _______, _______, _______, _______, _______, _______, _______, MS_BTN1, MS_BTN2, _______, _______, _______,
83 _______, _______, _______, _______, _______, _______, KC_VOLD, KC_END, KC_PGDN, _______, _______, _______,
84 _______, _______, _______, _______, KC_UP, _______,
85 _______, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______
86)
87
88};
89
90
91const uint16_t PROGMEM fn_actions[] = {
92
93};
94
95static uint16_t special_timers[LONGPRESS_COUNT] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
96static bool special_key_states[LONGPRESS_COUNT] = {0,0,0,0};
97static bool special_key_pressed[LONGPRESS_COUNT] = {0,0,0,0};
98
99static uint16_t shift_timer;
100static uint16_t num_timer;
101static uint16_t mouse_timer;
102
103static uint8_t red_timer;
104static uint8_t green_timer;
105static uint8_t blue_timer;
106
107static bool shift_singular_key = false;
108static bool number_singular_key = false;
109static bool mouse_singular_key = false;
110static bool capsLED = false;
111static bool shiftLED = false;
112static bool numLED = false;
113static bool mouseLED = false;
114
115static bool shift_held = false;
116static bool shift_suspended = false;
117report_mouse_t currentReport = {};
118
119bool process_record_user(uint16_t keycode, keyrecord_t *record) {
120 //uint8_t layer;
121 //layer = biton32(layer_state); // get the current layer //Or don't, I didn't use it.
122 bool returnVal = true; //this is to determine if more key processing is needed.
123
124 //custom layer handling for tri_layer,
125 switch (keycode) {
126 case NUMKEY:
127 if (record->event.pressed) {
128 num_timer = timer_read();
129 number_singular_key = true;
130 layer_invert(_NM);
131 numLED = !numLED;
132 } else {
133 if (timer_elapsed(num_timer) < CUSTOM_TOGGLE_TIME && number_singular_key) {
134 //do nothing, the layer has already been inverted
135 } else {
136 layer_invert(_NM);
137 numLED = !numLED;
138 }
139 }
140 update_tri_layer(_NM, _SF, _NS);
141 returnVal = false;
142 break;
143 //SHIFT is handled as LSHIFT in the general case - 'toggle' shoudl activate caps, while the layer is only active when shift is held.
144 case SFTKEY:
145 if (record->event.pressed) {
146 shift_held = true;
147 shiftLED = true;
148 shift_suspended = false;
149 shift_timer = timer_read();
150 shift_singular_key = true;
151 layer_on(_SF);
152 register_code(KC_LSFT);
153 } else {
154 shift_held = false;
155 shiftLED = false;
156 if (timer_elapsed(shift_timer) < CUSTOM_TOGGLE_TIME && shift_singular_key) {
157 //this was basically a toggle, so activate/deactivate caps lock.
158 SEND_STRING(SS_TAP(X_CAPSLOCK));
159 capsLED = !capsLED;
160 }
161 layer_off(_SF);
162 unregister_code(KC_LSFT);
163 }
164 update_tri_layer(_NM, _SF, _NS);
165 returnVal = false;
166 break;
167 //MOUSE layer needs to be handled the same way as NUMKEY, but differently from shift
168 case MOUKEY:
169 if (record->event.pressed) {
170 mouse_timer = timer_read();
171 mouse_singular_key = true;
172 layer_invert(_MS);
173 mouseLED = !mouseLED;
174 } else {
175 if (timer_elapsed(mouse_timer) < CUSTOM_TOGGLE_TIME && mouse_singular_key){
176 //do nothing, it was a toggle (and it's already been toggled)
177 } else {
178 layer_invert(_MS);
179 mouseLED = !mouseLED;
180 }
181 }
182 returnVal = false;
183 break;
184 //Custom macros for strange keys with different long-tap behavior
185 case CK_1G:
186 if (shift_held && shift_suspended){
187 register_code(KC_LSFT);
188 shift_suspended = false;
189 }
190 if (record->event.pressed) {
191 special_timers[CK_1G-SAFE_RANGE] = timer_read();
192 special_key_pressed[CK_1G-SAFE_RANGE] = 1;
193 } else {
194 if (special_key_states[CK_1G-SAFE_RANGE]){
195 //key was activated after custom_longpress, need to close those keycodes
196 special_key_states[CK_1G-SAFE_RANGE] = 0;
197 unregister_code(KC_GRAVE);
198 } else {
199 if (special_key_pressed[CK_1G-SAFE_RANGE]){
200 //key was not activated, return macro activating proper, pre-long-tap key
201 SEND_STRING(SS_TAP(X_1));
202 special_key_pressed[CK_1G-SAFE_RANGE] = 0;
203 } else {
204 //the short key was already sent, because another key was pressed.
205 //Do nothing.
206 }
207
208 }
209 }
210 returnVal = false;
211 break;
212 case CK_BSPE:
213 if (shift_held && shift_suspended){
214 register_code(KC_LSFT);
215 shift_suspended = false;
216 }
217 if (record->event.pressed) {
218 special_timers[CK_BSPE-SAFE_RANGE] = timer_read();
219 special_key_pressed[CK_BSPE-SAFE_RANGE] = 1;
220 } else {
221 if (special_key_states[CK_BSPE-SAFE_RANGE]){
222 //key was activated after custom_longpress, need to close those keycodes
223 special_key_states[CK_BSPE-SAFE_RANGE] = 0;
224 unregister_code(KC_ENTER);
225 } else {
226 if (special_key_pressed[CK_BSPE-SAFE_RANGE]){
227 //key was not activated, return macro activating proper, pre-long-tap key
228 SEND_STRING(SS_TAP(X_BSLASH));
229 special_key_pressed[CK_BSPE-SAFE_RANGE] = 0;
230 } else {
231 //the short key was already sent, because another key was pressed.
232 //Do nothing.
233 }
234 }
235 }
236 returnVal = false;
237 break;
238 case CK_QE:
239 if (shift_held && shift_suspended){
240 register_code(KC_LSFT);
241 shift_suspended = false;
242 }
243 if (record->event.pressed) {
244 special_timers[CK_QE-SAFE_RANGE] = timer_read();
245 special_key_pressed[CK_QE-SAFE_RANGE] = 1;
246 } else {
247 if (special_key_states[CK_QE-SAFE_RANGE]){
248 //key was activated after custom_longpress, need to close those keycodes
249 special_key_states[CK_QE-SAFE_RANGE] = 0;
250 unregister_code(KC_ENTER);
251 } else {
252 if (special_key_pressed[CK_QE-SAFE_RANGE]){
253 //the long-press key was not activated, return macro activating proper, pre-long-tap key
254 SEND_STRING(SS_TAP(X_QUOTE));
255 special_key_pressed[CK_QE-SAFE_RANGE] = 0;
256 } else {
257 //the short key was already sent, because another key was pressed.
258 //Do nothing.
259 }
260 }
261 }
262 returnVal = false;
263 break;
264 case CK_TE:
265 if (shift_held && shift_suspended){
266 register_code(KC_LSFT);
267 shift_suspended = false;
268 }
269 if (record->event.pressed) {
270 special_timers[CK_TE-SAFE_RANGE] = timer_read();
271 special_key_pressed[CK_TE-SAFE_RANGE] = 1;
272 } else {
273 if (special_key_states[CK_TE-SAFE_RANGE]){
274 //key was activated after custom_longpress, need to close those keycodes
275 special_key_states[CK_TE-SAFE_RANGE] = 0;
276 unregister_code(KC_ESCAPE);
277 } else {
278 if (special_key_pressed[CK_TE-SAFE_RANGE]){
279 //the long-press key was not activated, return macro activating proper, pre-long-tap key
280 SEND_STRING(SS_TAP(X_TAB));
281 special_key_pressed[CK_TE-SAFE_RANGE] = 0;
282 } else {
283 //the short key was already sent, because another key was pressed.
284 //Do nothing.
285 }
286 }
287 }
288 returnVal = false;
289 break;
290 //No-shift keys, they unregister the KC_LSFT code so they can send
291 //unshifted values - but they don't change the bool. if any other
292 //key is pressed and the bool is set, KC_LSFT is registered again.
293 case NS_HYPH:
294 if (record->event.pressed) {
295 shift_suspended = true;
296 unregister_code(KC_LSFT);
297 register_code(KC_MINS);
298 } else {
299 unregister_code(KC_MINS);
300 if (shift_held && shift_suspended){
301 register_code(KC_LSFT);
302 shift_suspended = false;
303 }
304 }
305 returnVal = false;
306 break;
307 case NS_EQU:
308 if (record->event.pressed) {
309 shift_suspended = true;
310 unregister_code(KC_LSFT);
311 register_code(KC_EQUAL);
312 } else {
313 unregister_code(KC_EQUAL);
314 if (shift_held && shift_suspended){
315 register_code(KC_LSFT);
316 shift_suspended = false;
317 }
318 }
319 returnVal = false;
320 break;
321
322 //mouse buttons, for 1-3, to update the mouse report:
323 case MS_BTN1:
324 currentReport = pointing_device_get_report();
325 if (record->event.pressed) {
326 if (shift_held && shift_suspended){
327 register_code(KC_LSFT);
328 shift_suspended = false;
329 }
330 //update mouse report here
331 currentReport.buttons |= MOUSE_BTN1; //MOUSE_BTN1 is a const defined in report.h
332 } else {
333 //update mouse report here
334 currentReport.buttons &= ~MOUSE_BTN1;
335 }
336 pointing_device_set_report(currentReport);
337 returnVal = false;
338 break;
339 case MS_BTN2:
340 currentReport = pointing_device_get_report();
341 if (record->event.pressed) {
342 if (shift_held && shift_suspended){
343 register_code(KC_LSFT);
344 shift_suspended = false;
345 }
346 //update mouse report here
347 currentReport.buttons |= MOUSE_BTN2; //MOUSE_BTN2 is a const defined in report.h
348 } else {
349 //update mouse report here
350 currentReport.buttons &= ~MOUSE_BTN2;
351 }
352 pointing_device_set_report(currentReport);
353 returnVal = false;
354 break;
355 case MS_BTN3:
356 currentReport = pointing_device_get_report();
357 if (record->event.pressed) {
358 if (shift_held && shift_suspended){
359 register_code(KC_LSFT);
360 shift_suspended = false;
361 }
362 //update mouse report here
363 currentReport.buttons |= MOUSE_BTN3; //MOUSE_BTN3 is a const defined in report.h
364 } else {
365 //update mouse report here
366 currentReport.buttons &= ~MOUSE_BTN3;
367 }
368 pointing_device_set_report(currentReport);
369 returnVal = false;
370 break;
371 //Additionally, if NS_ keys are in use, then shift may be held (but is
372 //disabled for the unshifted keycodes to be send. Check the bool and
373 //register shift as necessary.
374 default:
375 if (shift_held){
376 register_code(KC_LSFT);
377 }
378 break;
379 }
380 switch (keycode){
381 case KC_BSPC:
382 case KC_NO:
383 case NUMKEY:
384 case SFTKEY:
385 case MOUKEY:
386 //don't want to reset single key variables
387 break;
388 default:
389 //If any other key was pressed during the layer mod hold period,
390 //then the layer mod was used momentarily, and should block latching
391 shift_singular_key = false;
392 number_singular_key = false;
393 mouse_singular_key = false;
394 break;
395 }
396 switch (keycode){
397 case KC_BSPC:
398 case KC_NO:
399 case NUMKEY:
400 case SFTKEY:
401 case MOUKEY:
402 case MOUSE_BTN1:
403 case MOUSE_BTN2:
404 case MOUSE_BTN3:
405 case KC_LCTL:
406 case KC_LALT:
407 case KC_LGUI:
408 case KC_RCTL:
409 case KC_RALT:
410 case KC_RGUI:
411 case CK_1G:
412 case CK_BSPE:
413 case CK_QE:
414 case CK_TE:
415 //Do nothing, don't want to trigger the timer key rollover
416 break;
417 default:
418 //Now we're checking to see if any of the special timer keys are pressed
419 //if so, we need to activate their short-press features
420 if (record->event.pressed) {
421 for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
422 if ((!special_key_states[i]) && special_key_pressed[i]){
423 switch (i + SAFE_RANGE){
424 case CK_1G:
425 SEND_STRING(SS_TAP(X_1));
426 break;
427 case CK_BSPE:
428 SEND_STRING(SS_TAP(X_BSLASH));
429 break;
430 case CK_QE:
431 SEND_STRING(SS_TAP(X_QUOTE));
432 break;
433 case CK_TE:
434 SEND_STRING(SS_TAP(X_TAB));
435 break;
436 }
437 special_key_pressed[i] = 0;
438 }
439 }
440 } else {
441 //do nothing, we don't want to trigger short presses on key releases.
442 }
443 break;
444 }
445 return returnVal;
446};
447
448void matrix_scan_user(void) {
449 //uint8_t layer = biton32(layer_state);
450 for (uint8_t i = 0; i<LONGPRESS_COUNT; i++){
451 if ((timer_elapsed(special_timers[i]) >= CUSTOM_LONGPRESS) && (!special_key_states[i]) && special_key_pressed[i]){
452 switch (i + SAFE_RANGE){
453 case CK_1G:
454 register_code(KC_GRAVE);
455 break;
456 case CK_BSPE:
457 register_code(KC_ENTER);
458 break;
459 case CK_QE:
460 register_code(KC_ENTER);
461 break;
462 case CK_TE:
463 register_code(KC_ESCAPE);
464 break;
465 }
466 special_key_pressed[i] = 0;
467 special_key_states[i] = 1;
468 }
469 }
470 if (shiftLED || capsLED){
471 red_timer++;
472 if (red_timer < RED_BRIGHTNESS){
473 red_led_on();
474 } else {
475 red_timer = 0;
476 red_led_off();
477 }
478 } else {
479 red_timer = 0;
480 red_led_off();
481 }
482 if (numLED){
483 green_timer++;
484 if (green_timer < GREEN_BRIGHTNESS){
485 grn_led_on();
486 } else {
487 green_timer = 0;
488 grn_led_off();
489 }
490 } else {
491 green_timer = 0;
492 grn_led_off();
493 }
494 if (mouseLED){
495 blue_timer++;
496 if (blue_timer < BLUE_BRIGHTNESS){
497 blu_led_on();
498 } else {
499 blue_timer = 0;
500 blu_led_off();
501 }
502 } else {
503 blue_timer = 0;
504 blu_led_off();
505 }
506};
diff --git a/keyboards/dichotemy/matrix.c b/keyboards/dichotomy/matrix.c
index f2841df1d..14c3f0d8e 100644..100755
--- a/keyboards/dichotemy/matrix.c
+++ b/keyboards/dichotomy/matrix.c
@@ -26,6 +26,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
26#include "util.h" 26#include "util.h"
27#include "matrix.h" 27#include "matrix.h"
28#include "timer.h" 28#include "timer.h"
29#include "dichotomy.h"
30#include "pointing_device.h"
31#include "report.h"
29 32
30#if (MATRIX_COLS <= 8) 33#if (MATRIX_COLS <= 8)
31# define print_matrix_header() print("\nr/c 01234567\n") 34# 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/>.
45#endif 48#endif
46 49
47#define MAIN_ROWMASK 0xFFF0; 50#define MAIN_ROWMASK 0xFFF0;
48#define LOWER_ROWMASK 0x1F80; 51#define LOWER_ROWMASK 0x3FC0;
49 52
50/* matrix state(1:on, 0:off) */ 53/* matrix state(1:on, 0:off) */
51static matrix_row_t matrix[MATRIX_ROWS]; 54static matrix_row_t matrix[MATRIX_ROWS];
52 55
53__attribute__ ((weak)) 56__attribute__ ((weak))
57void matrix_init_quantum(void) {
58 matrix_init_kb();
59}
60
61__attribute__ ((weak))
62void matrix_scan_quantum(void) {
63 matrix_scan_kb();
64}
65
66__attribute__ ((weak))
54void matrix_init_kb(void) { 67void matrix_init_kb(void) {
55 matrix_init_user(); 68 matrix_init_user();
56} 69}
@@ -79,13 +92,16 @@ uint8_t matrix_cols(void) {
79} 92}
80 93
81void matrix_init(void) { 94void matrix_init(void) {
82 95 DDRF |= (1<<6);
96 DDRF |= (1<<5);
97 DDRD |= (1<<1);
83 matrix_init_quantum(); 98 matrix_init_quantum();
84} 99}
85 100
86uint8_t matrix_scan(void) 101uint8_t matrix_scan(void)
87{ 102{
88 SERIAL_UART_INIT(); 103 SERIAL_UART_INIT();
104 //xprintf("\r\nTRYING TO SCAN");
89 105
90 uint32_t timeout = 0; 106 uint32_t timeout = 0;
91 107
@@ -93,25 +109,35 @@ uint8_t matrix_scan(void)
93 SERIAL_UART_DATA = 's'; 109 SERIAL_UART_DATA = 's';
94 110
95 //trust the external keystates entirely, erase the last data 111 //trust the external keystates entirely, erase the last data
96 uint8_t uart_data[7] = {0}; 112 uint8_t uart_data[11] = {0};
97 113
98 //there are 10 bytes corresponding to 10 columns, and an end byte 114 //there are 10 bytes corresponding to 10 columns, and an end byte
99 for (uint8_t i = 0; i < 7; i++) { 115 for (uint8_t i = 0; i < 11; i++) {
100 //wait for the serial data, timeout if it's been too long 116 //wait for the serial data, timeout if it's been too long
101 //this only happened in testing with a loose wire, but does no 117 //this only happened in testing with a loose wire, but does no
102 //harm to leave it in here 118 //harm to leave it in here
103 while(!SERIAL_UART_RXD_PRESENT){ 119 while(!SERIAL_UART_RXD_PRESENT){
104 timeout++; 120 timeout++;
105 if (timeout > 10000){ 121 if (timeout > 10000){
122 xprintf("\r\nTime out in keyboard.");
106 break; 123 break;
107 } 124 }
108 } 125 }
109 uart_data[i] = SERIAL_UART_DATA; 126 uart_data[i] = SERIAL_UART_DATA;
110 } 127 }
111 128
112 //check for the end packet, the key state bytes use the LSBs, so 0xE0 129 //check for the end packet, the key state bytes use the LSBs, so 0xE0
113 //will only show up here if the correct bytes were recieved 130 //will only show up here if the correct bytes were recieved
114 if (uart_data[6] == 0x96) { //this is an arbitrary binary checksum (10010110) 131 uint8_t checksum = 0x00;
132 for (uint8_t z=0; z<10; z++){
133 checksum = checksum^uart_data[z];
134 }
135 checksum = checksum ^ (uart_data[10] & 0xF0);
136 // Smash the checksum from 1 byte into 4 bits
137 checksum = (checksum ^ ((checksum & 0xF0)>>4)) & 0x0F;
138//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);
139 if ((uart_data[10] & 0x0F) == checksum) { //this is an arbitrary binary checksum (1001) (that would be 0x9.)
140 //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]);
115 //shifting and transferring the keystates to the QMK matrix variable 141 //shifting and transferring the keystates to the QMK matrix variable
116 //bits 1-12 are row 1, 13-24 are row 2, 25-36 are row 3, 142 //bits 1-12 are row 1, 13-24 are row 2, 25-36 are row 3,
117 //bits 37-42 are row 4 (only 6 wide, 1-3 are 0, and 10-12 are 0) 143 //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)
121 matrix[1] = ((uint16_t) uart_data[1] << 12) | ((uint16_t) uart_data[2] << 4); 147 matrix[1] = ((uint16_t) uart_data[1] << 12) | ((uint16_t) uart_data[2] << 4);
122 matrix[2] = (((uint16_t) uart_data[3] << 8) | ((uint16_t) uart_data[4])) & MAIN_ROWMASK; 148 matrix[2] = (((uint16_t) uart_data[3] << 8) | ((uint16_t) uart_data[4])) & MAIN_ROWMASK;
123 matrix[3] = (((uint16_t) uart_data[4] << 9) | ((uint16_t) uart_data[5] << 1)) & LOWER_ROWMASK; 149 matrix[3] = (((uint16_t) uart_data[4] << 9) | ((uint16_t) uart_data[5] << 1)) & LOWER_ROWMASK;
124 matrix[4] = ((uint16_t) uart_data[5] << 7) & LOWER_ROWMASK; 150 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;
125 /* OK, TURNS OUT THAT WAS A BAD ASSUMPTION */ 151 /* OK, TURNS OUT THAT WAS A BAD ASSUMPTION */
126 for (uint8_t i = 0; i < MATRIX_ROWS; i++) { 152 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
127 //I've unpacked these into the mirror image of what QMK expects them to be, so... 153 //I've unpacked these into the mirror image of what QMK expects them to be, so...
128 matrix[i] = ((matrix[i] * 0x0802LU & 0x22110LU) | (matrix[i] * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16; 154 /*uint8_t halfOne = (matrix[i]>>8);
155 uint8_t halfTwo = (matrix[i] & 0xFF);
156 halfOne = ((halfOne * 0x0802LU & 0x22110LU) | (halfOne * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
157 halfTwo = ((halfTwo * 0x0802LU & 0x22110LU) | (halfTwo * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
158 matrix[i] = ((halfTwo<<8) & halfOne);*/
159 //matrix[i] = ((matrix[i] * 0x0802LU & 0x22110LU) | (matrix[i] * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
160 matrix[i] = bitrev16(matrix[i]);
129 //bithack mirror! Doesn't make any sense, but works - and efficiently. 161 //bithack mirror! Doesn't make any sense, but works - and efficiently.
130 } 162 }
163 //if (uart_data[6]!=0 || uart_data[7]!=0){
164 //if (maxCount<101){
165 // xprintf("\r\nMouse data: x=%d, y=%d",(int8_t)uart_data[6],(int8_t)uart_data[7]);
166 //}
167 report_mouse_t currentReport = {};
168 //check for the end packet, bytes 1-4 are movement and scroll
169 //but byte 5 has bits 0-3 for the scroll button state
170 //(1000 if pressed, 0000 if not) and bits 4-7 are always 1
171 //We can use this to verify the report sent properly.
172
173 currentReport = pointing_device_get_report();
174 //shifting and transferring the info to the mouse report varaible
175 //mouseReport.x = 127 max -127 min
176 currentReport.x = (int8_t) uart_data[6];
177 //mouseReport.y = 127 max -127 min
178 currentReport.y = (int8_t) uart_data[7];
179 //mouseReport.v = 127 max -127 min (scroll vertical)
180 currentReport.v = (int8_t) uart_data[8];
181 //mouseReport.h = 127 max -127 min (scroll horizontal)
182 currentReport.h = (int8_t) uart_data[9];
183 /*
184 currentReport.x = 0;
185 currentReport.y = 0;
186 currentReport.v = 0;
187 currentReport.h = 0;*/
188 pointing_device_set_report(currentReport);
189 } else {
190 //xprintf("\r\nRequested packet, data 10 was %d but checksum was %d",(uart_data[10] & 0x0F), (checksum & 0x0F));
131 } 191 }
132 192 //matrix_print();
133 193
134 matrix_scan_quantum(); 194 matrix_scan_quantum();
135 return 1; 195 return 1;
diff --git a/keyboards/dichotemy/readme.md b/keyboards/dichotomy/readme.md
index b30cf00cb..9027825c3 100644..100755
--- a/keyboards/dichotemy/readme.md
+++ b/keyboards/dichotomy/readme.md
@@ -1,4 +1,4 @@
1Dichotemy Keyboard Firmware 1Dichotomy Keyboard Firmware
2====================== 2======================
3 3
4These configuration files were based off the Mitosis keyboard. This keyboard uses a completely different 'matrix scan' system to other keyboards, it relies on an external nRF51822 microcontroller maintaining a matrix of keystates received from the keyboard halves - it also receives mouse pointer information from the keyboard halves, which is implemented through a new feature, "Pointing Device". The matrix.c file contains the code to poll the external microcontroller for the key matrix, and the keymap.c file contains similar code to obtain the mouse report. As long as the relavant functions in these files are not changed, all other QMK features are supported. 4These configuration files were based off the Mitosis keyboard. This keyboard uses a completely different 'matrix scan' system to other keyboards, it relies on an external nRF51822 microcontroller maintaining a matrix of keystates received from the keyboard halves - it also receives mouse pointer information from the keyboard halves, which is implemented through a new feature, "Pointing Device". The matrix.c file contains the code to poll the external microcontroller for the key matrix, and the keymap.c file contains similar code to obtain the mouse report. As long as the relavant functions in these files are not changed, all other QMK features are supported.
diff --git a/keyboards/dichotemy/rules.mk b/keyboards/dichotomy/rules.mk
index 4e9db8687..4dbc999b7 100644..100755
--- a/keyboards/dichotemy/rules.mk
+++ b/keyboards/dichotomy/rules.mk
@@ -1,6 +1,6 @@
1 1
2OPT_DEFS += -DDICHOTEMY_PROMICRO 2OPT_DEFS += -DDICHOTOMY_PROMICRO
3DICHOTEMY_UPLOAD_COMMAND = while [ ! -r $(USB) ]; do sleep 1; done; \ 3DICHOTOMY_UPLOAD_COMMAND = while [ ! -r $(USB) ]; do sleep 1; done; \
4 avrdude -p $(MCU) -c avr109 -U flash:w:$(TARGET).hex -P $(USB) 4 avrdude -p $(MCU) -c avr109 -U flash:w:$(TARGET).hex -P $(USB)
5 5
6# # project specific files 6# # project specific files
@@ -24,6 +24,8 @@ MCU = atmega32u4
24# software delays. 24# software delays.
25F_CPU = 16000000 25F_CPU = 16000000
26 26
27
28#
27# LUFA specific 29# LUFA specific
28# 30#
29# Target architecture (see library "Board Types" documentation). 31# Target architecture (see library "Board Types" documentation).
@@ -43,10 +45,10 @@ ARCH = AVR8
43F_USB = $(F_CPU) 45F_USB = $(F_CPU)
44 46
45# Bootloader 47# Bootloader
46# This definition is optional, and if your keyboard supports multiple bootloaders of 48 # This definition is optional, and if your keyboard supports multiple bootloaders of
47# different sizes, comment this out, and the correct address will be loaded 49 # different sizes, comment this out, and the correct address will be loaded
48# automatically (+60). See bootloader.mk for all options. 50 # automatically (+60). See bootloader.mk for all options.
49BOOTLOADER = caterina 51 BOOTLOADER = caterina
50 52
51# Interrupt driven control endpoint task(+60) 53# Interrupt driven control endpoint task(+60)
52OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT 54OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
@@ -72,4 +74,4 @@ UNICODE_ENABLE = YES # Unicode
72USB = /dev/ttyACM0 74USB = /dev/ttyACM0
73 75
74#upload: build 76#upload: build
75# $(DICHOTEMY_UPLOAD_COMMAND) 77# $(DICHOTOMY_UPLOAD_COMMAND)