aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Humbert <jack.humb@gmail.com>2017-06-27 14:21:42 -0400
committerJack Humbert <jack.humb@gmail.com>2017-06-27 14:21:42 -0400
commit9f5b4e1d7a37f873acbc19b8385964121566653e (patch)
tree78a51918d16a84148af5276170d2c30525dee661
parentb82604dadad81872abdb9fdde18086ee69e66671 (diff)
parent4ba9438c3f71e6ea3433be4f9e1a28d36471d247 (diff)
downloadqmk_firmware-9f5b4e1d7a37f873acbc19b8385964121566653e.tar.gz
qmk_firmware-9f5b4e1d7a37f873acbc19b8385964121566653e.zip
Merge branch 'master' of https://github.com/qmk/qmk_firmware into dual_audio
-rw-r--r--docs/_summary.md1
-rw-r--r--keyboards/ergodox/infinity/config.h5
-rw-r--r--keyboards/ergodox/keymaps/swedish/keymap.c247
-rw-r--r--keyboards/ergodox/keymaps/swedish/readme.md36
-rw-r--r--keyboards/orthodox/Makefile5
-rw-r--r--keyboards/orthodox/common/glcdfont.c276
-rw-r--r--keyboards/orthodox/config.h32
-rw-r--r--keyboards/orthodox/i2c.c162
-rw-r--r--keyboards/orthodox/i2c.h50
-rw-r--r--keyboards/orthodox/keymaps/i2c/config.h34
-rw-r--r--keyboards/orthodox/keymaps/i2c/keymap.c132
-rw-r--r--keyboards/orthodox/keymaps/serial/config.h34
-rw-r--r--keyboards/orthodox/keymaps/serial/keymap.c132
-rw-r--r--keyboards/orthodox/matrix.c351
-rw-r--r--keyboards/orthodox/orthodox.c1
-rw-r--r--keyboards/orthodox/orthodox.h30
-rw-r--r--keyboards/orthodox/pro_micro.h362
-rw-r--r--keyboards/orthodox/readme.md165
-rw-r--r--keyboards/orthodox/rev1/Makefile3
-rw-r--r--keyboards/orthodox/rev1/config.h99
-rw-r--r--keyboards/orthodox/rev1/rev1.c32
-rw-r--r--keyboards/orthodox/rev1/rev1.h25
-rw-r--r--keyboards/orthodox/rev1/rules.mk5
-rw-r--r--keyboards/orthodox/rules.mk87
-rw-r--r--keyboards/orthodox/serial.c230
-rw-r--r--keyboards/orthodox/serial.h27
-rw-r--r--keyboards/orthodox/split_util.c84
-rw-r--r--keyboards/orthodox/split_util.h24
-rw-r--r--keyboards/orthodox/ssd1306.c470
-rw-r--r--keyboards/orthodox/ssd1306.h17
-rw-r--r--keyboards/planck/keymaps/rai-suta/Makefile28
-rw-r--r--keyboards/planck/keymaps/rai-suta/config.h8
-rw-r--r--keyboards/planck/keymaps/rai-suta/keymap.c107
-rw-r--r--keyboards/planck/keymaps/rai-suta/readme.md3
-rw-r--r--keyboards/whitefox/animations.c128
-rw-r--r--keyboards/whitefox/animations.h30
-rw-r--r--keyboards/whitefox/config.h14
-rw-r--r--keyboards/whitefox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h109
-rw-r--r--keyboards/whitefox/drivers/gdisp/IS31FL3731C/driver.mk2
-rw-r--r--keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c312
-rw-r--r--keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h36
-rw-r--r--keyboards/whitefox/gfxconf.h329
-rw-r--r--keyboards/whitefox/halconf.h2
-rw-r--r--keyboards/whitefox/keymaps/jetpacktuxedo/Makefile5
-rw-r--r--keyboards/whitefox/keymaps/jetpacktuxedo/keymap.c14
-rw-r--r--keyboards/whitefox/rules.mk7
-rw-r--r--keyboards/whitefox/visualizer.c60
-rw-r--r--quantum/keycode_config.c28
-rw-r--r--quantum/keycode_config.h2
-rw-r--r--quantum/keymap_common.c3
-rw-r--r--quantum/keymap_extras/keymap_swedish.h52
-rw-r--r--quantum/quantum.c2
-rw-r--r--quantum/quantum_keycodes.h4
-rw-r--r--quantum/visualizer/led_keyframes.c4
-rw-r--r--quantum/visualizer/visualizer.c33
-rw-r--r--quantum/visualizer/visualizer.mk26
56 files changed, 4466 insertions, 40 deletions
diff --git a/docs/_summary.md b/docs/_summary.md
index 8e0a6f51c..c5e29cb52 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -29,3 +29,4 @@
29### Other topics 29### Other topics
30* [General FAQ](faq.md) 30* [General FAQ](faq.md)
31* [Differences from TMK](differences_from_tmk.md) 31* [Differences from TMK](differences_from_tmk.md)
32* [Using Eclipse with QMK](eclipse.md)
diff --git a/keyboards/ergodox/infinity/config.h b/keyboards/ergodox/infinity/config.h
index 95f713819..25cc8af0f 100644
--- a/keyboards/ergodox/infinity/config.h
+++ b/keyboards/ergodox/infinity/config.h
@@ -56,6 +56,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
56 56
57#define VISUALIZER_USER_DATA_SIZE 16 57#define VISUALIZER_USER_DATA_SIZE 16
58 58
59#define LCD_DISPLAY_NUMBER 0
60#define LED_DISPLAY_NUMBER 1
61
62#define LED_NUM_ROWS 7
63#define LED_NUM_COLS 7
59/* 64/*
60 * Feature disable options 65 * Feature disable options
61 * These options are also useful to firmware size reduction. 66 * These options are also useful to firmware size reduction.
diff --git a/keyboards/ergodox/keymaps/swedish/keymap.c b/keyboards/ergodox/keymaps/swedish/keymap.c
new file mode 100644
index 000000000..c110538e6
--- /dev/null
+++ b/keyboards/ergodox/keymaps/swedish/keymap.c
@@ -0,0 +1,247 @@
1/* Copyright 2017 Andreas Lindhé
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include "ergodox.h"
18#include "debug.h"
19#include "action_layer.h"
20#include "version.h"
21#include "keymap_swedish.h"
22
23#define BASE 0 // default layer
24#define SYMB 1 // symbols
25#define MDIA 2 // media keys
26
27enum custom_keycodes {
28 PLACEHOLDER = SAFE_RANGE, // can always be here
29 EPRM,
30 VRSN,
31 RGB_SLD
32};
33
34const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
35/* Keymap 0: Basic layer
36 *
37 * ,--------------------------------------------------. ,--------------------------------------------------.
38 * | ½ | ! | " | # | # | % | LEFT | | RIGHT| & | / | ( | ) | = | ? |
39 * | § | 1 | 2 @ | 3 £ | 4 $ | 5 | | | | 6 | 7 { | 8 [ | 9 ] | 0 } | + \ |
40 * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
41 * | Delete | Q | W | E | R | T | L1 | | L1 | Y | U | I | O | P | Å |
42 * | | | | | | | | | | | | | | | |
43 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
44 * | Caps | A | S | D | F | G |------| |------| H | J | K | L |Ö / L2|Ä / Cmd |
45 * | Lock | | | | | | Hyper| | Meh | | | | | | |
46 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
47 * | Left |Z/Ctrl| X | C | V | B | | | | N | M | ; | : |_/Ctrl| RShift |
48 * | Shift | | | | | | | | | | | , | . |- | |
49 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
50 * | '/L1 | ` |AltShf| Left | Right| | Up | Down | ^ | * | ~L1 |
51 * | | ' | | | | | | | | | |
52 * `----------------------------------' `----------------------------------'
53 * ,-------------. ,---------------.
54 * | App | LGui | | AltGr|Ctrl/Esc|
55 * ,------|------|------| |------+--------+------.
56 * | | | Home | | PgUp | | |
57 * | Space|Back- |------| |------| Tab |Enter |
58 * | |space | End | | PgDn | | |
59 * `--------------------' `----------------------'
60 */
61// If it accepts an argument (i.e, is a function), it doesn't need KC_.
62// Otherwise, it needs KC_*
63[BASE] = KEYMAP( // layer 0 : default
64 // left hand
65 NO_HALF, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LEFT,
66 KC_DELT, KC_Q, KC_W, KC_E, KC_R, KC_T, TG(SYMB),
67 KC_BSPC, KC_A, KC_S, KC_D, KC_F, KC_G,
68 KC_LSFT, CTL_T(KC_Z), KC_X, KC_C, KC_V, KC_B, ALL_T(KC_NO),
69 LT(SYMB,NO_APOS), NO_ACUT, LALT(KC_LSFT), KC_LEFT, KC_RGHT,
70 ALT_T(KC_APP), KC_LGUI,
71 KC_HOME,
72 KC_SPC,KC_BSPC,KC_END,
73 // right hand
74 KC_RGHT, KC_6, KC_7, KC_8, KC_9, KC_0, NO_PLUS,
75 TG(SYMB), KC_Y, KC_U, KC_I, KC_O, KC_P, NO_AA,
76 KC_H, KC_J, KC_K, KC_L, LT(MDIA, NO_OSLH), GUI_T(NO_AE),
77 MEH_T(KC_NO), KC_N, KC_M, KC_COMM, KC_DOT, CTL_T(NO_MINS), KC_RSFT,
78 KC_UP, KC_DOWN, NO_CIRC, NO_ASTR, KC_FN1,
79 NO_ALGR, CTL_T(KC_ESC),
80 KC_PGUP,
81 KC_PGDN,KC_TAB, KC_ENT
82),
83
84/* Keymap 1: Symbol Layer
85 *
86 * ,--------------------------------------------------. ,--------------------------------------------------.
87 * |Version | F1 | F2 | F3 | F4 | F5 | | | | F6 | F7 | F8 | F9 | F10 | F11 |
88 * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
89 * | | ! | @ | { | } | | | | | | Up | 7 | 8 | 9 | * | F12 |
90 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
91 * | | # | $ | ( | ) | ` |------| |------| Down | 4 | 5 | 6 | + | |
92 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
93 * | | % | ^ | [ | ] | ~ | | | | & | 1 | 2 | 3 | \ | |
94 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
95 * | | | | | | | | . | 0 | = | |
96 * `----------------------------------' `----------------------------------'
97 * ,-------------. ,-------------.
98 * |Animat| | |Toggle|Solid |
99 * ,------|------|------| |------+------+------.
100 * |Bright|Bright| | | |Hue- |Hue+ |
101 * |ness- |ness+ |------| |------| | |
102 * | | | | | | | |
103 * `--------------------' `--------------------'
104 */
105// SYMBOLS
106[SYMB] = KEYMAP(
107 // left hand
108 VRSN, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_TRNS,
109 KC_TRNS,KC_EXLM,NO_AT, NO_LCBR,NO_RCBR,NO_PIPE,KC_TRNS,
110 KC_TRNS,KC_HASH,NO_DLR, NO_LPRN,NO_RPRN,NO_GRV,
111 KC_TRNS,KC_PERC,NO_CIRC,NO_LBRC,NO_RBRC,NO_TILD,KC_TRNS,
112 EPRM,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
113 RGB_MOD,KC_TRNS,
114 KC_TRNS,
115 RGB_VAD,RGB_VAI,KC_TRNS,
116 // right hand
117 KC_TRNS, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11,
118 KC_TRNS, KC_UP, KC_7, KC_8, KC_9, NO_ASTR, KC_F12,
119 KC_DOWN, KC_4, KC_5, KC_6, NO_PLUS, KC_TRNS,
120 KC_TRNS, NO_AMPR, KC_1, KC_2, KC_3, NO_MINS, KC_TRNS,
121 KC_TRNS,KC_DOT, KC_0, NO_EQL, KC_TRNS,
122 RGB_TOG, RGB_SLD,
123 KC_TRNS,
124 KC_TRNS, RGB_HUD, RGB_HUI
125),
126
127/* Keymap 2: Media and mouse keys
128 *
129 * ,--------------------------------------------------. ,--------------------------------------------------.
130 * | | | | | | | | | | | | | | | |
131 * |--------+------+------+------+------+-------------| |------+------+------+------+------+------+--------|
132 * | | | | MsUp | | | | | | | | | | | |
133 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
134 * | | |MsLeft|MsDown|MsRght| |------| |------| | | | | | Play |
135 * |--------+------+------+------+------+------| | | |------+------+------+------+------+--------|
136 * | | | | | | | | | | | | Prev | Next | | |
137 * `--------+------+------+------+------+-------------' `-------------+------+------+------+------+--------'
138 * | | | | Lclk | Rclk | |VolUp |VolDn | Mute | | |
139 * `----------------------------------' `----------------------------------'
140 * ,-------------. ,-------------.
141 * | | | | | |
142 * ,------|------|------| |------+------+------.
143 * | | | | | | |Brwser|
144 * | | |------| |------| |Back |
145 * | | | | | | | |
146 * `--------------------' `--------------------'
147 */
148// MEDIA AND MOUSE
149[MDIA] = KEYMAP(
150 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
151 KC_TRNS, KC_TRNS, KC_TRNS, KC_MS_U, KC_TRNS, KC_TRNS, KC_TRNS,
152 KC_TRNS, KC_TRNS, KC_MS_L, KC_MS_D, KC_MS_R, KC_TRNS,
153 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
154 KC_TRNS, KC_TRNS, KC_TRNS, KC_BTN1, KC_BTN2,
155 KC_TRNS, KC_TRNS,
156 KC_TRNS,
157 KC_TRNS, KC_TRNS, KC_TRNS,
158 // right hand
159 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
160 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
161 KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY,
162 KC_TRNS, KC_TRNS, KC_TRNS, KC_MPRV, KC_MNXT, KC_TRNS, KC_TRNS,
163 KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS,
164 KC_TRNS, KC_TRNS,
165 KC_TRNS,
166 KC_TRNS, KC_TRNS, KC_WBAK
167),
168};
169
170const uint16_t PROGMEM fn_actions[] = {
171 [1] = ACTION_LAYER_TAP_TOGGLE(SYMB) // FN1 - Momentary Layer 1 (Symbols)
172};
173
174const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
175{
176 // MACRODOWN only works in this function
177 switch(id) {
178 case 0:
179 if (record->event.pressed) {
180 SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
181 }
182 break;
183 case 1:
184 if (record->event.pressed) { // For resetting EEPROM
185 eeconfig_init();
186 }
187 break;
188 }
189 return MACRO_NONE;
190};
191
192bool process_record_user(uint16_t keycode, keyrecord_t *record) {
193 switch (keycode) {
194 // dynamically generate these.
195 case EPRM:
196 if (record->event.pressed) {
197 eeconfig_init();
198 }
199 return false;
200 break;
201 case VRSN:
202 if (record->event.pressed) {
203 SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
204 }
205 return false;
206 break;
207 case RGB_SLD:
208 if (record->event.pressed) {
209 #ifdef RGBLIGHT_ENABLE
210 rgblight_mode(1);
211 #endif
212 }
213 return false;
214 break;
215 }
216 return true;
217}
218
219// Runs just one time when the keyboard initializes.
220void matrix_init_user(void) {
221
222};
223
224
225// Runs constantly in the background, in a loop.
226void matrix_scan_user(void) {
227
228 uint8_t layer = biton32(layer_state);
229
230 ergodox_board_led_off();
231 ergodox_right_led_1_off();
232 ergodox_right_led_2_off();
233 ergodox_right_led_3_off();
234 switch (layer) {
235 // TODO: Make this relevant to the ErgoDox EZ.
236 case 1:
237 ergodox_right_led_1_on();
238 break;
239 case 2:
240 ergodox_right_led_2_on();
241 break;
242 default:
243 // none
244 break;
245 }
246
247};
diff --git a/keyboards/ergodox/keymaps/swedish/readme.md b/keyboards/ergodox/keymaps/swedish/readme.md
new file mode 100644
index 000000000..b5b859bce
--- /dev/null
+++ b/keyboards/ergodox/keymaps/swedish/readme.md
@@ -0,0 +1,36 @@
1# Swedish (sv_SE) Qwerty layout for ErgoDox EZ, based on the Default configuration
2
3*NOTE:* it might still be desirable to set the software layout to sv_SE in your
4OS.
5
6Remind me and I'll provide a picture of the layout.
7
8I have tried making this as close of a match I could between the [default
9ErgoDox EZ configuration](https://ergodox-ez.com/pages/our-firmware) and a
10standard Swedish Qwerty layout.
11
12## Notable differences from default:
13
14* There are three special character buttons (acute accent, circumflex/tilde and
15 apostrophe/asterisk) that don't have any buttons to map to naturally. I've put
16 these at other places:
17
18 * Acute accent (´) can be found in the lower left corner, conveniently
19 placed to reach for making an é.
20
21 * Apostrophe (') was put in the lower left corner, close to acute accent.
22
23 * Circumflex (^) and asterisk (*) was placed in the lower right corner.
24
25 * Tilde (~) and diaeresis (¨) I couldn't find a good place for, so I left
26 those out. I could only get the buttons to produce a single one of the
27 characters. How can I get it to work properly?
28
29* The Alt button on right thumb was exchanged for AltGr (RAlt).
30
31* I changed the backslash in the numpad (layer 1) for a minus. Thought it was
32 more sensible.
33
34* I didn't find a good place for the "<>|" button, so that one was left out.
35 That is a problem that really needs to be resolved. Pipe can be found on layer
36 one, however.
diff --git a/keyboards/orthodox/Makefile b/keyboards/orthodox/Makefile
new file mode 100644
index 000000000..f5c87d4d6
--- /dev/null
+++ b/keyboards/orthodox/Makefile
@@ -0,0 +1,5 @@
1SUBPROJECT_DEFAULT = rev2
2
3ifndef MAKEFILE_INCLUDED
4 include ../../Makefile
5endif
diff --git a/keyboards/orthodox/common/glcdfont.c b/keyboards/orthodox/common/glcdfont.c
new file mode 100644
index 000000000..6f88bd23a
--- /dev/null
+++ b/keyboards/orthodox/common/glcdfont.c
@@ -0,0 +1,276 @@
1// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
2// See gfxfont.h for newer custom bitmap font info.
3
4#ifndef FONT5X7_H
5#define FONT5X7_H
6
7#ifdef __AVR__
8 #include <avr/io.h>
9 #include <avr/pgmspace.h>
10#elif defined(ESP8266)
11 #include <pgmspace.h>
12#else
13 #define PROGMEM
14#endif
15
16// Standard ASCII 5x7 font
17
18static const unsigned char font[] PROGMEM = {
19 0x00, 0x00, 0x00, 0x00, 0x00,
20 0x3E, 0x5B, 0x4F, 0x5B, 0x3E,
21 0x3E, 0x6B, 0x4F, 0x6B, 0x3E,
22 0x1C, 0x3E, 0x7C, 0x3E, 0x1C,
23 0x18, 0x3C, 0x7E, 0x3C, 0x18,
24 0x1C, 0x57, 0x7D, 0x57, 0x1C,
25 0x1C, 0x5E, 0x7F, 0x5E, 0x1C,
26 0x00, 0x18, 0x3C, 0x18, 0x00,
27 0xFF, 0xE7, 0xC3, 0xE7, 0xFF,
28 0x00, 0x18, 0x24, 0x18, 0x00,
29 0xFF, 0xE7, 0xDB, 0xE7, 0xFF,
30 0x30, 0x48, 0x3A, 0x06, 0x0E,
31 0x26, 0x29, 0x79, 0x29, 0x26,
32 0x40, 0x7F, 0x05, 0x05, 0x07,
33 0x40, 0x7F, 0x05, 0x25, 0x3F,
34 0x5A, 0x3C, 0xE7, 0x3C, 0x5A,
35 0x7F, 0x3E, 0x1C, 0x1C, 0x08,
36 0x08, 0x1C, 0x1C, 0x3E, 0x7F,
37 0x14, 0x22, 0x7F, 0x22, 0x14,
38 0x5F, 0x5F, 0x00, 0x5F, 0x5F,
39 0x06, 0x09, 0x7F, 0x01, 0x7F,
40 0x00, 0x66, 0x89, 0x95, 0x6A,
41 0x60, 0x60, 0x60, 0x60, 0x60,
42 0x94, 0xA2, 0xFF, 0xA2, 0x94,
43 0x08, 0x04, 0x7E, 0x04, 0x08,
44 0x10, 0x20, 0x7E, 0x20, 0x10,
45 0x08, 0x08, 0x2A, 0x1C, 0x08,
46 0x08, 0x1C, 0x2A, 0x08, 0x08,
47 0x1E, 0x10, 0x10, 0x10, 0x10,
48 0x0C, 0x1E, 0x0C, 0x1E, 0x0C,
49 0x30, 0x38, 0x3E, 0x38, 0x30,
50 0x06, 0x0E, 0x3E, 0x0E, 0x06,
51 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x5F, 0x00, 0x00,
53 0x00, 0x07, 0x00, 0x07, 0x00,
54 0x14, 0x7F, 0x14, 0x7F, 0x14,
55 0x24, 0x2A, 0x7F, 0x2A, 0x12,
56 0x23, 0x13, 0x08, 0x64, 0x62,
57 0x36, 0x49, 0x56, 0x20, 0x50,
58 0x00, 0x08, 0x07, 0x03, 0x00,
59 0x00, 0x1C, 0x22, 0x41, 0x00,
60 0x00, 0x41, 0x22, 0x1C, 0x00,
61 0x2A, 0x1C, 0x7F, 0x1C, 0x2A,
62 0x08, 0x08, 0x3E, 0x08, 0x08,
63 0x00, 0x80, 0x70, 0x30, 0x00,
64 0x08, 0x08, 0x08, 0x08, 0x08,
65 0x00, 0x00, 0x60, 0x60, 0x00,
66 0x20, 0x10, 0x08, 0x04, 0x02,
67 0x3E, 0x51, 0x49, 0x45, 0x3E,
68 0x00, 0x42, 0x7F, 0x40, 0x00,
69 0x72, 0x49, 0x49, 0x49, 0x46,
70 0x21, 0x41, 0x49, 0x4D, 0x33,
71 0x18, 0x14, 0x12, 0x7F, 0x10,
72 0x27, 0x45, 0x45, 0x45, 0x39,
73 0x3C, 0x4A, 0x49, 0x49, 0x31,
74 0x41, 0x21, 0x11, 0x09, 0x07,
75 0x36, 0x49, 0x49, 0x49, 0x36,
76 0x46, 0x49, 0x49, 0x29, 0x1E,
77 0x00, 0x00, 0x14, 0x00, 0x00,
78 0x00, 0x40, 0x34, 0x00, 0x00,
79 0x00, 0x08, 0x14, 0x22, 0x41,
80 0x14, 0x14, 0x14, 0x14, 0x14,
81 0x00, 0x41, 0x22, 0x14, 0x08,
82 0x02, 0x01, 0x59, 0x09, 0x06,
83 0x3E, 0x41, 0x5D, 0x59, 0x4E,
84 0x7C, 0x12, 0x11, 0x12, 0x7C,
85 0x7F, 0x49, 0x49, 0x49, 0x36,
86 0x3E, 0x41, 0x41, 0x41, 0x22,
87 0x7F, 0x41, 0x41, 0x41, 0x3E,
88 0x7F, 0x49, 0x49, 0x49, 0x41,
89 0x7F, 0x09, 0x09, 0x09, 0x01,
90 0x3E, 0x41, 0x41, 0x51, 0x73,
91 0x7F, 0x08, 0x08, 0x08, 0x7F,
92 0x00, 0x41, 0x7F, 0x41, 0x00,
93 0x20, 0x40, 0x41, 0x3F, 0x01,
94 0x7F, 0x08, 0x14, 0x22, 0x41,
95 0x7F, 0x40, 0x40, 0x40, 0x40,
96 0x7F, 0x02, 0x1C, 0x02, 0x7F,
97 0x7F, 0x04, 0x08, 0x10, 0x7F,
98 0x3E, 0x41, 0x41, 0x41, 0x3E,
99 0x7F, 0x09, 0x09, 0x09, 0x06,
100 0x3E, 0x41, 0x51, 0x21, 0x5E,
101 0x7F, 0x09, 0x19, 0x29, 0x46,
102 0x26, 0x49, 0x49, 0x49, 0x32,
103 0x03, 0x01, 0x7F, 0x01, 0x03,
104 0x3F, 0x40, 0x40, 0x40, 0x3F,
105 0x1F, 0x20, 0x40, 0x20, 0x1F,
106 0x3F, 0x40, 0x38, 0x40, 0x3F,
107 0x63, 0x14, 0x08, 0x14, 0x63,
108 0x03, 0x04, 0x78, 0x04, 0x03,
109 0x61, 0x59, 0x49, 0x4D, 0x43,
110 0x00, 0x7F, 0x41, 0x41, 0x41,
111 0x02, 0x04, 0x08, 0x10, 0x20,
112 0x00, 0x41, 0x41, 0x41, 0x7F,
113 0x04, 0x02, 0x01, 0x02, 0x04,
114 0x40, 0x40, 0x40, 0x40, 0x40,
115 0x00, 0x03, 0x07, 0x08, 0x00,
116 0x20, 0x54, 0x54, 0x78, 0x40,
117 0x7F, 0x28, 0x44, 0x44, 0x38,
118 0x38, 0x44, 0x44, 0x44, 0x28,
119 0x38, 0x44, 0x44, 0x28, 0x7F,
120 0x38, 0x54, 0x54, 0x54, 0x18,
121 0x00, 0x08, 0x7E, 0x09, 0x02,
122 0x18, 0xA4, 0xA4, 0x9C, 0x78,
123 0x7F, 0x08, 0x04, 0x04, 0x78,
124 0x00, 0x44, 0x7D, 0x40, 0x00,
125 0x20, 0x40, 0x40, 0x3D, 0x00,
126 0x7F, 0x10, 0x28, 0x44, 0x00,
127 0x00, 0x41, 0x7F, 0x40, 0x00,
128 0x7C, 0x04, 0x78, 0x04, 0x78,
129 0x7C, 0x08, 0x04, 0x04, 0x78,
130 0x38, 0x44, 0x44, 0x44, 0x38,
131 0xFC, 0x18, 0x24, 0x24, 0x18,
132 0x18, 0x24, 0x24, 0x18, 0xFC,
133 0x7C, 0x08, 0x04, 0x04, 0x08,
134 0x48, 0x54, 0x54, 0x54, 0x24,
135 0x04, 0x04, 0x3F, 0x44, 0x24,
136 0x3C, 0x40, 0x40, 0x20, 0x7C,
137 0x1C, 0x20, 0x40, 0x20, 0x1C,
138 0x3C, 0x40, 0x30, 0x40, 0x3C,
139 0x44, 0x28, 0x10, 0x28, 0x44,
140 0x4C, 0x90, 0x90, 0x90, 0x7C,
141 0x44, 0x64, 0x54, 0x4C, 0x44,
142 0x00, 0x08, 0x36, 0x41, 0x00,
143 0x00, 0x00, 0x77, 0x00, 0x00,
144 0x00, 0x41, 0x36, 0x08, 0x00,
145 0x02, 0x01, 0x02, 0x04, 0x02,
146 0x3C, 0x26, 0x23, 0x26, 0x3C,
147 0x1E, 0xA1, 0xA1, 0x61, 0x12,
148 0x3A, 0x40, 0x40, 0x20, 0x7A,
149 0x38, 0x54, 0x54, 0x55, 0x59,
150 0x21, 0x55, 0x55, 0x79, 0x41,
151 0x22, 0x54, 0x54, 0x78, 0x42, // a-umlaut
152 0x21, 0x55, 0x54, 0x78, 0x40,
153 0x20, 0x54, 0x55, 0x79, 0x40,
154 0x0C, 0x1E, 0x52, 0x72, 0x12,
155 0x39, 0x55, 0x55, 0x55, 0x59,
156 0x39, 0x54, 0x54, 0x54, 0x59,
157 0x39, 0x55, 0x54, 0x54, 0x58,
158 0x00, 0x00, 0x45, 0x7C, 0x41,
159 0x00, 0x02, 0x45, 0x7D, 0x42,
160 0x00, 0x01, 0x45, 0x7C, 0x40,
161 0x7D, 0x12, 0x11, 0x12, 0x7D, // A-umlaut
162 0xF0, 0x28, 0x25, 0x28, 0xF0,
163 0x7C, 0x54, 0x55, 0x45, 0x00,
164 0x20, 0x54, 0x54, 0x7C, 0x54,
165 0x7C, 0x0A, 0x09, 0x7F, 0x49,
166 0x32, 0x49, 0x49, 0x49, 0x32,
167 0x3A, 0x44, 0x44, 0x44, 0x3A, // o-umlaut
168 0x32, 0x4A, 0x48, 0x48, 0x30,
169 0x3A, 0x41, 0x41, 0x21, 0x7A,
170 0x3A, 0x42, 0x40, 0x20, 0x78,
171 0x00, 0x9D, 0xA0, 0xA0, 0x7D,
172 0x3D, 0x42, 0x42, 0x42, 0x3D, // O-umlaut
173 0x3D, 0x40, 0x40, 0x40, 0x3D,
174 0x3C, 0x24, 0xFF, 0x24, 0x24,
175 0x48, 0x7E, 0x49, 0x43, 0x66,
176 0x2B, 0x2F, 0xFC, 0x2F, 0x2B,
177 0xFF, 0x09, 0x29, 0xF6, 0x20,
178 0xC0, 0x88, 0x7E, 0x09, 0x03,
179 0x20, 0x54, 0x54, 0x79, 0x41,
180 0x00, 0x00, 0x44, 0x7D, 0x41,
181 0x30, 0x48, 0x48, 0x4A, 0x32,
182 0x38, 0x40, 0x40, 0x22, 0x7A,
183 0x00, 0x7A, 0x0A, 0x0A, 0x72,
184 0x7D, 0x0D, 0x19, 0x31, 0x7D,
185 0x26, 0x29, 0x29, 0x2F, 0x28,
186 0x26, 0x29, 0x29, 0x29, 0x26,
187 0x30, 0x48, 0x4D, 0x40, 0x20,
188 0x38, 0x08, 0x08, 0x08, 0x08,
189 0x08, 0x08, 0x08, 0x08, 0x38,
190 0x2F, 0x10, 0xC8, 0xAC, 0xBA,
191 0x2F, 0x10, 0x28, 0x34, 0xFA,
192 0x00, 0x00, 0x7B, 0x00, 0x00,
193 0x08, 0x14, 0x2A, 0x14, 0x22,
194 0x22, 0x14, 0x2A, 0x14, 0x08,
195 0x55, 0x00, 0x55, 0x00, 0x55, // #176 (25% block) missing in old code
196 0xAA, 0x55, 0xAA, 0x55, 0xAA, // 50% block
197 0xFF, 0x55, 0xFF, 0x55, 0xFF, // 75% block
198 0x00, 0x00, 0x00, 0xFF, 0x00,
199 0x10, 0x10, 0x10, 0xFF, 0x00,
200 0x14, 0x14, 0x14, 0xFF, 0x00,
201 0x10, 0x10, 0xFF, 0x00, 0xFF,
202 0x10, 0x10, 0xF0, 0x10, 0xF0,
203 0x14, 0x14, 0x14, 0xFC, 0x00,
204 0x14, 0x14, 0xF7, 0x00, 0xFF,
205 0x00, 0x00, 0xFF, 0x00, 0xFF,
206 0x14, 0x14, 0xF4, 0x04, 0xFC,
207 0x14, 0x14, 0x17, 0x10, 0x1F,
208 0x10, 0x10, 0x1F, 0x10, 0x1F,
209 0x14, 0x14, 0x14, 0x1F, 0x00,
210 0x10, 0x10, 0x10, 0xF0, 0x00,
211 0x00, 0x00, 0x00, 0x1F, 0x10,
212 0x10, 0x10, 0x10, 0x1F, 0x10,
213 0x10, 0x10, 0x10, 0xF0, 0x10,
214 0x00, 0x00, 0x00, 0xFF, 0x10,
215 0x10, 0x10, 0x10, 0x10, 0x10,
216 0x10, 0x10, 0x10, 0xFF, 0x10,
217 0x00, 0x00, 0x00, 0xFF, 0x14,
218 0x00, 0x00, 0xFF, 0x00, 0xFF,
219 0x00, 0x00, 0x1F, 0x10, 0x17,
220 0x00, 0x00, 0xFC, 0x04, 0xF4,
221 0x14, 0x14, 0x17, 0x10, 0x17,
222 0x14, 0x14, 0xF4, 0x04, 0xF4,
223 0x00, 0x00, 0xFF, 0x00, 0xF7,
224 0x14, 0x14, 0x14, 0x14, 0x14,
225 0x14, 0x14, 0xF7, 0x00, 0xF7,
226 0x14, 0x14, 0x14, 0x17, 0x14,
227 0x10, 0x10, 0x1F, 0x10, 0x1F,
228 0x14, 0x14, 0x14, 0xF4, 0x14,
229 0x10, 0x10, 0xF0, 0x10, 0xF0,
230 0x00, 0x00, 0x1F, 0x10, 0x1F,
231 0x00, 0x00, 0x00, 0x1F, 0x14,
232 0x00, 0x00, 0x00, 0xFC, 0x14,
233 0x00, 0x00, 0xF0, 0x10, 0xF0,
234 0x10, 0x10, 0xFF, 0x10, 0xFF,
235 0x14, 0x14, 0x14, 0xFF, 0x14,
236 0x10, 0x10, 0x10, 0x1F, 0x00,
237 0x00, 0x00, 0x00, 0xF0, 0x10,
238 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
239 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
240 0xFF, 0xFF, 0xFF, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0xFF, 0xFF,
242 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
243 0x38, 0x44, 0x44, 0x38, 0x44,
244 0xFC, 0x4A, 0x4A, 0x4A, 0x34, // sharp-s or beta
245 0x7E, 0x02, 0x02, 0x06, 0x06,
246 0x02, 0x7E, 0x02, 0x7E, 0x02,
247 0x63, 0x55, 0x49, 0x41, 0x63,
248 0x38, 0x44, 0x44, 0x3C, 0x04,
249 0x40, 0x7E, 0x20, 0x1E, 0x20,
250 0x06, 0x02, 0x7E, 0x02, 0x02,
251 0x99, 0xA5, 0xE7, 0xA5, 0x99,
252 0x1C, 0x2A, 0x49, 0x2A, 0x1C,
253 0x4C, 0x72, 0x01, 0x72, 0x4C,
254 0x30, 0x4A, 0x4D, 0x4D, 0x30,
255 0x30, 0x48, 0x78, 0x48, 0x30,
256 0xBC, 0x62, 0x5A, 0x46, 0x3D,
257 0x3E, 0x49, 0x49, 0x49, 0x00,
258 0x7E, 0x01, 0x01, 0x01, 0x7E,
259 0x2A, 0x2A, 0x2A, 0x2A, 0x2A,
260 0x44, 0x44, 0x5F, 0x44, 0x44,
261 0x40, 0x51, 0x4A, 0x44, 0x40,
262 0x40, 0x44, 0x4A, 0x51, 0x40,
263 0x00, 0x00, 0xFF, 0x01, 0x03,
264 0xE0, 0x80, 0xFF, 0x00, 0x00,
265 0x08, 0x08, 0x6B, 0x6B, 0x08,
266 0x36, 0x12, 0x36, 0x24, 0x36,
267 0x06, 0x0F, 0x09, 0x0F, 0x06,
268 0x00, 0x00, 0x18, 0x18, 0x00,
269 0x00, 0x00, 0x10, 0x10, 0x00,
270 0x30, 0x40, 0xFF, 0x01, 0x01,
271 0x00, 0x1F, 0x01, 0x01, 0x1E,
272 0x00, 0x19, 0x1D, 0x17, 0x12,
273 0x00, 0x3C, 0x3C, 0x3C, 0x3C,
274 0x00, 0x00, 0x00, 0x00, 0x00 // #255 NBSP
275};
276#endif // FONT5X7_H
diff --git a/keyboards/orthodox/config.h b/keyboards/orthodox/config.h
new file mode 100644
index 000000000..008fb0978
--- /dev/null
+++ b/keyboards/orthodox/config.h
@@ -0,0 +1,32 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef CONFIG_H
19#define CONFIG_H
20
21#include "config_common.h"
22
23#ifdef SUBPROJECT_rev1
24 #include "rev1/config.h"
25#endif
26#ifdef SUBPROJECT_rev2
27 #include "rev2/config.h"
28#endif
29#ifdef SUBPROJECT_rev2fliphalf
30 #include "../../rev2fliphalf/config.h"
31#endif
32#endif
diff --git a/keyboards/orthodox/i2c.c b/keyboards/orthodox/i2c.c
new file mode 100644
index 000000000..084c890c4
--- /dev/null
+++ b/keyboards/orthodox/i2c.c
@@ -0,0 +1,162 @@
1#include <util/twi.h>
2#include <avr/io.h>
3#include <stdlib.h>
4#include <avr/interrupt.h>
5#include <util/twi.h>
6#include <stdbool.h>
7#include "i2c.h"
8
9#ifdef USE_I2C
10
11// Limits the amount of we wait for any one i2c transaction.
12// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is
13// 9 bits, a single transaction will take around 90μs to complete.
14//
15// (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit
16// poll loop takes at least 8 clock cycles to execute
17#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8
18
19#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE)
20
21volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
22
23static volatile uint8_t slave_buffer_pos;
24static volatile bool slave_has_register_set = false;
25
26// Wait for an i2c operation to finish
27inline static
28void i2c_delay(void) {
29 uint16_t lim = 0;
30 while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT)
31 lim++;
32
33 // easier way, but will wait slightly longer
34 // _delay_us(100);
35}
36
37// Setup twi to run at 100kHz
38void i2c_master_init(void) {
39 // no prescaler
40 TWSR = 0;
41 // Set TWI clock frequency to SCL_CLOCK. Need TWBR>10.
42 // Check datasheets for more info.
43 TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
44}
45
46// Start a transaction with the given i2c slave address. The direction of the
47// transfer is set with I2C_READ and I2C_WRITE.
48// returns: 0 => success
49// 1 => error
50uint8_t i2c_master_start(uint8_t address) {
51 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
52
53 i2c_delay();
54
55 // check that we started successfully
56 if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))
57 return 1;
58
59 TWDR = address;
60 TWCR = (1<<TWINT) | (1<<TWEN);
61
62 i2c_delay();
63
64 if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) )
65 return 1; // slave did not acknowledge
66 else
67 return 0; // success
68}
69
70
71// Finish the i2c transaction.
72void i2c_master_stop(void) {
73 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
74
75 uint16_t lim = 0;
76 while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT)
77 lim++;
78}
79
80// Write one byte to the i2c slave.
81// returns 0 => slave ACK
82// 1 => slave NACK
83uint8_t i2c_master_write(uint8_t data) {
84 TWDR = data;
85 TWCR = (1<<TWINT) | (1<<TWEN);
86
87 i2c_delay();
88
89 // check if the slave acknowledged us
90 return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1;
91}
92
93// Read one byte from the i2c slave. If ack=1 the slave is acknowledged,
94// if ack=0 the acknowledge bit is not set.
95// returns: byte read from i2c device
96uint8_t i2c_master_read(int ack) {
97 TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA);
98
99 i2c_delay();
100 return TWDR;
101}
102
103void i2c_reset_state(void) {
104 TWCR = 0;
105}
106
107void i2c_slave_init(uint8_t address) {
108 TWAR = address << 0; // slave i2c address
109 // TWEN - twi enable
110 // TWEA - enable address acknowledgement
111 // TWINT - twi interrupt flag
112 // TWIE - enable the twi interrupt
113 TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
114}
115
116ISR(TWI_vect);
117
118ISR(TWI_vect) {
119 uint8_t ack = 1;
120 switch(TW_STATUS) {
121 case TW_SR_SLA_ACK:
122 // this device has been addressed as a slave receiver
123 slave_has_register_set = false;
124 break;
125
126 case TW_SR_DATA_ACK:
127 // this device has received data as a slave receiver
128 // The first byte that we receive in this transaction sets the location
129 // of the read/write location of the slaves memory that it exposes over
130 // i2c. After that, bytes will be written at slave_buffer_pos, incrementing
131 // slave_buffer_pos after each write.
132 if(!slave_has_register_set) {
133 slave_buffer_pos = TWDR;
134 // don't acknowledge the master if this memory loctaion is out of bounds
135 if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) {
136 ack = 0;
137 slave_buffer_pos = 0;
138 }
139 slave_has_register_set = true;
140 } else {
141 i2c_slave_buffer[slave_buffer_pos] = TWDR;
142 BUFFER_POS_INC();
143 }
144 break;
145
146 case TW_ST_SLA_ACK:
147 case TW_ST_DATA_ACK:
148 // master has addressed this device as a slave transmitter and is
149 // requesting data.
150 TWDR = i2c_slave_buffer[slave_buffer_pos];
151 BUFFER_POS_INC();
152 break;
153
154 case TW_BUS_ERROR: // something went wrong, reset twi state
155 TWCR = 0;
156 default:
157 break;
158 }
159 // Reset everything, so we are ready for the next TWI interrupt
160 TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN);
161}
162#endif
diff --git a/keyboards/orthodox/i2c.h b/keyboards/orthodox/i2c.h
new file mode 100644
index 000000000..2af843ff6
--- /dev/null
+++ b/keyboards/orthodox/i2c.h
@@ -0,0 +1,50 @@
1#ifndef I2C_H
2#define I2C_H
3
4#include <stdint.h>
5#include "matrix.h"
6
7#ifndef F_CPU
8#define F_CPU 16000000UL
9#endif
10
11#define I2C_READ 1
12#define I2C_WRITE 0
13
14#define I2C_ACK 1
15#define I2C_NACK 0
16
17#define SLAVE_BUFFER_SIZE 0x10
18
19// i2c SCL clock frequency
20#define SCL_CLOCK 100000UL
21
22extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
23
24void i2c_master_init(void);
25uint8_t i2c_master_start(uint8_t address);
26void i2c_master_stop(void);
27uint8_t i2c_master_write(uint8_t data);
28uint8_t i2c_master_read(int);
29void i2c_reset_state(void);
30void i2c_slave_init(uint8_t address);
31
32
33static inline unsigned char i2c_start_read(unsigned char addr) {
34 return i2c_master_start((addr << 1) | I2C_READ);
35}
36
37static inline unsigned char i2c_start_write(unsigned char addr) {
38 return i2c_master_start((addr << 1) | I2C_WRITE);
39}
40
41// from SSD1306 scrips
42extern unsigned char i2c_rep_start(unsigned char addr);
43extern void i2c_start_wait(unsigned char addr);
44extern unsigned char i2c_readAck(void);
45extern unsigned char i2c_readNak(void);
46extern unsigned char i2c_read(unsigned char ack);
47
48#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
49
50#endif
diff --git a/keyboards/orthodox/keymaps/i2c/config.h b/keyboards/orthodox/keymaps/i2c/config.h
new file mode 100644
index 000000000..542529719
--- /dev/null
+++ b/keyboards/orthodox/keymaps/i2c/config.h
@@ -0,0 +1,34 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18
19#define USE_I2C
20
21//#define MASTER_LEFT
22//#define _MASTER_RIGHT
23#define EE_HANDS
24
25
26#ifdef SUBPROJECT_rev1
27 #include "../../rev1/config.h"
28#endif
29#ifdef SUBPROJECT_rev2
30 #include "../../rev2/config.h"
31#endif
32#ifdef SUBPROJECT_rev2fliphalf
33 #include "../../rev2fliphalf/config.h"
34#endif
diff --git a/keyboards/orthodox/keymaps/i2c/keymap.c b/keyboards/orthodox/keymaps/i2c/keymap.c
new file mode 100644
index 000000000..ed24a3a1f
--- /dev/null
+++ b/keyboards/orthodox/keymaps/i2c/keymap.c
@@ -0,0 +1,132 @@
1#include "orthodox.h"
2#include "action_layer.h"
3#include "eeconfig.h"
4
5extern keymap_config_t keymap_config;
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.
11#define _QWERTY 0
12#define _COLEMAK 1
13#define _DVORAK 2
14#define _LOWER 3
15#define _RAISE 4
16#define _ADJUST 16
17
18enum custom_keycodes {
19 QWERTY = SAFE_RANGE,
20 COLEMAK,
21 DVORAK,
22 LOWER,
23 RAISE,
24 ADJUST,
25};
26
27// Fillers to make layering more clear
28#define _______ KC_TRNS
29#define XXXXXXX KC_NO
30
31#define LS__SPC MT(MOD_LSFT, KC_SPC)
32
33const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
34
35[_QWERTY] = KEYMAP( \
36 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
37 KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_LEFT, XXXXXXX, KC_DOWN, KC_UP, XXXXXXX, KC_RIGHT,KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \
38 KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, LOWER, KC_BSPC, KC_ENT, KC_RALT, LS__SPC, RAISE, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LGUI \
39),
40
41[_LOWER] = KEYMAP( \
42 KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, \
43 KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_LCTL, XXXXXXX, _______, _______, XXXXXXX, KC_RCTL, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
44 _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, _______, _______, _______, KC_F12, KC_HOME, KC_COMM, KC_DOT, KC_END, _______ \
45),
46
47[_RAISE] = KEYMAP( \
48 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \
49 KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, XXXXXXX, _______, _______, XXXXXXX, _______, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
50 _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, _______, _______, _______, KC_F12, KC_PGUP, KC_COMM, KC_DOT, KC_PGDN, _______ \
51),
52
53[_ADJUST] = KEYMAP( \
54 _______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, \
55 _______, _______, _______, AU_ON, AU_OFF, AG_NORM, _______, XXXXXXX, _______, _______, XXXXXXX, _______, AG_SWAP, QWERTY , COLEMAK, DVORAK, _______, _______, \
56 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
57)
58
59
60};
61
62#ifdef AUDIO_ENABLE
63float tone_qwerty[][2] = SONG(QWERTY_SOUND);
64float tone_dvorak[][2] = SONG(DVORAK_SOUND);
65float tone_colemak[][2] = SONG(COLEMAK_SOUND);
66#endif
67
68void persistent_default_layer_set(uint16_t default_layer) {
69 eeconfig_update_default_layer(default_layer);
70 default_layer_set(default_layer);
71}
72
73bool process_record_user(uint16_t keycode, keyrecord_t *record) {
74 switch (keycode) {
75 case QWERTY:
76 if (record->event.pressed) {
77 #ifdef AUDIO_ENABLE
78 PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
79 #endif
80 persistent_default_layer_set(1UL<<_QWERTY);
81 }
82 return false;
83 break;
84 case COLEMAK:
85 if (record->event.pressed) {
86 #ifdef AUDIO_ENABLE
87 PLAY_NOTE_ARRAY(tone_colemak, false, 0);
88 #endif
89 persistent_default_layer_set(1UL<<_COLEMAK);
90 }
91 return false;
92 break;
93 case DVORAK:
94 if (record->event.pressed) {
95 #ifdef AUDIO_ENABLE
96 PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
97 #endif
98 persistent_default_layer_set(1UL<<_DVORAK);
99 }
100 return false;
101 break;
102 case LOWER:
103 if (record->event.pressed) {
104 layer_on(_LOWER);
105 update_tri_layer(_LOWER, _RAISE, _ADJUST);
106 } else {
107 layer_off(_LOWER);
108 update_tri_layer(_LOWER, _RAISE, _ADJUST);
109 }
110 return false;
111 break;
112 case RAISE:
113 if (record->event.pressed) {
114 layer_on(_RAISE);
115 update_tri_layer(_LOWER, _RAISE, _ADJUST);
116 } else {
117 layer_off(_RAISE);
118 update_tri_layer(_LOWER, _RAISE, _ADJUST);
119 }
120 return false;
121 break;
122 case ADJUST:
123 if (record->event.pressed) {
124 layer_on(_ADJUST);
125 } else {
126 layer_off(_ADJUST);
127 }
128 return false;
129 break;
130 }
131 return true;
132}
diff --git a/keyboards/orthodox/keymaps/serial/config.h b/keyboards/orthodox/keymaps/serial/config.h
new file mode 100644
index 000000000..5169452ba
--- /dev/null
+++ b/keyboards/orthodox/keymaps/serial/config.h
@@ -0,0 +1,34 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18
19#define USE_SERIAL
20
21//#define MASTER_LEFT
22//#define _MASTER_RIGHT
23#define EE_HANDS
24
25
26#ifdef SUBPROJECT_rev1
27 #include "../../rev1/config.h"
28#endif
29#ifdef SUBPROJECT_rev2
30 #include "../../rev2/config.h"
31#endif
32#ifdef SUBPROJECT_rev2fliphalf
33 #include "../../rev2fliphalf/config.h"
34#endif
diff --git a/keyboards/orthodox/keymaps/serial/keymap.c b/keyboards/orthodox/keymaps/serial/keymap.c
new file mode 100644
index 000000000..ed24a3a1f
--- /dev/null
+++ b/keyboards/orthodox/keymaps/serial/keymap.c
@@ -0,0 +1,132 @@
1#include "orthodox.h"
2#include "action_layer.h"
3#include "eeconfig.h"
4
5extern keymap_config_t keymap_config;
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.
11#define _QWERTY 0
12#define _COLEMAK 1
13#define _DVORAK 2
14#define _LOWER 3
15#define _RAISE 4
16#define _ADJUST 16
17
18enum custom_keycodes {
19 QWERTY = SAFE_RANGE,
20 COLEMAK,
21 DVORAK,
22 LOWER,
23 RAISE,
24 ADJUST,
25};
26
27// Fillers to make layering more clear
28#define _______ KC_TRNS
29#define XXXXXXX KC_NO
30
31#define LS__SPC MT(MOD_LSFT, KC_SPC)
32
33const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
34
35[_QWERTY] = KEYMAP( \
36 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC, \
37 KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_LEFT, XXXXXXX, KC_DOWN, KC_UP, XXXXXXX, KC_RIGHT,KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, \
38 KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, LOWER, KC_BSPC, KC_ENT, KC_RALT, LS__SPC, RAISE, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_LGUI \
39),
40
41[_LOWER] = KEYMAP( \
42 KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, \
43 KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_LCTL, XXXXXXX, _______, _______, XXXXXXX, KC_RCTL, KC_F6, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, \
44 _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, _______, _______, _______, KC_F12, KC_HOME, KC_COMM, KC_DOT, KC_END, _______ \
45),
46
47[_RAISE] = KEYMAP( \
48 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, \
49 KC_DEL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, _______, XXXXXXX, _______, _______, XXXXXXX, _______, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS, \
50 _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, _______, _______, _______, _______, _______, _______, KC_F12, KC_PGUP, KC_COMM, KC_DOT, KC_PGDN, _______ \
51),
52
53[_ADJUST] = KEYMAP( \
54 _______, RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL, \
55 _______, _______, _______, AU_ON, AU_OFF, AG_NORM, _______, XXXXXXX, _______, _______, XXXXXXX, _______, AG_SWAP, QWERTY , COLEMAK, DVORAK, _______, _______, \
56 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY \
57)
58
59
60};
61
62#ifdef AUDIO_ENABLE
63float tone_qwerty[][2] = SONG(QWERTY_SOUND);
64float tone_dvorak[][2] = SONG(DVORAK_SOUND);
65float tone_colemak[][2] = SONG(COLEMAK_SOUND);
66#endif
67
68void persistent_default_layer_set(uint16_t default_layer) {
69 eeconfig_update_default_layer(default_layer);
70 default_layer_set(default_layer);
71}
72
73bool process_record_user(uint16_t keycode, keyrecord_t *record) {
74 switch (keycode) {
75 case QWERTY:
76 if (record->event.pressed) {
77 #ifdef AUDIO_ENABLE
78 PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
79 #endif
80 persistent_default_layer_set(1UL<<_QWERTY);
81 }
82 return false;
83 break;
84 case COLEMAK:
85 if (record->event.pressed) {
86 #ifdef AUDIO_ENABLE
87 PLAY_NOTE_ARRAY(tone_colemak, false, 0);
88 #endif
89 persistent_default_layer_set(1UL<<_COLEMAK);
90 }
91 return false;
92 break;
93 case DVORAK:
94 if (record->event.pressed) {
95 #ifdef AUDIO_ENABLE
96 PLAY_NOTE_ARRAY(tone_dvorak, false, 0);
97 #endif
98 persistent_default_layer_set(1UL<<_DVORAK);
99 }
100 return false;
101 break;
102 case LOWER:
103 if (record->event.pressed) {
104 layer_on(_LOWER);
105 update_tri_layer(_LOWER, _RAISE, _ADJUST);
106 } else {
107 layer_off(_LOWER);
108 update_tri_layer(_LOWER, _RAISE, _ADJUST);
109 }
110 return false;
111 break;
112 case RAISE:
113 if (record->event.pressed) {
114 layer_on(_RAISE);
115 update_tri_layer(_LOWER, _RAISE, _ADJUST);
116 } else {
117 layer_off(_RAISE);
118 update_tri_layer(_LOWER, _RAISE, _ADJUST);
119 }
120 return false;
121 break;
122 case ADJUST:
123 if (record->event.pressed) {
124 layer_on(_ADJUST);
125 } else {
126 layer_off(_ADJUST);
127 }
128 return false;
129 break;
130 }
131 return true;
132}
diff --git a/keyboards/orthodox/matrix.c b/keyboards/orthodox/matrix.c
new file mode 100644
index 000000000..3b60cead8
--- /dev/null
+++ b/keyboards/orthodox/matrix.c
@@ -0,0 +1,351 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18/*
19 * scan matrix
20 */
21#include <stdint.h>
22#include <stdbool.h>
23#ifdef USE_I2C
24// provides memcpy for copying TWI slave buffer
25// #include <string.h>
26#endif
27#include <avr/io.h>
28#include <avr/wdt.h>
29#include <avr/interrupt.h>
30#include <util/delay.h>
31#include "print.h"
32#include "debug.h"
33#include "util.h"
34#include "matrix.h"
35#include "split_util.h"
36#include "pro_micro.h"
37#include "config.h"
38
39#ifdef USE_I2C
40# include "i2c.h"
41#else // USE_SERIAL
42# include "serial.h"
43#endif
44
45#ifndef DEBOUNCE
46# define DEBOUNCE 5
47#endif
48
49#define ERROR_DISCONNECT_COUNT 5
50
51static uint8_t debouncing = DEBOUNCE;
52static const int ROWS_PER_HAND = MATRIX_ROWS/2;
53static uint8_t error_count = 0;
54
55static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
56static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
57
58/* matrix state(1:on, 0:off) */
59static matrix_row_t matrix[MATRIX_ROWS];
60static matrix_row_t matrix_debouncing[MATRIX_ROWS];
61
62static matrix_row_t read_cols(void);
63static void init_cols(void);
64static void unselect_rows(void);
65static void select_row(uint8_t row);
66
67__attribute__ ((weak))
68void matrix_init_quantum(void) {
69 matrix_init_kb();
70}
71
72__attribute__ ((weak))
73void matrix_scan_quantum(void) {
74 matrix_scan_kb();
75}
76
77__attribute__ ((weak))
78void matrix_init_kb(void) {
79 matrix_init_user();
80}
81
82__attribute__ ((weak))
83void matrix_scan_kb(void) {
84 matrix_scan_user();
85}
86
87__attribute__ ((weak))
88void matrix_init_user(void) {
89}
90
91__attribute__ ((weak))
92void matrix_scan_user(void) {
93}
94
95inline
96uint8_t matrix_rows(void)
97{
98 return MATRIX_ROWS;
99}
100
101inline
102uint8_t matrix_cols(void)
103{
104 return MATRIX_COLS;
105}
106
107void matrix_init(void)
108{
109 debug_enable = true;
110 debug_matrix = true;
111 debug_mouse = true;
112 // initialize row and col
113 unselect_rows();
114 init_cols();
115
116 TX_RX_LED_INIT;
117
118 // initialize matrix state: all keys off
119 for (uint8_t i=0; i < MATRIX_ROWS; i++) {
120 matrix[i] = 0;
121 matrix_debouncing[i] = 0;
122 }
123
124 matrix_init_quantum();
125}
126
127uint8_t _matrix_scan(void)
128{
129 // Right hand is stored after the left in the matrix so, we need to offset it
130 int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
131
132 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
133 select_row(i);
134 _delay_us(30); // without this wait read unstable value.
135 matrix_row_t cols = read_cols();
136 if (matrix_debouncing[i+offset] != cols) {
137 matrix_debouncing[i+offset] = cols;
138 debouncing = DEBOUNCE;
139 }
140 unselect_rows();
141 }
142
143 if (debouncing) {
144 if (--debouncing) {
145 _delay_ms(1);
146 } else {
147 for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
148 matrix[i+offset] = matrix_debouncing[i+offset];
149 }
150 }
151 }
152
153 return 1;
154}
155
156#ifdef USE_I2C
157
158// Get rows from other half over i2c
159int i2c_transaction(void) {
160 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
161
162 int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
163 if (err) goto i2c_error;
164
165 // start of matrix stored at 0x00
166 err = i2c_master_write(0x00);
167 if (err) goto i2c_error;
168
169 // Start read
170 err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
171 if (err) goto i2c_error;
172
173 if (!err) {
174 /*
175 // read from TWI byte-by-byte into matrix_row_t memory space
176 size_t i;
177 for (i = 0; i < SLAVE_BUFFER_SIZE-1; ++i) {
178 *((uint8_t*)&matrix[slaveOffset]+i) = i2c_master_read(I2C_ACK);
179 }
180 // last byte to be read / end of chunk
181 *((uint8_t*)&matrix[slaveOffset]+i) = i2c_master_read(I2C_NACK);
182 */
183
184 // kludge for column #9: unpack bits for keys (2,9) and (3,9) from (1,7) and (1,8)
185 // i2c_master_read(I2C_ACK);
186 matrix[slaveOffset+0] = i2c_master_read(I2C_ACK);
187 // i2c_master_read(I2C_ACK);
188 matrix[slaveOffset+1] = (matrix_row_t)i2c_master_read(I2C_ACK)\
189 | (matrix[slaveOffset+0]&0x40U)<<2;
190 // i2c_master_read(I2C_ACK);
191 matrix[slaveOffset+2] = (matrix_row_t)i2c_master_read(I2C_NACK)\
192 | (matrix[slaveOffset+0]&0x80U)<<1;
193 // clear highest two bits on row 1, where the col9 bits were transported
194 matrix[slaveOffset+0] &= 0x3F;
195
196 i2c_master_stop();
197 } else {
198i2c_error: // the cable is disconnected, or something else went wrong
199 i2c_reset_state();
200 return err;
201 }
202
203 return 0;
204}
205
206#else // USE_SERIAL
207
208int serial_transaction(void) {
209 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
210
211 if (serial_update_buffers()) {
212 return 1;
213 }
214
215 for (int i = 0; i < ROWS_PER_HAND; ++i) {
216 matrix[slaveOffset+i] = serial_slave_buffer[i];
217 }
218 return 0;
219}
220#endif
221
222uint8_t matrix_scan(void)
223{
224 int ret = _matrix_scan();
225
226
227
228#ifdef USE_I2C
229 if( i2c_transaction() ) {
230#else // USE_SERIAL
231 if( serial_transaction() ) {
232#endif
233 // turn on the indicator led when halves are disconnected
234 TXLED1;
235
236 error_count++;
237
238 if (error_count > ERROR_DISCONNECT_COUNT) {
239 // reset other half if disconnected
240 int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
241 for (int i = 0; i < ROWS_PER_HAND; ++i) {
242 matrix[slaveOffset+i] = 0;
243 }
244 }
245 } else {
246 // turn off the indicator led on no error
247 TXLED0;
248 error_count = 0;
249 }
250 matrix_scan_quantum();
251 return ret;
252}
253
254void matrix_slave_scan(void) {
255 _matrix_scan();
256
257 int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
258
259#ifdef USE_I2C
260 // SLAVE_BUFFER_SIZE is from i2c.h
261 // (MATRIX_ROWS/2*sizeof(matrix_row_t))
262 // memcpy((void*)i2c_slave_buffer, (const void*)&matrix[offset], (ROWS_PER_HAND*sizeof(matrix_row_t)));
263
264 // kludge for column #9: put bits for keys (2,9) and (3,9) into (1,7) and (1,8)
265 i2c_slave_buffer[0] = (uint8_t)(matrix[offset+0])\
266 | (matrix[offset+1]&0x100U)>>2\
267 | (matrix[offset+2]&0x100U)>>1;
268 i2c_slave_buffer[1] = (uint8_t)(matrix[offset+1]);
269 i2c_slave_buffer[2] = (uint8_t)(matrix[offset+2]);
270 // note: looks like a possible operator-precedence bug here, in last version?
271 /*
272 i2c_slave_buffer[1] = (uint8_t)matrix[offset+0];
273 i2c_slave_buffer[2] = (uint8_t)(matrix[offset+1]>>8);
274 i2c_slave_buffer[3] = (uint8_t)(matrix[offset+1]>>8);
275 i2c_slave_buffer[4] = (uint8_t)(matrix[offset+2]>>8);
276 i2c_slave_buffer[5] = (uint8_t)matrix[offset+2];
277 */
278#else // USE_SERIAL
279 for (int i = 0; i < ROWS_PER_HAND; ++i) {
280 serial_slave_buffer[i] = matrix[offset+i];
281 }
282#endif
283}
284
285bool matrix_is_modified(void)
286{
287 if (debouncing) return false;
288 return true;
289}
290
291inline
292bool matrix_is_on(uint8_t row, uint8_t col)
293{
294 return (matrix[row] & ((matrix_row_t)1<<col));
295}
296
297inline
298matrix_row_t matrix_get_row(uint8_t row)
299{
300 return matrix[row];
301}
302
303void matrix_print(void)
304{
305 print("\nr/c 0123456789ABCDEF\n");
306 for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
307 phex(row); print(": ");
308 pbin_reverse16(matrix_get_row(row));
309 print("\n");
310 }
311}
312
313uint8_t matrix_key_count(void)
314{
315 uint8_t count = 0;
316 for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
317 count += bitpop16(matrix[i]);
318 }
319 return count;
320}
321
322static void init_cols(void)
323{
324 for(int x = 0; x < MATRIX_COLS; x++) {
325 _SFR_IO8((col_pins[x] >> 4) + 1) &= ~_BV(col_pins[x] & 0xF);
326 _SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF);
327 }
328}
329
330static matrix_row_t read_cols(void)
331{
332 matrix_row_t result = 0;
333 for(int x = 0; x < MATRIX_COLS; x++) {
334 result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x);
335 }
336 return result;
337}
338
339static void unselect_rows(void)
340{
341 for(int x = 0; x < ROWS_PER_HAND; x++) {
342 _SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF);
343 _SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF);
344 }
345}
346
347static void select_row(uint8_t row)
348{
349 _SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF);
350 _SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF);
351}
diff --git a/keyboards/orthodox/orthodox.c b/keyboards/orthodox/orthodox.c
new file mode 100644
index 000000000..0b366e944
--- /dev/null
+++ b/keyboards/orthodox/orthodox.c
@@ -0,0 +1 @@
#include "orthodox.h" \ No newline at end of file
diff --git a/keyboards/orthodox/orthodox.h b/keyboards/orthodox/orthodox.h
new file mode 100644
index 000000000..bb7efb6ad
--- /dev/null
+++ b/keyboards/orthodox/orthodox.h
@@ -0,0 +1,30 @@
1#ifndef ORTHODOX_H
2#define ORTHODOX_H
3
4#ifdef SUBPROJECT_rev1
5 #include "rev1.h"
6#endif
7#ifdef SUBPROJECT_rev2
8 #include "rev2.h"
9#endif
10#ifdef SUBPROJECT_rev2fliphalf
11 #include "rev2fliphalf.h"
12#endif
13
14// Used to create a keymap using only KC_ prefixed keys
15#define KC_KEYMAP( \
16 L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
17 L10, L11, L12, L13, L14, L15, R10, R11, R12, R13, R14, R15, \
18 L20, L21, L22, L23, L24, L25, R20, R21, R22, R23, R24, R25, \
19 L30, L31, L32, L33, L34, L35, R30, R31, R32, R33, R34, R35 \
20 ) \
21 KEYMAP( \
22 KC_##L00, KC_##L01, KC_##L02, KC_##L03, KC_##L04, KC_##L05, KC_##R00, KC_##R01, KC_##R02, KC_##R03, KC_##R04, KC_##R05, \
23 KC_##L10, KC_##L11, KC_##L12, KC_##L13, KC_##L14, KC_##L15, KC_##R10, KC_##R11, KC_##R12, KC_##R13, KC_##R14, KC_##R15, \
24 KC_##L20, KC_##L21, KC_##L22, KC_##L23, KC_##L24, KC_##L25, KC_##R20, KC_##R21, KC_##R22, KC_##R23, KC_##R24, KC_##R25, \
25 KC_##L30, KC_##L31, KC_##L32, KC_##L33, KC_##L34, KC_##L35, KC_##R30, KC_##R31, KC_##R32, KC_##R33, KC_##R34, KC_##R35 \
26 )
27
28#include "quantum.h"
29
30#endif \ No newline at end of file
diff --git a/keyboards/orthodox/pro_micro.h b/keyboards/orthodox/pro_micro.h
new file mode 100644
index 000000000..f9e7ed75d
--- /dev/null
+++ b/keyboards/orthodox/pro_micro.h
@@ -0,0 +1,362 @@
1/*
2 pins_arduino.h - Pin definition functions for Arduino
3 Part of Arduino - http://www.arduino.cc/
4
5 Copyright (c) 2007 David A. Mellis
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General
18 Public License along with this library; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 Boston, MA 02111-1307 USA
21
22 $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
23*/
24
25#ifndef Pins_Arduino_h
26#define Pins_Arduino_h
27
28#include <avr/pgmspace.h>
29
30// Workaround for wrong definitions in "iom32u4.h".
31// This should be fixed in the AVR toolchain.
32#undef UHCON
33#undef UHINT
34#undef UHIEN
35#undef UHADDR
36#undef UHFNUM
37#undef UHFNUML
38#undef UHFNUMH
39#undef UHFLEN
40#undef UPINRQX
41#undef UPINTX
42#undef UPNUM
43#undef UPRST
44#undef UPCONX
45#undef UPCFG0X
46#undef UPCFG1X
47#undef UPSTAX
48#undef UPCFG2X
49#undef UPIENX
50#undef UPDATX
51#undef TCCR2A
52#undef WGM20
53#undef WGM21
54#undef COM2B0
55#undef COM2B1
56#undef COM2A0
57#undef COM2A1
58#undef TCCR2B
59#undef CS20
60#undef CS21
61#undef CS22
62#undef WGM22
63#undef FOC2B
64#undef FOC2A
65#undef TCNT2
66#undef TCNT2_0
67#undef TCNT2_1
68#undef TCNT2_2
69#undef TCNT2_3
70#undef TCNT2_4
71#undef TCNT2_5
72#undef TCNT2_6
73#undef TCNT2_7
74#undef OCR2A
75#undef OCR2_0
76#undef OCR2_1
77#undef OCR2_2
78#undef OCR2_3
79#undef OCR2_4
80#undef OCR2_5
81#undef OCR2_6
82#undef OCR2_7
83#undef OCR2B
84#undef OCR2_0
85#undef OCR2_1
86#undef OCR2_2
87#undef OCR2_3
88#undef OCR2_4
89#undef OCR2_5
90#undef OCR2_6
91#undef OCR2_7
92
93#define NUM_DIGITAL_PINS 30
94#define NUM_ANALOG_INPUTS 12
95
96#define TX_RX_LED_INIT DDRD |= (1<<5), DDRB |= (1<<0)
97#define TXLED0 PORTD |= (1<<5)
98#define TXLED1 PORTD &= ~(1<<5)
99#define RXLED0 PORTB |= (1<<0)
100#define RXLED1 PORTB &= ~(1<<0)
101
102static const uint8_t SDA = 2;
103static const uint8_t SCL = 3;
104#define LED_BUILTIN 13
105
106// Map SPI port to 'new' pins D14..D17
107static const uint8_t SS = 17;
108static const uint8_t MOSI = 16;
109static const uint8_t MISO = 14;
110static const uint8_t SCK = 15;
111
112// Mapping of analog pins as digital I/O
113// A6-A11 share with digital pins
114static const uint8_t ADC0 = 18;
115static const uint8_t ADC1 = 19;
116static const uint8_t ADC2 = 20;
117static const uint8_t ADC3 = 21;
118static const uint8_t ADC4 = 22;
119static const uint8_t ADC5 = 23;
120static const uint8_t ADC6 = 24; // D4
121static const uint8_t ADC7 = 25; // D6
122static const uint8_t ADC8 = 26; // D8
123static const uint8_t ADC9 = 27; // D9
124static const uint8_t ADC10 = 28; // D10
125static const uint8_t ADC11 = 29; // D12
126
127#define digitalPinToPCICR(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCICR) : ((uint8_t *)0))
128#define digitalPinToPCICRbit(p) 0
129#define digitalPinToPCMSK(p) ((((p) >= 8 && (p) <= 11) || ((p) >= 14 && (p) <= 17) || ((p) >= A8 && (p) <= A10)) ? (&PCMSK0) : ((uint8_t *)0))
130#define digitalPinToPCMSKbit(p) ( ((p) >= 8 && (p) <= 11) ? (p) - 4 : ((p) == 14 ? 3 : ((p) == 15 ? 1 : ((p) == 16 ? 2 : ((p) == 17 ? 0 : (p - A8 + 4))))))
131
132// __AVR_ATmega32U4__ has an unusual mapping of pins to channels
133extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
134#define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
135
136#define digitalPinToInterrupt(p) ((p) == 0 ? 2 : ((p) == 1 ? 3 : ((p) == 2 ? 1 : ((p) == 3 ? 0 : ((p) == 7 ? 4 : NOT_AN_INTERRUPT)))))
137
138#ifdef ARDUINO_MAIN
139
140// On the Arduino board, digital pins are also used
141// for the analog output (software PWM). Analog input
142// pins are a separate set.
143
144// ATMEL ATMEGA32U4 / ARDUINO LEONARDO
145//
146// D0 PD2 RXD1/INT2
147// D1 PD3 TXD1/INT3
148// D2 PD1 SDA SDA/INT1
149// D3# PD0 PWM8/SCL OC0B/SCL/INT0
150// D4 A6 PD4 ADC8
151// D5# PC6 ??? OC3A/#OC4A
152// D6# A7 PD7 FastPWM #OC4D/ADC10
153// D7 PE6 INT6/AIN0
154//
155// D8 A8 PB4 ADC11/PCINT4
156// D9# A9 PB5 PWM16 OC1A/#OC4B/ADC12/PCINT5
157// D10# A10 PB6 PWM16 OC1B/0c4B/ADC13/PCINT6
158// D11# PB7 PWM8/16 0C0A/OC1C/#RTS/PCINT7
159// D12 A11 PD6 T1/#OC4D/ADC9
160// D13# PC7 PWM10 CLK0/OC4A
161//
162// A0 D18 PF7 ADC7
163// A1 D19 PF6 ADC6
164// A2 D20 PF5 ADC5
165// A3 D21 PF4 ADC4
166// A4 D22 PF1 ADC1
167// A5 D23 PF0 ADC0
168//
169// New pins D14..D17 to map SPI port to digital pins
170//
171// MISO D14 PB3 MISO,PCINT3
172// SCK D15 PB1 SCK,PCINT1
173// MOSI D16 PB2 MOSI,PCINT2
174// SS D17 PB0 RXLED,SS/PCINT0
175//
176// Connected LEDs on board for TX and RX
177// TXLED D24 PD5 XCK1
178// RXLED D17 PB0
179// HWB PE2 HWB
180
181// these arrays map port names (e.g. port B) to the
182// appropriate addresses for various functions (e.g. reading
183// and writing)
184const uint16_t PROGMEM port_to_mode_PGM[] = {
185 NOT_A_PORT,
186 NOT_A_PORT,
187 (uint16_t) &DDRB,
188 (uint16_t) &DDRC,
189 (uint16_t) &DDRD,
190 (uint16_t) &DDRE,
191 (uint16_t) &DDRF,
192};
193
194const uint16_t PROGMEM port_to_output_PGM[] = {
195 NOT_A_PORT,
196 NOT_A_PORT,
197 (uint16_t) &PORTB,
198 (uint16_t) &PORTC,
199 (uint16_t) &PORTD,
200 (uint16_t) &PORTE,
201 (uint16_t) &PORTF,
202};
203
204const uint16_t PROGMEM port_to_input_PGM[] = {
205 NOT_A_PORT,
206 NOT_A_PORT,
207 (uint16_t) &PINB,
208 (uint16_t) &PINC,
209 (uint16_t) &PIND,
210 (uint16_t) &PINE,
211 (uint16_t) &PINF,
212};
213
214const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
215 PD, // D0 - PD2
216 PD, // D1 - PD3
217 PD, // D2 - PD1
218 PD, // D3 - PD0
219 PD, // D4 - PD4
220 PC, // D5 - PC6
221 PD, // D6 - PD7
222 PE, // D7 - PE6
223
224 PB, // D8 - PB4
225 PB, // D9 - PB5
226 PB, // D10 - PB6
227 PB, // D11 - PB7
228 PD, // D12 - PD6
229 PC, // D13 - PC7
230
231 PB, // D14 - MISO - PB3
232 PB, // D15 - SCK - PB1
233 PB, // D16 - MOSI - PB2
234 PB, // D17 - SS - PB0
235
236 PF, // D18 - A0 - PF7
237 PF, // D19 - A1 - PF6
238 PF, // D20 - A2 - PF5
239 PF, // D21 - A3 - PF4
240 PF, // D22 - A4 - PF1
241 PF, // D23 - A5 - PF0
242
243 PD, // D24 - PD5
244 PD, // D25 / D6 - A7 - PD7
245 PB, // D26 / D8 - A8 - PB4
246 PB, // D27 / D9 - A9 - PB5
247 PB, // D28 / D10 - A10 - PB6
248 PD, // D29 / D12 - A11 - PD6
249};
250
251const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
252 _BV(2), // D0 - PD2
253 _BV(3), // D1 - PD3
254 _BV(1), // D2 - PD1
255 _BV(0), // D3 - PD0
256 _BV(4), // D4 - PD4
257 _BV(6), // D5 - PC6
258 _BV(7), // D6 - PD7
259 _BV(6), // D7 - PE6
260
261 _BV(4), // D8 - PB4
262 _BV(5), // D9 - PB5
263 _BV(6), // D10 - PB6
264 _BV(7), // D11 - PB7
265 _BV(6), // D12 - PD6
266 _BV(7), // D13 - PC7
267
268 _BV(3), // D14 - MISO - PB3
269 _BV(1), // D15 - SCK - PB1
270 _BV(2), // D16 - MOSI - PB2
271 _BV(0), // D17 - SS - PB0
272
273 _BV(7), // D18 - A0 - PF7
274 _BV(6), // D19 - A1 - PF6
275 _BV(5), // D20 - A2 - PF5
276 _BV(4), // D21 - A3 - PF4
277 _BV(1), // D22 - A4 - PF1
278 _BV(0), // D23 - A5 - PF0
279
280 _BV(5), // D24 - PD5
281 _BV(7), // D25 / D6 - A7 - PD7
282 _BV(4), // D26 / D8 - A8 - PB4
283 _BV(5), // D27 / D9 - A9 - PB5
284 _BV(6), // D28 / D10 - A10 - PB6
285 _BV(6), // D29 / D12 - A11 - PD6
286};
287
288const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
289 NOT_ON_TIMER,
290 NOT_ON_TIMER,
291 NOT_ON_TIMER,
292 TIMER0B, /* 3 */
293 NOT_ON_TIMER,
294 TIMER3A, /* 5 */
295 TIMER4D, /* 6 */
296 NOT_ON_TIMER,
297
298 NOT_ON_TIMER,
299 TIMER1A, /* 9 */
300 TIMER1B, /* 10 */
301 TIMER0A, /* 11 */
302
303 NOT_ON_TIMER,
304 TIMER4A, /* 13 */
305
306 NOT_ON_TIMER,
307 NOT_ON_TIMER,
308 NOT_ON_TIMER,
309 NOT_ON_TIMER,
310 NOT_ON_TIMER,
311 NOT_ON_TIMER,
312
313 NOT_ON_TIMER,
314 NOT_ON_TIMER,
315 NOT_ON_TIMER,
316 NOT_ON_TIMER,
317 NOT_ON_TIMER,
318 NOT_ON_TIMER,
319 NOT_ON_TIMER,
320 NOT_ON_TIMER,
321 NOT_ON_TIMER,
322 NOT_ON_TIMER,
323};
324
325const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
326 7, // A0 PF7 ADC7
327 6, // A1 PF6 ADC6
328 5, // A2 PF5 ADC5
329 4, // A3 PF4 ADC4
330 1, // A4 PF1 ADC1
331 0, // A5 PF0 ADC0
332 8, // A6 D4 PD4 ADC8
333 10, // A7 D6 PD7 ADC10
334 11, // A8 D8 PB4 ADC11
335 12, // A9 D9 PB5 ADC12
336 13, // A10 D10 PB6 ADC13
337 9 // A11 D12 PD6 ADC9
338};
339
340#endif /* ARDUINO_MAIN */
341
342// These serial port names are intended to allow libraries and architecture-neutral
343// sketches to automatically default to the correct port name for a particular type
344// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
345// the first hardware serial port whose RX/TX pins are not dedicated to another use.
346//
347// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
348//
349// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
350//
351// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
352//
353// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
354//
355// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
356// pins are NOT connected to anything by default.
357#define SERIAL_PORT_MONITOR Serial
358#define SERIAL_PORT_USBVIRTUAL Serial
359#define SERIAL_PORT_HARDWARE Serial1
360#define SERIAL_PORT_HARDWARE_OPEN Serial1
361
362#endif /* Pins_Arduino_h */
diff --git a/keyboards/orthodox/readme.md b/keyboards/orthodox/readme.md
new file mode 100644
index 000000000..94bb8ebb9
--- /dev/null
+++ b/keyboards/orthodox/readme.md
@@ -0,0 +1,165 @@
1Orthodox
2========
3
4*Please note this guide is a work in progress and is based directly on the Let's Split guide.*
5
6Orthodox is a split ortholinear keyboard with thumb-clusters designed in 2017 by /u/Deductivemonkee, expected to be available in group buys.
7Each half has 18 keys in a 3x6 grid and a five key thumb-cluster, of which three use 1.25-unit keycaps.
8
9![Example prototype build by /u/Deductivemonkee](http://i.imgur.com/R4PPKdog.jpg)
10
11Its firmware is based on the Let's Split's.
12Each side is controlled by an Arduino Pro Micro (or compatible), and they're connected by a TRRS cable using the serial protocol.
13Support for the protocol using TWI (i2c®) is a work-in-progress.
14
15
16## Revisions
17
18- `Rev.1` Prototype GB version, supporting only Pro Micro in the corner footprint, and using PCB top- and bottom-plates.
19
20Note that the second number after the `Rev.` text is the pcb *order number.* The prototypes will say 1, and the next order of any revision will say 2 and so on.
21
22## Keymaps
23
24[The default layout can be unofficially referred to here.](http://www.keyboard-layout-editor.com/#/gists/f120e2703a22a6a69c7be9a65a9d1342)
25
26The thumb-clusters are an extension of row 2 and row 3 along columns 7, 8, and 9.
27Row 2 does not have a physical key in column 8, so when editing keymaps a placeholder constant (`XXXXXXX` or `KC_NO`) must be used in the row2-col8 position.
28
29## Build Guide
30
31[Official build guide by /u/Deductivemonkee](http://imgur.com/a/9c0NP)
32
33For further reading on build- and flashing-procedures for split ortholinear skeleton-case keyboards, please refer to [An Overly Verbose Guide to Building a Let's Split Keyboard](https://github.com/nicinabox/lets-split-guide), much of which can be applied to the Orthodox.
34
35## First Time Setup
36
37Download or clone the whole firmware and navigate to the keyboards/orthodox directory. Once your dev env is setup, you'll be able to generate the default .hex using:
38
39```
40$ make rev1
41```
42
43You will see a lot of output and if everything worked correctly you will see the built hex files in your *root qmk_firmware directory* two levels up:
44
45```
46orthodox_rev1_serial.hex
47```
48
49If you would like to use one of the alternative keymaps, or create your own, copy one of the existing [keymaps](keymaps/) and run make like so:
50
51
52```
53$ make rev1-YOUR_KEYMAP_NAME
54```
55
56If everything worked correctly you will see a file:
57
58```
59orthodox_rev1_YOUR_KEYMAP_NAME.hex
60```
61
62For more information on customizing keymaps, take a look at the primary documentation for [Customizing Your Keymap](/readme.md##customizing-your-keymap) in the main readme.md.
63
64
65Features
66--------
67
68For the full Quantum Mechanical Keyboard feature list, see [the parent readme.md](/readme.md).
69
70Some features supported by the firmware:
71
72* Either half can connect to the computer via USB, or both halves can be used
73 independently.
74* You only need 3 wires to connect the two halves. Two for VCC and GND and one
75 for serial communication.
76
77
78Required Hardware
79-----------------
80
81Apart from diodes and key switches for the keyboard matrix in each half, you
82will need:
83
84* 2 Arduino Pro Micro's. You can find theses on aliexpress for ≈3.50USD each.
85* 2 TRRS sockets and 1 TRRS cable
86
87
88Notes on Software Configuration
89-------------------------------
90
91Configuring the firmware is similar to any other QMK project. One thing
92to note is that `MATRIX_ROWS` in `config.h` is the total number of rows between
93the two halves, i.e. if your split keyboard has 3 rows in each half, then
94`MATRIX_ROWS=6`.
95
96
97Flashing
98-------
99From the keymap directory run `make SUBPROJECT-KEYMAP-avrdude` for automatic serial port resolution and flashing.
100Example: `make rev2-serial-avrdude`
101
102
103Choosing which board to plug the USB cable into (choosing Master)
104--------
105Because the two boards are identical, the firmware has logic to differentiate the left and right board.
106
107It uses two strategies to figure things out: look at the EEPROM (memory on the chip) or looks if the current board has the usb cable.
108
109The EEPROM approach requires additional setup (flashing the eeeprom) but allows you to swap the usb cable to either side.
110
111The USB cable approach is easier to setup and if you just want the usb cable on the left board, you do not need to do anything extra.
112
113### Setting the left hand as master
114If you always plug the usb cable into the left board, nothing extra is needed as this is the default. Comment out `EE_HANDS` and comment out `I2C_MASTER_RIGHT` or `MASTER_RIGHT` if for some reason it was set.
115
116### Setting the right hand as master
117If you always plug the usb cable into the right board, add an extra flag to your `config.h`
118```
119 #define MASTER_RIGHT
120```
121
122### Setting EE_hands to use either hands as master
123If you define `EE_HANDS` in your `config.h`, you will need to set the
124EEPROM for the left and right halves.
125
126The EEPROM is used to store whether the
127half is left handed or right handed. This makes it so that the same firmware
128file will run on both hands instead of having to flash left and right handed
129versions of the firmware to each half. To flash the EEPROM file for the left
130half run:
131```
132avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-lefthand.eep
133// or the equivalent in dfu-programmer
134
135```
136and similarly for right half
137```
138avrdude -p atmega32u4 -P $(COM_PORT) -c avr109 -U eeprom:w:eeprom-righhand.eep
139// or the equivalent in dfu-programmer
140```
141
142NOTE: replace `$(COM_PORT)` with the port of your device (e.g. `/dev/ttyACM0`)
143
144After you have flashed the EEPROM, you then need to set `EE_HANDS` in your config.h, rebuild the hex files and reflash.
145
146Note that you need to program both halves, but you have the option of using
147different keymaps for each half. You could program the left half with a QWERTY
148layout and the right half with a Colemak layout using bootmagic's default layout option.
149Then if you connect the left half to a computer by USB the keyboard will use QWERTY and Colemak when the
150right half is connected.
151
152
153Notes on Using Pro Micro 3.3V
154-----------------------------
155
156Do update the `F_CPU` parameter in `rules.mk` to `8000000` which reflects
157the frequency on the 3.3V board.
158
159Also, if the slave board is producing weird characters in certain columns,
160update the following line in `matrix.c` to the following:
161
162```
163// _delay_us(30); // without this wait read unstable value.
164_delay_us(300); // without this wait read unstable value.
165```
diff --git a/keyboards/orthodox/rev1/Makefile b/keyboards/orthodox/rev1/Makefile
new file mode 100644
index 000000000..4e2a6f00f
--- /dev/null
+++ b/keyboards/orthodox/rev1/Makefile
@@ -0,0 +1,3 @@
1ifndef MAKEFILE_INCLUDED
2 include ../../Makefile
3endif \ No newline at end of file
diff --git a/keyboards/orthodox/rev1/config.h b/keyboards/orthodox/rev1/config.h
new file mode 100644
index 000000000..46bb99440
--- /dev/null
+++ b/keyboards/orthodox/rev1/config.h
@@ -0,0 +1,99 @@
1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef CONFIG_H
19#define CONFIG_H
20
21#include "config_common.h"
22
23/* USB Device descriptor parameter */
24#define VENDOR_ID 0xFEED
25#define PRODUCT_ID 0x3060
26#define DEVICE_VER 0x0001
27#define MANUFACTURER deductivemonkee
28#define PRODUCT Monkeebs Orthodox Rev.1
29#define DESCRIPTION Oreodox
30
31/* key matrix size */
32// Rows are doubled-up
33#define MATRIX_ROWS 6
34#define MATRIX_COLS 9
35
36// wiring of each half
37
38
39//PRO MICRO
40#define MATRIX_ROW_PINS { D4, B4, B5 }
41#define MATRIX_COL_PINS { D7, F4, F5, F6, F7, B1, B3, B2, B6 }
42//#define MATRIX_COL_PINS { B2, B3, B1, F7, F6, F5, F4, D7 }
43
44/*/
45//TEENSY
46#define MATRIX_ROW_PINS { D0, C6, C7, }
47#define MATRIX_COL_PINS { D2, F5, F6, F7, B6, B5, B4, D7, D6 }
48/*/
49
50#define CATERINA_BOOTLOADER
51
52/* COL2ROW or ROW2COL */
53#define DIODE_DIRECTION COL2ROW
54
55/* define if matrix has ghost */
56//#define MATRIX_HAS_GHOST
57
58/* number of backlight levels */
59// #define BACKLIGHT_LEVELS 3
60
61/* Set 0 if debouncing isn't needed */
62#define DEBOUNCING_DELAY 5
63
64/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
65// #define LOCKING_SUPPORT_ENABLE
66/* Locking resynchronize hack */
67// #define LOCKING_RESYNC_ENABLE
68
69/* key combination for command */
70#define IS_COMMAND() ( \
71 keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
72)
73
74/* ws2812 RGB LED */
75//#define RGB_DI_PIN D3
76//#define RGBLIGHT_TIMER
77//#define RGBLED_NUM 16 // Number of LEDs
78//#define ws2812_PORTREG PORTD
79//#define ws2812_DDRREG DDRD
80
81/*
82 * Feature disable options
83 * These options are also useful to firmware size reduction.
84 */
85
86/* disable debug print */
87// #define NO_DEBUG
88
89/* disable print */
90// #define NO_PRINT
91
92/* disable action features */
93//#define NO_ACTION_LAYER
94//#define NO_ACTION_TAPPING
95//#define NO_ACTION_ONESHOT
96//#define NO_ACTION_MACRO
97//#define NO_ACTION_FUNCTION
98
99#endif
diff --git a/keyboards/orthodox/rev1/rev1.c b/keyboards/orthodox/rev1/rev1.c
new file mode 100644
index 000000000..10ece03f0
--- /dev/null
+++ b/keyboards/orthodox/rev1/rev1.c
@@ -0,0 +1,32 @@
1#include "orthodox.h"
2
3#ifdef AUDIO_ENABLE
4 float tone_startup[][2] = SONG(STARTUP_SOUND);
5 float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
6#endif
7
8void matrix_init_kb(void) {
9
10 #ifdef AUDIO_ENABLE
11 _delay_ms(20); // gets rid of tick
12 PLAY_NOTE_ARRAY(tone_startup, false, 0);
13 #endif
14
15 // // green led on
16 // DDRD |= (1<<5);
17 // PORTD &= ~(1<<5);
18
19 // // orange led on
20 // DDRB |= (1<<0);
21 // PORTB &= ~(1<<0);
22
23 matrix_init_user();
24};
25
26void shutdown_user(void) {
27 #ifdef AUDIO_ENABLE
28 PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
29 _delay_ms(150);
30 stop_all_notes();
31 #endif
32}
diff --git a/keyboards/orthodox/rev1/rev1.h b/keyboards/orthodox/rev1/rev1.h
new file mode 100644
index 000000000..4f163299d
--- /dev/null
+++ b/keyboards/orthodox/rev1/rev1.h
@@ -0,0 +1,25 @@
1#ifndef REV1_H
2#define REV1_H
3
4#include "../orthodox.h"
5
6//void promicro_bootloader_jmp(bool program);
7#include "quantum.h"
8
9//void promicro_bootloader_jmp(bool program);
10
11#define KEYMAP( \
12 L00, L01, L02, L03, L04, L05, R00, R01, R02, R03, R04, R05, \
13 L10, L11, L12, L13, L14, L15, L16, L17, L18, R10, R11, R12, R13, R14, R15, R16, R17, R18, \
14 L20, L21, L22, L23, L24, L25, L26, L27, L28, R20, R21, R22, R23, R24, R25, R26, R27, R28 \
15 ) \
16 { \
17 { L00, L01, L02, L03, L04, L05 }, \
18 { L10, L11, L12, L13, L14, L15, L16, L17, L18}, \
19 { L20, L21, L22, L23, L24, L25, L26, L27, L28 }, \
20 { R05, R04, R03, R02, R01, R00 }, \
21 { R18, R17, R16, R15, R14, R13, R12, R11, R10 }, \
22 { R28, R27, R26, R25, R24, R23, R22, R21, R20 } \
23 }
24
25#endif \ No newline at end of file
diff --git a/keyboards/orthodox/rev1/rules.mk b/keyboards/orthodox/rev1/rules.mk
new file mode 100644
index 000000000..a0825b4ef
--- /dev/null
+++ b/keyboards/orthodox/rev1/rules.mk
@@ -0,0 +1,5 @@
1BACKLIGHT_ENABLE = no
2
3ifndef QUANTUM_DIR
4 include ../../../Makefile
5endif \ No newline at end of file
diff --git a/keyboards/orthodox/rules.mk b/keyboards/orthodox/rules.mk
new file mode 100644
index 000000000..0efa78550
--- /dev/null
+++ b/keyboards/orthodox/rules.mk
@@ -0,0 +1,87 @@
1SRC += matrix.c \
2 i2c.c \
3 split_util.c \
4 serial.c
5
6# MCU name
7#MCU = at90usb1287
8MCU = atmega32u4
9
10# Processor frequency.
11# This will define a symbol, F_CPU, in all source code files equal to the
12# processor frequency in Hz. You can then use this symbol in your source code to
13# calculate timings. Do NOT tack on a 'UL' at the end, this will be done
14# automatically to create a 32-bit value in your source code.
15#
16# This will be an integer division of F_USB below, as it is sourced by
17# F_USB after it has run through any CPU prescalers. Note that this value
18# does not *change* the processor frequency - it should merely be updated to
19# reflect the processor speed set externally so that the code can use accurate
20# software delays.
21F_CPU = 16000000
22
23#
24# LUFA specific
25#
26# Target architecture (see library "Board Types" documentation).
27ARCH = AVR8
28
29# Input clock frequency.
30# This will define a symbol, F_USB, in all source code files equal to the
31# input clock frequency (before any prescaling is performed) in Hz. This value may
32# differ from F_CPU if prescaling is used on the latter, and is required as the
33# raw input clock is fed directly to the PLL sections of the AVR for high speed
34# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
35# at the end, this will be done automatically to create a 32-bit value in your
36# source code.
37#
38# If no clock division is performed on the input clock inside the AVR (via the
39# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
40F_USB = $(F_CPU)
41
42# Interrupt driven control endpoint task(+60)
43OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
44
45
46# Boot Section Size in *bytes*
47# Teensy halfKay 512
48# Teensy++ halfKay 1024
49# Atmel DFU loader 4096
50# LUFA bootloader 4096
51# USBaspLoader 2048
52OPT_DEFS += -DBOOTLOADER_SIZE=4096
53
54# Build Options
55# change to "no" to disable the options, or define them in the Makefile in
56# the appropriate keymap folder that will get included automatically
57#
58BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration(+1000)
59MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700)
60EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
61CONSOLE_ENABLE ?= no # Console for debug(+400)
62COMMAND_ENABLE ?= yes # Commands for debug and configuration
63NKRO_ENABLE ?= no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
64BACKLIGHT_ENABLE ?= no # Enable keyboard backlight functionality
65MIDI_ENABLE ?= no # MIDI controls
66AUDIO_ENABLE ?= no # Audio output on port C6
67UNICODE_ENABLE ?= no # Unicode
68BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
69RGBLIGHT_ENABLE ?= no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
70SUBPROJECT_rev1 ?= yes
71USE_I2C ?= yes
72# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
73SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
74
75CUSTOM_MATRIX = yes
76
77avrdude: build
78 ls /dev/tty* > /tmp/1; \
79 echo "Reset your Pro Micro now"; \
80 while [[ -z $$USB ]]; do \
81 sleep 1; \
82 ls /dev/tty* > /tmp/2; \
83 USB=`diff /tmp/1 /tmp/2 | grep -o '/dev/tty.*'`; \
84 done; \
85 avrdude -p $(MCU) -c avr109 -P $$USB -U flash:w:$(BUILD_DIR)/$(TARGET).hex
86
87.PHONY: avrdude
diff --git a/keyboards/orthodox/serial.c b/keyboards/orthodox/serial.c
new file mode 100644
index 000000000..4936e4249
--- /dev/null
+++ b/keyboards/orthodox/serial.c
@@ -0,0 +1,230 @@
1/*
2 * WARNING: be careful changing this code, it is very timing dependent
3 */
4
5#ifndef F_CPU
6#define F_CPU 16000000
7#endif
8
9#include <avr/io.h>
10#include <avr/interrupt.h>
11#include <util/delay.h>
12#include <stdbool.h>
13#include "serial.h"
14
15#ifdef USE_SERIAL
16
17// Serial pulse period in microseconds. Its probably a bad idea to lower this
18// value.
19#define SERIAL_DELAY 24
20
21matrix_row_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
22matrix_row_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
23
24#define ROW_MASK (((matrix_row_t)0-1)>>(8*sizeof(matrix_row_t)-MATRIX_COLS))
25
26#define SLAVE_DATA_CORRUPT (1<<0)
27volatile uint8_t status = 0;
28
29inline static
30void serial_delay(void) {
31 _delay_us(SERIAL_DELAY);
32}
33
34inline static
35void serial_output(void) {
36 SERIAL_PIN_DDR |= SERIAL_PIN_MASK;
37}
38
39// make the serial pin an input with pull-up resistor
40inline static
41void serial_input(void) {
42 SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK;
43 SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
44}
45
46inline static
47matrix_row_t serial_read_pin(void) {
48 return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);
49}
50
51inline static
52void serial_low(void) {
53 SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
54}
55
56inline static
57void serial_high(void) {
58 SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
59}
60
61void serial_master_init(void) {
62 serial_output();
63 serial_high();
64}
65
66void serial_slave_init(void) {
67 serial_input();
68
69 // Enable INT0
70 EIMSK |= _BV(INT0);
71 // Trigger on falling edge of INT0
72 EICRA &= ~(_BV(ISC00) | _BV(ISC01));
73}
74
75// Used by the master to synchronize timing with the slave.
76static
77void sync_recv(void) {
78 serial_input();
79 // This shouldn't hang if the slave disconnects because the
80 // serial line will float to high if the slave does disconnect.
81 while (!serial_read_pin());
82 serial_delay();
83}
84
85// Used by the slave to send a synchronization signal to the master.
86static
87void sync_send(void) {
88 serial_output();
89
90 serial_low();
91 serial_delay();
92
93 serial_high();
94}
95
96// Reads a byte from the serial line
97static
98matrix_row_t serial_read_byte(void) {
99 matrix_row_t byte = 0;
100 serial_input();
101 for ( uint8_t i = 0; i < MATRIX_COLS; ++i) {
102 byte = (byte << 1) | serial_read_pin();
103 serial_delay();
104 _delay_us(1);
105 }
106
107 return byte;
108}
109
110// Sends a byte with MSB ordering
111static
112void serial_write_byte(matrix_row_t data) {
113 matrix_row_t b = MATRIX_COLS;
114 serial_output();
115 while( b-- ) {
116 if(data & (1UL << b)) {
117 serial_high();
118 } else {
119 serial_low();
120 }
121 serial_delay();
122 }
123}
124
125// interrupt handle to be used by the slave device
126ISR(SERIAL_PIN_INTERRUPT) {
127 sync_send();
128
129 matrix_row_t checksum = 0;
130 for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {
131 serial_write_byte(serial_slave_buffer[i]);
132 sync_send();
133 checksum += ROW_MASK & serial_slave_buffer[i];
134 }
135 serial_write_byte(checksum);
136 sync_send();
137
138 // wait for the sync to finish sending
139 serial_delay();
140
141 // read the middle of pulses
142 _delay_us(SERIAL_DELAY/2);
143
144 matrix_row_t checksum_computed = 0;
145 for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {
146 serial_master_buffer[i] = serial_read_byte();
147 sync_send();
148 checksum_computed += ROW_MASK & serial_master_buffer[i];
149 }
150 matrix_row_t checksum_received = serial_read_byte();
151 sync_send();
152
153 serial_input(); // end transaction
154
155 if ( checksum_computed != checksum_received ) {
156 status |= SLAVE_DATA_CORRUPT;
157 } else {
158 status &= ~SLAVE_DATA_CORRUPT;
159 }
160}
161
162inline
163bool serial_slave_DATA_CORRUPT(void) {
164 return status & SLAVE_DATA_CORRUPT;
165}
166
167// Copies the serial_slave_buffer to the master and sends the
168// serial_master_buffer to the slave.
169//
170// Returns:
171// 0 => no error
172// 1 => slave did not respond
173int serial_update_buffers(void) {
174 // this code is very time dependent, so we need to disable interrupts
175 cli();
176
177 // signal to the slave that we want to start a transaction
178 serial_output();
179 serial_low();
180 _delay_us(1);
181
182 // wait for the slaves response
183 serial_input();
184 serial_high();
185 _delay_us(SERIAL_DELAY);
186
187 // check if the slave is present
188 if (serial_read_pin()) {
189 // slave failed to pull the line low, assume not present
190 sei();
191 return 1;
192 }
193
194 // if the slave is present syncronize with it
195 sync_recv();
196
197 matrix_row_t checksum_computed = 0;
198 // receive data from the slave
199 for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {
200 serial_slave_buffer[i] = serial_read_byte();
201 sync_recv();
202 checksum_computed += ROW_MASK & serial_slave_buffer[i];
203 }
204 matrix_row_t checksum_received = serial_read_byte();
205 sync_recv();
206
207 if (checksum_computed != checksum_received) {
208 sei();
209 return 1;
210 }
211
212 matrix_row_t checksum = 0;
213 // send data to the slave
214 for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {
215 serial_write_byte(serial_master_buffer[i]);
216 sync_recv();
217 checksum += ROW_MASK & serial_master_buffer[i];
218 }
219 serial_write_byte(checksum);
220 sync_recv();
221
222 // always, release the line when not in use
223 serial_output();
224 serial_high();
225
226 sei();
227 return 0;
228}
229
230#endif
diff --git a/keyboards/orthodox/serial.h b/keyboards/orthodox/serial.h
new file mode 100644
index 000000000..a46a98c94
--- /dev/null
+++ b/keyboards/orthodox/serial.h
@@ -0,0 +1,27 @@
1#ifndef MY_SERIAL_H
2#define MY_SERIAL_H
3
4#include "config.h"
5#include <stdbool.h>
6#include "matrix.h"
7
8/* TODO: some defines for interrupt setup */
9#define SERIAL_PIN_DDR DDRD
10#define SERIAL_PIN_PORT PORTD
11#define SERIAL_PIN_INPUT PIND
12#define SERIAL_PIN_MASK _BV(PD0)
13#define SERIAL_PIN_INTERRUPT INT0_vect
14
15#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
16#define SERIAL_MASTER_BUFFER_LENGTH 1
17
18// Buffers for master - slave communication
19extern volatile matrix_row_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
20extern volatile matrix_row_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
21
22void serial_master_init(void);
23void serial_slave_init(void);
24int serial_update_buffers(void);
25bool serial_slave_data_corrupt(void);
26
27#endif
diff --git a/keyboards/orthodox/split_util.c b/keyboards/orthodox/split_util.c
new file mode 100644
index 000000000..39639c3b4
--- /dev/null
+++ b/keyboards/orthodox/split_util.c
@@ -0,0 +1,84 @@
1#include <avr/io.h>
2#include <avr/wdt.h>
3#include <avr/power.h>
4#include <avr/interrupt.h>
5#include <util/delay.h>
6#include <avr/eeprom.h>
7#include "split_util.h"
8#include "matrix.h"
9#include "keyboard.h"
10#include "config.h"
11
12#ifdef USE_I2C
13# include "i2c.h"
14#else
15# include "serial.h"
16#endif
17
18volatile bool isLeftHand = true;
19
20static void setup_handedness(void) {
21 #ifdef EE_HANDS
22 isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
23 #else
24 // I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c
25 #if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
26 isLeftHand = !has_usb();
27 #else
28 isLeftHand = has_usb();
29 #endif
30 #endif
31}
32
33static void keyboard_master_setup(void) {
34#ifdef USE_I2C
35 i2c_master_init();
36#ifdef SSD1306OLED
37 matrix_master_OLED_init ();
38#endif
39#else
40 serial_master_init();
41#endif
42}
43
44static void keyboard_slave_setup(void) {
45#ifdef USE_I2C
46 i2c_slave_init(SLAVE_I2C_ADDRESS);
47#else
48 serial_slave_init();
49#endif
50}
51
52bool has_usb(void) {
53 USBCON |= (1 << OTGPADE); //enables VBUS pad
54 _delay_us(5);
55 return (USBSTA & (1<<VBUS)); //checks state of VBUS
56}
57
58void split_keyboard_setup(void) {
59 setup_handedness();
60
61 if (has_usb()) {
62 keyboard_master_setup();
63 } else {
64 keyboard_slave_setup();
65 }
66 sei();
67}
68
69void keyboard_slave_loop(void) {
70 matrix_init();
71
72 while (1) {
73 matrix_slave_scan();
74 }
75}
76
77// this code runs before the usb and keyboard is initialized
78void matrix_setup(void) {
79 split_keyboard_setup();
80
81 if (!has_usb()) {
82 keyboard_slave_loop();
83 }
84}
diff --git a/keyboards/orthodox/split_util.h b/keyboards/orthodox/split_util.h
new file mode 100644
index 000000000..3ae76c209
--- /dev/null
+++ b/keyboards/orthodox/split_util.h
@@ -0,0 +1,24 @@
1#ifndef SPLIT_KEYBOARD_UTIL_H
2#define SPLIT_KEYBOARD_UTIL_H
3
4#include <stdbool.h>
5
6#ifdef EE_HANDS
7 #define EECONFIG_BOOTMAGIC_END (uint8_t *)10
8 #define EECONFIG_HANDEDNESS EECONFIG_BOOTMAGIC_END
9#endif
10
11#define SLAVE_I2C_ADDRESS 0x32
12
13extern volatile bool isLeftHand;
14
15// slave version of matix scan, defined in matrix.c
16void matrix_slave_scan(void);
17
18void split_keyboard_setup(void);
19bool has_usb(void);
20void keyboard_slave_loop(void);
21
22void matrix_master_OLED_init (void);
23
24#endif
diff --git a/keyboards/orthodox/ssd1306.c b/keyboards/orthodox/ssd1306.c
new file mode 100644
index 000000000..5c6dff27f
--- /dev/null
+++ b/keyboards/orthodox/ssd1306.c
@@ -0,0 +1,470 @@
1#ifdef SSD1306OLED
2
3#include "ssd1306.h"
4#include "config.h"
5#include "i2c.h"
6#include <string.h>
7#include "print.h"
8#include "lets_split.h"
9#include "common/glcdfont.c"
10#ifdef ADAFRUIT_BLE_ENABLE
11#include "adafruit_ble.h"
12#endif
13#ifdef PROTOCOL_LUFA
14#include "lufa.h"
15#endif
16#include "sendchar.h"
17#include "pincontrol.h"
18
19//assign the right code to your layers
20#define _BASE 0
21#define _LOWER 8
22#define _RAISE 16
23#define _FNLAYER 64
24#define _NUMLAY 128
25#define _NLOWER 136
26#define _NFNLAYER 192
27#define _MOUSECURSOR 256
28#define _ADJUST 65560
29
30// Set this to 1 to help diagnose early startup problems
31// when testing power-on with ble. Turn it off otherwise,
32// as the latency of printing most of the debug info messes
33// with the matrix scan, causing keys to drop.
34#define DEBUG_TO_SCREEN 0
35
36// Controls the SSD1306 128x32 OLED display via i2c
37
38#define i2cAddress 0x3C
39
40#define DisplayHeight 32
41#define DisplayWidth 128
42
43#define FontHeight 8
44#define FontWidth 6
45
46#define MatrixRows (DisplayHeight / FontHeight)
47#define MatrixCols (DisplayWidth / FontWidth)
48
49struct CharacterMatrix {
50 uint8_t display[MatrixRows][MatrixCols];
51 uint8_t *cursor;
52 bool dirty;
53};
54
55static struct CharacterMatrix display;
56//static uint16_t last_battery_update;
57//static uint32_t vbat;
58//#define BatteryUpdateInterval 10000 /* milliseconds */
59#define ScreenOffInterval 300000 /* milliseconds */
60#if DEBUG_TO_SCREEN
61static uint8_t displaying;
62#endif
63static uint16_t last_flush;
64
65enum ssd1306_cmds {
66 DisplayOff = 0xAE,
67 DisplayOn = 0xAF,
68
69 SetContrast = 0x81,
70 DisplayAllOnResume = 0xA4,
71
72 DisplayAllOn = 0xA5,
73 NormalDisplay = 0xA6,
74 InvertDisplay = 0xA7,
75 SetDisplayOffset = 0xD3,
76 SetComPins = 0xda,
77 SetVComDetect = 0xdb,
78 SetDisplayClockDiv = 0xD5,
79 SetPreCharge = 0xd9,
80 SetMultiPlex = 0xa8,
81 SetLowColumn = 0x00,
82 SetHighColumn = 0x10,
83 SetStartLine = 0x40,
84
85 SetMemoryMode = 0x20,
86 ColumnAddr = 0x21,
87 PageAddr = 0x22,
88
89 ComScanInc = 0xc0,
90 ComScanDec = 0xc8,
91 SegRemap = 0xa0,
92 SetChargePump = 0x8d,
93 ExternalVcc = 0x01,
94 SwitchCapVcc = 0x02,
95
96 ActivateScroll = 0x2f,
97 DeActivateScroll = 0x2e,
98 SetVerticalScrollArea = 0xa3,
99 RightHorizontalScroll = 0x26,
100 LeftHorizontalScroll = 0x27,
101 VerticalAndRightHorizontalScroll = 0x29,
102 VerticalAndLeftHorizontalScroll = 0x2a,
103};
104
105
106// Write command sequence.
107// Returns true on success.
108static inline bool _send_cmd1(uint8_t cmd) {
109 bool res = false;
110
111 if (i2c_start_write(i2cAddress)) {
112 xprintf("failed to start write to %d\n", i2cAddress);
113 goto done;
114 }
115
116 if (i2c_master_write(0x0 /* command byte follows */)) {
117 print("failed to write control byte\n");
118
119 goto done;
120 }
121
122 if (i2c_master_write(cmd)) {
123 xprintf("failed to write command %d\n", cmd);
124 goto done;
125 }
126 res = true;
127done:
128 i2c_master_stop();
129 return res;
130}
131
132// Write 2-byte command sequence.
133// Returns true on success
134static inline bool _send_cmd2(uint8_t cmd, uint8_t opr) {
135 if (!_send_cmd1(cmd)) {
136 return false;
137 }
138 return _send_cmd1(opr);
139}
140
141// Write 3-byte command sequence.
142// Returns true on success
143static inline bool _send_cmd3(uint8_t cmd, uint8_t opr1, uint8_t opr2) {
144 if (!_send_cmd1(cmd)) {
145 return false;
146 }
147 if (!_send_cmd1(opr1)) {
148 return false;
149 }
150 return _send_cmd1(opr2);
151}
152
153#define send_cmd1(c) if (!_send_cmd1(c)) {goto done;}
154#define send_cmd2(c,o) if (!_send_cmd2(c,o)) {goto done;}
155#define send_cmd3(c,o1,o2) if (!_send_cmd3(c,o1,o2)) {goto done;}
156
157static void matrix_clear(struct CharacterMatrix *matrix);
158
159static void clear_display(void) {
160 matrix_clear(&display);
161
162 // Clear all of the display bits (there can be random noise
163 // in the RAM on startup)
164 send_cmd3(PageAddr, 0, (DisplayHeight / 8) - 1);
165 send_cmd3(ColumnAddr, 0, DisplayWidth - 1);
166
167 if (i2c_start_write(i2cAddress)) {
168 goto done;
169 }
170 if (i2c_master_write(0x40)) {
171 // Data mode
172 goto done;
173 }
174 for (uint8_t row = 0; row < MatrixRows; ++row) {
175 for (uint8_t col = 0; col < DisplayWidth; ++col) {
176 i2c_master_write(0);
177 }
178 }
179
180 display.dirty = false;
181
182done:
183 i2c_master_stop();
184}
185
186#if DEBUG_TO_SCREEN
187#undef sendchar
188static int8_t capture_sendchar(uint8_t c) {
189 sendchar(c);
190 iota_gfx_write_char(c);
191
192 if (!displaying) {
193 iota_gfx_flush();
194 }
195 return 0;
196}
197#endif
198
199bool iota_gfx_init(void) {
200 bool success = false;
201
202 send_cmd1(DisplayOff);
203 send_cmd2(SetDisplayClockDiv, 0x80);
204 send_cmd2(SetMultiPlex, DisplayHeight - 1);
205
206 send_cmd2(SetDisplayOffset, 0);
207
208
209 send_cmd1(SetStartLine | 0x0);
210 send_cmd2(SetChargePump, 0x14 /* Enable */);
211 send_cmd2(SetMemoryMode, 0 /* horizontal addressing */);
212
213/// Flips the display orientation 0 degrees
214 send_cmd1(SegRemap | 0x1);
215 send_cmd1(ComScanDec);
216/*
217// the following Flip the display orientation 180 degrees
218 send_cmd1(SegRemap);
219 send_cmd1(ComScanInc);
220// end flip */
221 send_cmd2(SetComPins, 0x2);
222 send_cmd2(SetContrast, 0x8f);
223 send_cmd2(SetPreCharge, 0xf1);
224 send_cmd2(SetVComDetect, 0x40);
225 send_cmd1(DisplayAllOnResume);
226 send_cmd1(NormalDisplay);
227 send_cmd1(DeActivateScroll);
228 send_cmd1(DisplayOn);
229
230 send_cmd2(SetContrast, 0); // Dim
231
232 clear_display();
233
234 success = true;
235
236 iota_gfx_flush();
237
238#if DEBUG_TO_SCREEN
239 print_set_sendchar(capture_sendchar);
240#endif
241
242done:
243 return success;
244}
245
246bool iota_gfx_off(void) {
247 bool success = false;
248
249 send_cmd1(DisplayOff);
250 success = true;
251
252done:
253 return success;
254}
255
256bool iota_gfx_on(void) {
257 bool success = false;
258
259 send_cmd1(DisplayOn);
260 success = true;
261
262done:
263 return success;
264}
265
266static void matrix_write_char_inner(struct CharacterMatrix *matrix, uint8_t c) {
267 *matrix->cursor = c;
268 ++matrix->cursor;
269
270 if (matrix->cursor - &matrix->display[0][0] == sizeof(matrix->display)) {
271 // We went off the end; scroll the display upwards by one line
272 memmove(&matrix->display[0], &matrix->display[1],
273 MatrixCols * (MatrixRows - 1));
274 matrix->cursor = &matrix->display[MatrixRows - 1][0];
275 memset(matrix->cursor, ' ', MatrixCols);
276 }
277}
278
279static void matrix_write_char(struct CharacterMatrix *matrix, uint8_t c) {
280 matrix->dirty = true;
281
282 if (c == '\n') {
283 // Clear to end of line from the cursor and then move to the
284 // start of the next line
285 uint8_t cursor_col = (matrix->cursor - &matrix->display[0][0]) % MatrixCols;
286
287 while (cursor_col++ < MatrixCols) {
288 matrix_write_char_inner(matrix, ' ');
289 }
290 return;
291 }
292
293 matrix_write_char_inner(matrix, c);
294}
295
296void iota_gfx_write_char(uint8_t c) {
297 matrix_write_char(&display, c);
298}
299
300static void matrix_write(struct CharacterMatrix *matrix, const char *data) {
301 const char *end = data + strlen(data);
302 while (data < end) {
303 matrix_write_char(matrix, *data);
304 ++data;
305 }
306}
307
308void iota_gfx_write(const char *data) {
309 matrix_write(&display, data);
310}
311
312static void matrix_write_P(struct CharacterMatrix *matrix, const char *data) {
313 while (true) {
314 uint8_t c = pgm_read_byte(data);
315 if (c == 0) {
316 return;
317 }
318 matrix_write_char(matrix, c);
319 ++data;
320 }
321}
322
323void iota_gfx_write_P(const char *data) {
324 matrix_write_P(&display, data);
325}
326
327static void matrix_clear(struct CharacterMatrix *matrix) {
328 memset(matrix->display, ' ', sizeof(matrix->display));
329 matrix->cursor = &matrix->display[0][0];
330 matrix->dirty = true;
331}
332
333void iota_gfx_clear_screen(void) {
334 matrix_clear(&display);
335}
336
337static void matrix_render(struct CharacterMatrix *matrix) {
338 last_flush = timer_read();
339 iota_gfx_on();
340#if DEBUG_TO_SCREEN
341 ++displaying;
342#endif
343
344 // Move to the home position
345 send_cmd3(PageAddr, 0, MatrixRows - 1);
346 send_cmd3(ColumnAddr, 0, (MatrixCols * FontWidth) - 1);
347
348 if (i2c_start_write(i2cAddress)) {
349 goto done;
350 }
351 if (i2c_master_write(0x40)) {
352 // Data mode
353 goto done;
354 }
355
356 for (uint8_t row = 0; row < MatrixRows; ++row) {
357 for (uint8_t col = 0; col < MatrixCols; ++col) {
358 const uint8_t *glyph = font + (matrix->display[row][col] * (FontWidth - 1));
359
360 for (uint8_t glyphCol = 0; glyphCol < FontWidth - 1; ++glyphCol) {
361 uint8_t colBits = pgm_read_byte(glyph + glyphCol);
362 i2c_master_write(colBits);
363 }
364
365 // 1 column of space between chars (it's not included in the glyph)
366 i2c_master_write(0);
367 }
368 }
369
370 matrix->dirty = false;
371
372done:
373 i2c_master_stop();
374#if DEBUG_TO_SCREEN
375 --displaying;
376#endif
377}
378
379void iota_gfx_flush(void) {
380 matrix_render(&display);
381}
382
383static void matrix_update(struct CharacterMatrix *dest,
384 const struct CharacterMatrix *source) {
385 if (memcmp(dest->display, source->display, sizeof(dest->display))) {
386 memcpy(dest->display, source->display, sizeof(dest->display));
387 dest->dirty = true;
388 }
389}
390
391static void render_status_info(void) {
392#if DEBUG_TO_SCREEN
393 if (debug_enable) {
394 return;
395 }
396#endif
397
398 struct CharacterMatrix matrix;
399
400 matrix_clear(&matrix);
401 matrix_write_P(&matrix, PSTR("USB: "));
402#ifdef PROTOCOL_LUFA
403 switch (USB_DeviceState) {
404 case DEVICE_STATE_Unattached:
405 matrix_write_P(&matrix, PSTR("Unattached"));
406 break;
407 case DEVICE_STATE_Suspended:
408 matrix_write_P(&matrix, PSTR("Suspended"));
409 break;
410 case DEVICE_STATE_Configured:
411 matrix_write_P(&matrix, PSTR("Connected"));
412 break;
413 case DEVICE_STATE_Powered:
414 matrix_write_P(&matrix, PSTR("Powered"));
415 break;
416 case DEVICE_STATE_Default:
417 matrix_write_P(&matrix, PSTR("Default"));
418 break;
419 case DEVICE_STATE_Addressed:
420 matrix_write_P(&matrix, PSTR("Addressed"));
421 break;
422 default:
423 matrix_write_P(&matrix, PSTR("Invalid"));
424 }
425#endif
426
427// Define layers here, Have not worked out how to have text displayed for each layer. Copy down the number you see and add a case for it below
428
429 char buf[40];
430 snprintf(buf,sizeof(buf), "Undef-%ld", layer_state);
431 matrix_write_P(&matrix, PSTR("\n\nLayer: "));
432 switch (layer_state) {
433 case _BASE:
434 matrix_write_P(&matrix, PSTR("Default"));
435 break;
436 case _RAISE:
437 matrix_write_P(&matrix, PSTR("Raise"));
438 break;
439 case _LOWER:
440 matrix_write_P(&matrix, PSTR("Lower"));
441 break;
442 case _ADJUST:
443 matrix_write_P(&matrix, PSTR("ADJUST"));
444 break;
445 default:
446 matrix_write(&matrix, buf);
447 }
448
449 // Host Keyboard LED Status
450 char led[40];
451 snprintf(led, sizeof(led), "\n%s %s %s",
452 (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? "NUMLOCK" : " ",
453 (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? "CAPS" : " ",
454 (host_keyboard_leds() & (1<<USB_LED_SCROLL_LOCK)) ? "SCLK" : " ");
455 matrix_write(&matrix, led);
456 matrix_update(&display, &matrix);
457}
458
459void iota_gfx_task(void) {
460 render_status_info();
461
462 if (display.dirty) {
463 iota_gfx_flush();
464 }
465
466 if (timer_elapsed(last_flush) > ScreenOffInterval) {
467 iota_gfx_off();
468 }
469}
470#endif
diff --git a/keyboards/orthodox/ssd1306.h b/keyboards/orthodox/ssd1306.h
new file mode 100644
index 000000000..b0c74f987
--- /dev/null
+++ b/keyboards/orthodox/ssd1306.h
@@ -0,0 +1,17 @@
1#ifndef SSD1306_H
2#define SSD1306_H
3
4#include <stdbool.h>
5#include <stdio.h>
6
7bool iota_gfx_init(void);
8void iota_gfx_task(void);
9bool iota_gfx_off(void);
10bool iota_gfx_on(void);
11void iota_gfx_flush(void);
12void iota_gfx_write_char(uint8_t c);
13void iota_gfx_write(const char *data);
14void iota_gfx_write_P(const char *data);
15void iota_gfx_clear_screen(void);
16
17#endif
diff --git a/keyboards/planck/keymaps/rai-suta/Makefile b/keyboards/planck/keymaps/rai-suta/Makefile
new file mode 100644
index 000000000..4263440ec
--- /dev/null
+++ b/keyboards/planck/keymaps/rai-suta/Makefile
@@ -0,0 +1,28 @@
1
2
3# Build Options
4# change to "no" to disable the options, or define them in the Makefile in
5# the appropriate keymap folder that will get included automatically
6#
7BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000)
8MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
9EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
10CONSOLE_ENABLE = yes # Console for debug(+400)
11COMMAND_ENABLE = no # Commands for debug and configuration
12NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
13BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
14MIDI_ENABLE = no # MIDI controls
15AUDIO_ENABLE = no # Audio output on port C6
16UNICODE_ENABLE = no # Unicode
17BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
18RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
19
20# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
21SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
22
23# Option defines
24OPT_DEFS += -DJIS_KEYCODE
25
26ifndef QUANTUM_DIR
27 include ../../../../Makefile
28endif \ No newline at end of file
diff --git a/keyboards/planck/keymaps/rai-suta/config.h b/keyboards/planck/keymaps/rai-suta/config.h
new file mode 100644
index 000000000..b36aa3db9
--- /dev/null
+++ b/keyboards/planck/keymaps/rai-suta/config.h
@@ -0,0 +1,8 @@
1#ifndef CONFIG_USER_H
2#define CONFIG_USER_H
3
4#include "../../config.h"
5
6#define TAPPING_TERM ( 200 )
7
8#endif
diff --git a/keyboards/planck/keymaps/rai-suta/keymap.c b/keyboards/planck/keymaps/rai-suta/keymap.c
new file mode 100644
index 000000000..13fc3677e
--- /dev/null
+++ b/keyboards/planck/keymaps/rai-suta/keymap.c
@@ -0,0 +1,107 @@
1// This keymap assumes that the keyboard is recognized as JIS keyboard from the OS.
2
3#include "planck.h"
4#include "version.h"
5
6// Keycode defines
7#define _______ KC_TRNS
8#define XXXXXXX KC_NO
9#define C(kc) LCTL(kc)
10// JIS keyboard
11#define JK_CIRC KC_EQL // ^
12#define JK_AT KC_LBRC // @
13#define JK_LBRC KC_RBRC // [
14#define JK_CLN KC_QUOT // :
15#define JK_RBRC KC_BSLS // ]
16#define JK_BSLS KC_RO // Backslash(\)
17#define JK_DQT S(KC_2) // "
18#define JK_AMPR S(KC_6) // &
19#define JK_SQT S(KC_7) // '
20#define JK_LPRN S(KC_8) // (
21#define JK_RPRN S(KC_9) // )
22#define JK_S0 S(KC_0) // Tilde(~) at IBM 5576-A01 spec
23#define JK_EQ S(KC_MINS) // =
24#define JK_TLD S(JK_CIRC) // ~
25#define JK_PIPE S(KC_JYEN) // |
26#define JK_GRV S(JK_AT) // `
27#define JK_LCBR S(JK_LBRC) // {
28#define JK_PLUS S(KC_SCLN) // +
29#define JK_ASTR S(JK_CLN) // *
30#define JK_RCBR S(JK_RBRC) // }
31#define JK_QUES S(KC_SLSH) // ?
32#define JK_UNDS S(JK_BSLS) // _
33
34enum user_macro {
35 UM_MHEN,
36 UM_HENK,
37 UM_DEBUG,
38};
39#define M_MHEN MACROTAP(UM_MHEN)
40#define M_HENK MACROTAP(UM_HENK)
41#define M_DEBUG M(UM_DEBUG)
42
43enum keymap_layer {
44 KL_QWERTY,
45 KL_LOWER,
46 KL_RAISE,
47};
48const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
49
50 [KL_QWERTY] = {
51 { KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC},
52 {KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, JK_CLN},
53 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT},
54 {KC_ZKHK, KC_KANA, KC_LGUI, KC_LALT, M_MHEN, KC_SPC, KC_SPC, M_HENK, KC_RALT, KC_RGUI, KC_APP, KC_ENT}
55 },
56
57 [KL_LOWER] = {
58 {KC_GESC, KC_EXLM, JK_DQT, KC_HASH, KC_DLR, KC_PERC, JK_AMPR, JK_SQT, JK_LPRN, JK_RPRN, JK_S0, KC_DEL},
59 {_______, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, KC_DEL, KC_BSPC, JK_EQ, JK_TLD, JK_GRV, JK_LCBR, JK_PIPE},
60 {_______, C(KC_Z), C(KC_X), C(KC_C), C(KC_V), C(KC_Y), XXXXXXX, KC_ENT, KC_LABK, KC_RABK, JK_RCBR, JK_UNDS},
61 { RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
62 },
63
64 [KL_RAISE] = {
65 {KC_CAPS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL},
66 {_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, JK_CIRC, JK_AT, JK_LBRC, KC_JYEN},
67 {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, KC_COMM, KC_DOT, JK_RBRC, JK_BSLS},
68 {M_DEBUG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
69 },
70
71};
72
73const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
74{
75 dprintf( "record.\n"
76 " event.pressed = %u\n"
77 " tap.count = %u\n"
78 " tap.interrupted = %u\n"
79 , record->event.pressed
80 , record->tap.count
81 , record->tap.interrupted );
82 dprintf( "id = %u\n", id );
83 dprintf( "opt = %u\n", opt );
84
85 switch(id) {
86
87 case UM_MHEN: {
88 return MACRO_TAP_HOLD_LAYER( record, MACRO(TYPE(KC_MHEN), END), KL_LOWER );
89 } break;
90
91 case UM_HENK: {
92 return MACRO_TAP_HOLD_LAYER( record, MACRO(TYPE(KC_HENK), END), KL_RAISE );
93 } break;
94
95 case UM_DEBUG: {
96 if (record->event.pressed) {
97 debug_enable = !debug_enable;
98 if (debug_enable) {
99 dprint("\nDEBUG: enabled.\n");
100 SEND_STRING (QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
101 }
102 }
103 } break;
104
105 }
106 return MACRO_NONE;
107};
diff --git a/keyboards/planck/keymaps/rai-suta/readme.md b/keyboards/planck/keymaps/rai-suta/readme.md
new file mode 100644
index 000000000..cb73c172a
--- /dev/null
+++ b/keyboards/planck/keymaps/rai-suta/readme.md
@@ -0,0 +1,3 @@
1# rai-suta's Planck Layout
2
3This keymap assumes that the keyboard is recognized as JIS keyboard from the OS.
diff --git a/keyboards/whitefox/animations.c b/keyboards/whitefox/animations.c
new file mode 100644
index 000000000..ed1d75efb
--- /dev/null
+++ b/keyboards/whitefox/animations.c
@@ -0,0 +1,128 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#if defined(VISUALIZER_ENABLE)
18
19#include "animations.h"
20#include "visualizer.h"
21
22#ifdef BACKLIGHT_ENABLE
23#include "led_keyframes.h"
24#endif
25
26#include "visualizer_keyframes.h"
27
28
29#if defined(LCD_ENABLE) || defined(LCD_BACKLIGHT_ENABLE) || defined(BACKLIGHT_ENABLE)
30
31static bool keyframe_enable(keyframe_animation_t* animation, visualizer_state_t* state) {
32#ifdef BACKLIGHT_ENABLE
33 led_keyframe_enable(animation, state);
34#endif
35 return false;
36}
37
38static bool keyframe_disable(keyframe_animation_t* animation, visualizer_state_t* state) {
39#ifdef BACKLIGHT_ENABLE
40 led_keyframe_disable(animation, state);
41#endif
42 return false;
43}
44
45static bool keyframe_fade_in(keyframe_animation_t* animation, visualizer_state_t* state) {
46 bool ret = false;
47#ifdef BACKLIGHT_ENABLE
48 ret |= led_keyframe_fade_in_all(animation, state);
49#endif
50 return ret;
51}
52
53static bool keyframe_fade_out(keyframe_animation_t* animation, visualizer_state_t* state) {
54 bool ret = false;
55#ifdef BACKLIGHT_ENABLE
56 ret |= led_keyframe_fade_out_all(animation, state);
57#endif
58 return ret;
59}
60
61
62// Don't worry, if the startup animation is long, you can use the keyboard like normal
63// during that time
64keyframe_animation_t default_startup_animation = {
65 .num_frames = 2,
66 .loop = false,
67 .frame_lengths = {0, gfxMillisecondsToTicks(5000)},
68 .frame_functions = {
69 keyframe_enable,
70 keyframe_fade_in,
71 },
72};
73
74keyframe_animation_t default_suspend_animation = {
75 .num_frames = 2,
76 .loop = false,
77 .frame_lengths = {gfxMillisecondsToTicks(1000), 0},
78 .frame_functions = {
79 keyframe_fade_out,
80 keyframe_disable,
81 },
82};
83#endif
84
85#if defined(BACKLIGHT_ENABLE)
86#define CROSSFADE_TIME 1000
87#define GRADIENT_TIME 3000
88
89keyframe_animation_t led_test_animation = {
90 .num_frames = 14,
91 .loop = true,
92 .frame_lengths = {
93 gfxMillisecondsToTicks(1000), // fade in
94 gfxMillisecondsToTicks(1000), // no op (leds on)
95 gfxMillisecondsToTicks(1000), // fade out
96 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
97 gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in)
98 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
99 gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom
100 0, // mirror leds
101 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
102 gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out)
103 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
104 gfxMillisecondsToTicks(GRADIENT_TIME), // top_to_bottom
105 0, // normal leds
106 gfxMillisecondsToTicks(CROSSFADE_TIME), // crossfade
107
108 },
109 .frame_functions = {
110 led_keyframe_fade_in_all,
111 keyframe_no_operation,
112 led_keyframe_fade_out_all,
113 led_keyframe_crossfade,
114 led_keyframe_left_to_right_gradient,
115 led_keyframe_crossfade,
116 led_keyframe_top_to_bottom_gradient,
117 led_keyframe_mirror_orientation,
118 led_keyframe_crossfade,
119 led_keyframe_left_to_right_gradient,
120 led_keyframe_crossfade,
121 led_keyframe_top_to_bottom_gradient,
122 led_keyframe_normal_orientation,
123 led_keyframe_crossfade,
124 },
125};
126#endif
127
128#endif
diff --git a/keyboards/whitefox/animations.h b/keyboards/whitefox/animations.h
new file mode 100644
index 000000000..6d8b9830d
--- /dev/null
+++ b/keyboards/whitefox/animations.h
@@ -0,0 +1,30 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_
18#define KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_
19
20#include "visualizer.h"
21
22// You can use these default animations, but of course you can also write your own custom ones instead
23extern keyframe_animation_t default_startup_animation;
24extern keyframe_animation_t default_suspend_animation;
25
26// An animation for testing and demonstrating the led support, should probably not be used for real world
27// cases
28extern keyframe_animation_t led_test_animation;
29
30#endif /* KEYBOARDS_ERGODOX_INFINITY_ANIMATIONS_H_ */
diff --git a/keyboards/whitefox/config.h b/keyboards/whitefox/config.h
index b7116341f..08de9b9aa 100644
--- a/keyboards/whitefox/config.h
+++ b/keyboards/whitefox/config.h
@@ -35,6 +35,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
35#define MATRIX_ROWS 9 35#define MATRIX_ROWS 9
36#define MATRIX_COLS 8 36#define MATRIX_COLS 8
37 37
38/* number of backlight levels */
39#define BACKLIGHT_LEVELS 3
40
41#define LED_BRIGHTNESS_LO 100
42#define LED_BRIGHTNESS_HI 255
43
38/* define if matrix has ghost */ 44/* define if matrix has ghost */
39//#define MATRIX_HAS_GHOST 45//#define MATRIX_HAS_GHOST
40 46
@@ -76,3 +82,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
76//#define NO_ACTION_FUNCTION 82//#define NO_ACTION_FUNCTION
77 83
78#endif 84#endif
85
86// The visualizer needs gfx thread priorities
87#define LED_DISPLAY_NUMBER 0
88
89#define LED_NUM_ROWS 5
90#define LED_NUM_COLS 16
91
92#define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2)
diff --git a/keyboards/whitefox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h
new file mode 100644
index 000000000..3dc5327a5
--- /dev/null
+++ b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/board_IS31FL3731C.h
@@ -0,0 +1,109 @@
1/*
2Copyright 2016 Fred Sundvik <fsundvik@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef _GDISP_LLD_BOARD_H
19#define _GDISP_LLD_BOARD_H
20
21static const I2CConfig i2ccfg = {
22 400000 // clock speed (Hz); 400kHz max for IS31
23};
24
25#define GDISP_SCREEN_WIDTH 16
26#define GDISP_SCREEN_HEIGHT 5
27
28static const uint8_t led_mask[] = {
29 0xFF, 0x00, /* C1-1 -> C1-16 */
30 0xFF, 0x00, /* C2-1 -> C2-16 */
31 0xFF, 0x00, /* C3-1 -> C3-16 */
32 0xFF, 0x00, /* C4-1 -> C4-16 */
33 0xFF, 0x00, /* C5-1 -> C5-16 */
34 0xFF, 0x00, /* C6-1 -> C6-16 */
35 0xFF, 0x00, /* C7-1 -> C7-16 */
36 0xFF, 0x00, /* C8-1 -> C8-16 */
37 0xFE, 0x00, /* C9-1 -> C9-16 */
38};
39
40// The address of the LED
41#define LA(c, r) (c + r * 16 )
42// Need to be an address that is not mapped, but inside the range of the controller matrix
43#define NA LA(8, 8)
44
45// The numbers in the comments are the led numbers DXX on the PCB
46// The mapping is taken from the schematic of left hand side
47static const uint8_t led_mapping[GDISP_SCREEN_HEIGHT][GDISP_SCREEN_WIDTH] = {
48// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
49 { LA(0, 0), LA(1, 0), LA(2, 0), LA(3, 0), LA(4, 0), LA(5, 0), LA(6, 0), LA(7, 0), LA(0, 1), LA(1, 1), LA(2, 1), LA(3, 1), LA(4, 1), LA(5, 1), LA(6, 1), LA(7, 1)},
50// 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
51 { LA(0, 2), LA(1, 2), LA(2, 2), LA(3, 2), LA(4, 2), LA(5, 2), LA(6, 2), LA(7, 2), LA(0, 3), LA(1, 3), NA, LA(2, 3), LA(3, 3), LA(4, 3), LA(5, 3), LA(6, 3)},
52// 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
53 { LA(7, 3), LA(0, 4), LA(1, 4), LA(2, 4), LA(3, 4), LA(4, 4), LA(5, 4), LA(6, 4), LA(7, 4), LA(0, 5), NA, LA(1, 5), LA(2, 5), LA(3, 5), LA(4, 5), LA(5, 5)},
54// 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
55 { LA(6, 5), LA(7, 5), LA(0, 6), LA(1, 6), LA(2, 6), LA(3, 6), LA(4, 6), LA(5, 6), LA(6, 6), LA(7, 6), NA, LA(0, 7), LA(1, 7), LA(2, 7), LA(3, 7), LA(4, 7)},
56// 62 63 64 65 66 67 68 69 70 71
57 { LA(5, 7), LA(6, 7), LA(7, 7), NA, NA, NA, LA(0, 8), NA, NA, NA, LA(1, 8), LA(2, 8), LA(3, 8), LA(4, 8), LA(5, 8), LA(6, 8)},
58};
59
60
61#define IS31_ADDR_DEFAULT 0x74 // AD connected to GND
62#define IS31_TIMEOUT 5000
63
64static GFXINLINE void init_board(GDisplay *g) {
65 (void) g;
66 /* I2C pins */
67 palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL
68 palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2); // PTB1/I2C0/SDA
69 palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL);
70 palClearPad(GPIOB, 16);
71 /* start I2C */
72 i2cStart(&I2CD1, &i2ccfg);
73 // try high drive (from kiibohd)
74 I2CD1.i2c->C2 |= I2Cx_C2_HDRS;
75 // try glitch fixing (from kiibohd)
76 I2CD1.i2c->FLT = 4;
77}
78
79static GFXINLINE void post_init_board(GDisplay *g) {
80 (void) g;
81}
82
83static GFXINLINE const uint8_t* get_led_mask(GDisplay* g) {
84 (void) g;
85 return led_mask;
86}
87
88static GFXINLINE uint8_t get_led_address(GDisplay* g, uint16_t x, uint16_t y)
89{
90 (void) g;
91 return led_mapping[y][x];
92}
93
94static GFXINLINE void set_hardware_shutdown(GDisplay* g, bool shutdown) {
95 (void) g;
96 if(!shutdown) {
97 palSetPad(GPIOB, 16);
98 }
99 else {
100 palClearPad(GPIOB, 16);
101 }
102}
103
104static GFXINLINE void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
105 (void) g;
106 i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, data, length, 0, 0, US2ST(IS31_TIMEOUT));
107}
108
109#endif /* _GDISP_LLD_BOARD_H */
diff --git a/keyboards/whitefox/drivers/gdisp/IS31FL3731C/driver.mk b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/driver.mk
new file mode 100644
index 000000000..f32d0d868
--- /dev/null
+++ b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/driver.mk
@@ -0,0 +1,2 @@
1GFXINC += drivers/gdisp/IS31FL3731C
2GFXSRC += drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c
diff --git a/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c
new file mode 100644
index 000000000..c807cbd1e
--- /dev/null
+++ b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_IS31FL3731C.c
@@ -0,0 +1,312 @@
1/*
2Copyright 2016 Fred Sundvik <fsundvik@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include "gfx.h"
19
20#if GFX_USE_GDISP
21
22#define GDISP_DRIVER_VMT GDISPVMT_IS31FL3731C_WHITEFOX
23#include "drivers/gdisp/IS31FL3731C/gdisp_lld_config.h"
24#include "src/gdisp/gdisp_driver.h"
25
26#include "board_IS31FL3731C.h"
27
28
29// Can't include led_tables from here
30extern const uint8_t CIE1931_CURVE[];
31
32/*===========================================================================*/
33/* Driver local definitions. */
34/*===========================================================================*/
35
36#ifndef GDISP_SCREEN_HEIGHT
37 #define GDISP_SCREEN_HEIGHT 9
38#endif
39#ifndef GDISP_SCREEN_WIDTH
40 #define GDISP_SCREEN_WIDTH 16
41#endif
42#ifndef GDISP_INITIAL_CONTRAST
43 #define GDISP_INITIAL_CONTRAST 0
44#endif
45#ifndef GDISP_INITIAL_BACKLIGHT
46 #define GDISP_INITIAL_BACKLIGHT 0
47#endif
48
49#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0)
50
51#define IS31_ADDR_DEFAULT 0x74
52
53#define IS31_REG_CONFIG 0x00
54// bits in reg
55#define IS31_REG_CONFIG_PICTUREMODE 0x00
56#define IS31_REG_CONFIG_AUTOPLAYMODE 0x08
57#define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18
58// D2:D0 bits are starting frame for autoplay mode
59
60#define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode
61
62#define IS31_REG_AUTOPLAYCTRL1 0x02
63// D6:D4 number of loops (000=infty)
64// D2:D0 number of frames to be used
65
66#define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms)
67
68#define IS31_REG_DISPLAYOPT 0x05
69#define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames
70#define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x8
71// D2:D0 bits blink period time (*0.27s)
72
73#define IS31_REG_AUDIOSYNC 0x06
74#define IS31_REG_AUDIOSYNC_ENABLE 0x1
75
76#define IS31_REG_FRAMESTATE 0x07
77
78#define IS31_REG_BREATHCTRL1 0x08
79// D6:D4 fade out time (26ms*2^i)
80// D2:D0 fade in time (26ms*2^i)
81
82#define IS31_REG_BREATHCTRL2 0x09
83#define IS31_REG_BREATHCTRL2_ENABLE 0x10
84// D2:D0 extinguish time (3.5ms*2^i)
85
86#define IS31_REG_SHUTDOWN 0x0A
87#define IS31_REG_SHUTDOWN_OFF 0x0
88#define IS31_REG_SHUTDOWN_ON 0x1
89
90#define IS31_REG_AGCCTRL 0x0B
91#define IS31_REG_ADCRATE 0x0C
92
93#define IS31_COMMANDREGISTER 0xFD
94#define IS31_FUNCTIONREG 0x0B // helpfully called 'page nine'
95#define IS31_FUNCTIONREG_SIZE 0xD
96
97#define IS31_FRAME_SIZE 0xB4
98
99#define IS31_PWM_REG 0x24
100#define IS31_PWM_SIZE 0x90
101
102#define IS31_LED_MASK_SIZE 0x12
103#define IS31_SCREEN_WIDTH 16
104
105#define IS31
106
107/*===========================================================================*/
108/* Driver local functions. */
109/*===========================================================================*/
110
111typedef struct{
112 uint8_t write_buffer_offset;
113 uint8_t write_buffer[IS31_FRAME_SIZE];
114 uint8_t frame_buffer[GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH];
115 uint8_t page;
116}__attribute__((__packed__)) PrivData;
117
118// Some common routines and macros
119#define PRIV(g) ((PrivData*)g->priv)
120
121/*===========================================================================*/
122/* Driver exported functions. */
123/*===========================================================================*/
124
125static GFXINLINE void write_page(GDisplay* g, uint8_t page) {
126 uint8_t tx[2] __attribute__((aligned(2)));
127 tx[0] = IS31_COMMANDREGISTER;
128 tx[1] = page;
129 write_data(g, tx, 2);
130}
131
132static GFXINLINE void write_register(GDisplay* g, uint8_t page, uint8_t reg, uint8_t data) {
133 uint8_t tx[2] __attribute__((aligned(2)));
134 tx[0] = reg;
135 tx[1] = data;
136 write_page(g, page);
137 write_data(g, tx, 2);
138}
139
140static GFXINLINE void write_ram(GDisplay *g, uint8_t page, uint16_t offset, uint16_t length) {
141 PRIV(g)->write_buffer_offset = offset;
142 write_page(g, page);
143 write_data(g, (uint8_t*)PRIV(g), length + 1);
144}
145
146LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
147 // The private area is the display surface.
148 g->priv = gfxAlloc(sizeof(PrivData));
149 __builtin_memset(PRIV(g), 0, sizeof(PrivData));
150 PRIV(g)->page = 0;
151
152 // Initialise the board interface
153 init_board(g);
154 gfxSleepMilliseconds(10);
155
156 // zero function page, all registers (assuming full_page is all zeroes)
157 write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE);
158 set_hardware_shutdown(g, false);
159 gfxSleepMilliseconds(10);
160 // software shutdown
161 write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
162 gfxSleepMilliseconds(10);
163 // zero function page, all registers
164 write_ram(g, IS31_FUNCTIONREG, 0, IS31_FUNCTIONREG_SIZE);
165 gfxSleepMilliseconds(10);
166
167
168 // zero all LED registers on all 8 pages, and enable the mask
169 __builtin_memcpy(PRIV(g)->write_buffer, get_led_mask(g), IS31_LED_MASK_SIZE);
170 for(uint8_t i=0; i<8; i++) {
171 write_ram(g, i, 0, IS31_FRAME_SIZE);
172 gfxSleepMilliseconds(1);
173 }
174
175 // software shutdown disable (i.e. turn stuff on)
176 write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
177 gfxSleepMilliseconds(10);
178
179 // Finish Init
180 post_init_board(g);
181
182 /* Initialise the GDISP structure */
183 g->g.Width = GDISP_SCREEN_WIDTH;
184 g->g.Height = GDISP_SCREEN_HEIGHT;
185 g->g.Orientation = GDISP_ROTATE_0;
186 g->g.Powermode = powerOff;
187 g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
188 g->g.Contrast = GDISP_INITIAL_CONTRAST;
189 return TRUE;
190}
191
192#if GDISP_HARDWARE_FLUSH
193 LLDSPEC void gdisp_lld_flush(GDisplay *g) {
194 // Don't flush if we don't need it.
195 if (!(g->flags & GDISP_FLG_NEEDFLUSH))
196 return;
197
198 PRIV(g)->page++;
199 PRIV(g)->page %= 2;
200 // TODO: some smarter algorithm for this
201 // We should run only one physical page at a time
202 // This way we don't need to send so much data, and
203 // we could use slightly less memory
204 uint8_t* src = PRIV(g)->frame_buffer;
205 for (int y=0;y<GDISP_SCREEN_HEIGHT;y++) {
206 for (int x=0;x<GDISP_SCREEN_WIDTH;x++) {
207 uint8_t val = (uint16_t)*src * g->g.Backlight / 100;
208 PRIV(g)->write_buffer[get_led_address(g, x, y)]=CIE1931_CURVE[val];
209 ++src;
210 }
211 }
212 write_ram(g, PRIV(g)->page, IS31_PWM_REG, IS31_PWM_SIZE);
213 gfxSleepMilliseconds(1);
214 write_register(g, IS31_FUNCTIONREG, IS31_REG_PICTDISP, PRIV(g)->page);
215
216 g->flags &= ~GDISP_FLG_NEEDFLUSH;
217 }
218#endif
219
220#if GDISP_HARDWARE_DRAWPIXEL
221 LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
222 coord_t x, y;
223
224 switch(g->g.Orientation) {
225 default:
226 case GDISP_ROTATE_0:
227 x = g->p.x;
228 y = g->p.y;
229 break;
230 case GDISP_ROTATE_180:
231 x = GDISP_SCREEN_WIDTH-1 - g->p.x;
232 y = g->p.y;
233 break;
234 }
235 PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x] = gdispColor2Native(g->p.color);
236 g->flags |= GDISP_FLG_NEEDFLUSH;
237 }
238#endif
239
240#if GDISP_HARDWARE_PIXELREAD
241 LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
242 coord_t x, y;
243
244 switch(g->g.Orientation) {
245 default:
246 case GDISP_ROTATE_0:
247 x = g->p.x;
248 y = g->p.y;
249 break;
250 case GDISP_ROTATE_180:
251 x = GDISP_SCREEN_WIDTH-1 - g->p.x;
252 y = g->p.y;
253 break;
254 }
255 return gdispNative2Color(PRIV(g)->frame_buffer[y * GDISP_SCREEN_WIDTH + x]);
256 }
257#endif
258
259#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
260 LLDSPEC void gdisp_lld_control(GDisplay *g) {
261 switch(g->p.x) {
262 case GDISP_CONTROL_POWER:
263 if (g->g.Powermode == (powermode_t)g->p.ptr)
264 return;
265 switch((powermode_t)g->p.ptr) {
266 case powerOff:
267 case powerSleep:
268 case powerDeepSleep:
269 write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
270 break;
271 case powerOn:
272 write_register(g, IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON);
273 break;
274 default:
275 return;
276 }
277 g->g.Powermode = (powermode_t)g->p.ptr;
278 return;
279
280 case GDISP_CONTROL_ORIENTATION:
281 if (g->g.Orientation == (orientation_t)g->p.ptr)
282 return;
283 switch((orientation_t)g->p.ptr) {
284 /* Rotation is handled by the drawing routines */
285 case GDISP_ROTATE_0:
286 case GDISP_ROTATE_180:
287 g->g.Height = GDISP_SCREEN_HEIGHT;
288 g->g.Width = GDISP_SCREEN_WIDTH;
289 break;
290 case GDISP_ROTATE_90:
291 case GDISP_ROTATE_270:
292 g->g.Height = GDISP_SCREEN_WIDTH;
293 g->g.Width = GDISP_SCREEN_HEIGHT;
294 break;
295 default:
296 return;
297 }
298 g->g.Orientation = (orientation_t)g->p.ptr;
299 return;
300
301 case GDISP_CONTROL_BACKLIGHT:
302 if (g->g.Backlight == (unsigned)g->p.ptr)
303 return;
304 unsigned val = (unsigned)g->p.ptr;
305 g->g.Backlight = val > 100 ? 100 : val;
306 g->flags |= GDISP_FLG_NEEDFLUSH;
307 return;
308 }
309 }
310#endif // GDISP_NEED_CONTROL
311
312#endif // GFX_USE_GDISP
diff --git a/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h
new file mode 100644
index 000000000..bb28ad775
--- /dev/null
+++ b/keyboards/whitefox/drivers/gdisp/IS31FL3731C/gdisp_lld_config.h
@@ -0,0 +1,36 @@
1/*
2Copyright 2016 Fred Sundvik <fsundvik@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#ifndef _GDISP_LLD_CONFIG_H
19#define _GDISP_LLD_CONFIG_H
20
21#if GFX_USE_GDISP
22
23/*===========================================================================*/
24/* Driver hardware support. */
25/*===========================================================================*/
26
27#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing
28#define GDISP_HARDWARE_DRAWPIXEL TRUE
29#define GDISP_HARDWARE_PIXELREAD TRUE
30#define GDISP_HARDWARE_CONTROL TRUE
31
32#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_GRAY256
33
34#endif /* GFX_USE_GDISP */
35
36#endif /* _GDISP_LLD_CONFIG_H */
diff --git a/keyboards/whitefox/gfxconf.h b/keyboards/whitefox/gfxconf.h
new file mode 100644
index 000000000..890317a0f
--- /dev/null
+++ b/keyboards/whitefox/gfxconf.h
@@ -0,0 +1,329 @@
1/**
2 * This file has a different license to the rest of the uGFX system.
3 * You can copy, modify and distribute this file as you see fit.
4 * You do not need to publish your source modifications to this file.
5 * The only thing you are not permitted to do is to relicense it
6 * under a different license.
7 */
8
9/**
10 * Copy this file into your project directory and rename it as gfxconf.h
11 * Edit your copy to turn on the uGFX features you want to use.
12 * The values below are the defaults.
13 *
14 * Only remove the comments from lines where you want to change the
15 * default value. This allows definitions to be included from
16 * driver makefiles when required and provides the best future
17 * compatibility for your project.
18 *
19 * Please use spaces instead of tabs in this file.
20 */
21
22#ifndef _GFXCONF_H
23#define _GFXCONF_H
24
25
26///////////////////////////////////////////////////////////////////////////
27// GOS - One of these must be defined, preferably in your Makefile //
28///////////////////////////////////////////////////////////////////////////
29//#define GFX_USE_OS_CHIBIOS TRUE
30//#define GFX_USE_OS_FREERTOS FALSE
31// #define GFX_FREERTOS_USE_TRACE FALSE
32//#define GFX_USE_OS_WIN32 FALSE
33//#define GFX_USE_OS_LINUX FALSE
34//#define GFX_USE_OS_OSX FALSE
35//#define GFX_USE_OS_ECOS FALSE
36//#define GFX_USE_OS_RAWRTOS FALSE
37//#define GFX_USE_OS_ARDUINO FALSE
38//#define GFX_USE_OS_KEIL FALSE
39//#define GFX_USE_OS_CMSIS FALSE
40//#define GFX_USE_OS_RAW32 FALSE
41// #define INTERRUPTS_OFF() optional_code
42// #define INTERRUPTS_ON() optional_code
43// These are not defined by default for some reason
44#define GOS_NEED_X_THREADS FALSE
45#define GOS_NEED_X_HEAP FALSE
46
47// Options that (should where relevant) apply to all operating systems
48 #define GFX_NO_INLINE FALSE
49// #define GFX_COMPILER GFX_COMPILER_UNKNOWN
50// #define GFX_CPU GFX_CPU_UNKNOWN
51// #define GFX_OS_HEAP_SIZE 0
52// #define GFX_OS_NO_INIT FALSE
53// #define GFX_OS_INIT_NO_WARNING FALSE
54// #define GFX_OS_PRE_INIT_FUNCTION myHardwareInitRoutine
55// #define GFX_OS_EXTRA_INIT_FUNCTION myOSInitRoutine
56// #define GFX_OS_EXTRA_DEINIT_FUNCTION myOSDeInitRoutine
57
58
59///////////////////////////////////////////////////////////////////////////
60// GDISP //
61///////////////////////////////////////////////////////////////////////////
62#define GFX_USE_GDISP TRUE
63
64//#define GDISP_NEED_AUTOFLUSH FALSE
65//#define GDISP_NEED_TIMERFLUSH FALSE
66//#define GDISP_NEED_VALIDATION TRUE
67//#define GDISP_NEED_CLIP TRUE
68#define GDISP_NEED_CIRCLE TRUE
69#define GDISP_NEED_ELLIPSE TRUE
70#define GDISP_NEED_ARC TRUE
71#define GDISP_NEED_ARCSECTORS TRUE
72#define GDISP_NEED_CONVEX_POLYGON TRUE
73//#define GDISP_NEED_SCROLL FALSE
74#define GDISP_NEED_PIXELREAD TRUE
75#define GDISP_NEED_CONTROL TRUE
76//#define GDISP_NEED_QUERY FALSE
77//#define GDISP_NEED_MULTITHREAD FALSE
78//#define GDISP_NEED_STREAMING FALSE
79#define GDISP_NEED_TEXT TRUE
80// #define GDISP_NEED_TEXT_WORDWRAP FALSE
81// #define GDISP_NEED_ANTIALIAS FALSE
82// #define GDISP_NEED_UTF8 FALSE
83 #define GDISP_NEED_TEXT_KERNING TRUE
84// #define GDISP_INCLUDE_FONT_UI1 FALSE
85// #define GDISP_INCLUDE_FONT_UI2 FALSE // The smallest preferred font.
86// #define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
87// #define GDISP_INCLUDE_FONT_DEJAVUSANS10 FALSE
88// #define GDISP_INCLUDE_FONT_DEJAVUSANS12 FALSE
89// #define GDISP_INCLUDE_FONT_DEJAVUSANS16 FALSE
90// #define GDISP_INCLUDE_FONT_DEJAVUSANS20 FALSE
91// #define GDISP_INCLUDE_FONT_DEJAVUSANS24 FALSE
92// #define GDISP_INCLUDE_FONT_DEJAVUSANS32 FALSE
93 #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12 TRUE
94// #define GDISP_INCLUDE_FONT_FIXED_10X20 FALSE
95// #define GDISP_INCLUDE_FONT_FIXED_7X14 FALSE
96 #define GDISP_INCLUDE_FONT_FIXED_5X8 TRUE
97// #define GDISP_INCLUDE_FONT_DEJAVUSANS12_AA FALSE
98// #define GDISP_INCLUDE_FONT_DEJAVUSANS16_AA FALSE
99// #define GDISP_INCLUDE_FONT_DEJAVUSANS20_AA FALSE
100// #define GDISP_INCLUDE_FONT_DEJAVUSANS24_AA FALSE
101// #define GDISP_INCLUDE_FONT_DEJAVUSANS32_AA FALSE
102// #define GDISP_INCLUDE_FONT_DEJAVUSANSBOLD12_AA FALSE
103// #define GDISP_INCLUDE_USER_FONTS FALSE
104
105//#define GDISP_NEED_IMAGE FALSE
106// #define GDISP_NEED_IMAGE_NATIVE FALSE
107// #define GDISP_NEED_IMAGE_GIF FALSE
108// #define GDISP_NEED_IMAGE_BMP FALSE
109// #define GDISP_NEED_IMAGE_BMP_1 FALSE
110// #define GDISP_NEED_IMAGE_BMP_4 FALSE
111// #define GDISP_NEED_IMAGE_BMP_4_RLE FALSE
112// #define GDISP_NEED_IMAGE_BMP_8 FALSE
113// #define GDISP_NEED_IMAGE_BMP_8_RLE FALSE
114// #define GDISP_NEED_IMAGE_BMP_16 FALSE
115// #define GDISP_NEED_IMAGE_BMP_24 FALSE
116// #define GDISP_NEED_IMAGE_BMP_32 FALSE
117// #define GDISP_NEED_IMAGE_JPG FALSE
118// #define GDISP_NEED_IMAGE_PNG FALSE
119// #define GDISP_NEED_IMAGE_ACCOUNTING FALSE
120#ifdef EMULATOR
121#define GDISP_NEED_PIXMAP TRUE
122#endif
123// #define GDISP_NEED_PIXMAP_IMAGE FALSE
124
125//#define GDISP_DEFAULT_ORIENTATION GDISP_ROTATE_LANDSCAPE // If not defined the native hardware orientation is used.
126//#define GDISP_LINEBUF_SIZE 128
127//#define GDISP_STARTUP_COLOR Black
128#define GDISP_NEED_STARTUP_LOGO FALSE
129
130//#define GDISP_TOTAL_DISPLAYS 2
131
132#ifndef EMULATOR
133#define GDISP_DRIVER_LIST GDISPVMT_IS31FL3731C_WHITEFOX
134#endif
135
136 #ifdef GDISP_DRIVER_LIST
137 // For code and speed optimization define as TRUE or FALSE if all controllers have the same capability
138 #define GDISP_HARDWARE_STREAM_WRITE FALSE
139 #define GDISP_HARDWARE_STREAM_READ FALSE
140 #define GDISP_HARDWARE_STREAM_POS FALSE
141 #define GDISP_HARDWARE_DRAWPIXEL TRUE
142 #define GDISP_HARDWARE_CLEARS FALSE
143 #define GDISP_HARDWARE_FILLS FALSE
144 //#define GDISP_HARDWARE_BITFILLS FALSE
145 #define GDISP_HARDWARE_SCROLL FALSE
146 #define GDISP_HARDWARE_PIXELREAD TRUE
147 #define GDISP_HARDWARE_CONTROL TRUE
148 #define GDISP_HARDWARE_QUERY FALSE
149 #define GDISP_HARDWARE_CLIP FALSE
150
151 #define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB888
152 #endif
153
154// The custom format is not defined for some reason, so define it as error
155// so we don't get compiler warnings
156#define GDISP_PIXELFORMAT_CUSTOM GDISP_PIXELFORMAT_ERROR
157
158#define GDISP_USE_GFXNET FALSE
159// #define GDISP_GFXNET_PORT 13001
160// #define GDISP_GFXNET_CUSTOM_LWIP_STARTUP FALSE
161// #define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE
162// #define GDISP_GFXNET_UNSAFE_SOCKETS FALSE
163
164
165///////////////////////////////////////////////////////////////////////////
166// GWIN //
167///////////////////////////////////////////////////////////////////////////
168#define GFX_USE_GWIN FALSE
169
170//#define GWIN_NEED_WINDOWMANAGER FALSE
171// #define GWIN_REDRAW_IMMEDIATE FALSE
172// #define GWIN_REDRAW_SINGLEOP FALSE
173// #define GWIN_NEED_FLASHING FALSE
174// #define GWIN_FLASHING_PERIOD 250
175
176//#define GWIN_NEED_CONSOLE FALSE
177// #define GWIN_CONSOLE_USE_HISTORY FALSE
178// #define GWIN_CONSOLE_HISTORY_AVERAGING FALSE
179// #define GWIN_CONSOLE_HISTORY_ATCREATE FALSE
180// #define GWIN_CONSOLE_ESCSEQ FALSE
181// #define GWIN_CONSOLE_USE_BASESTREAM FALSE
182// #define GWIN_CONSOLE_USE_FLOAT FALSE
183//#define GWIN_NEED_GRAPH FALSE
184//#define GWIN_NEED_GL3D FALSE
185
186//#define GWIN_NEED_WIDGET FALSE
187//#define GWIN_FOCUS_HIGHLIGHT_WIDTH 1
188// #define GWIN_NEED_LABEL FALSE
189// #define GWIN_LABEL_ATTRIBUTE FALSE
190// #define GWIN_NEED_BUTTON FALSE
191// #define GWIN_BUTTON_LAZY_RELEASE FALSE
192// #define GWIN_NEED_SLIDER FALSE
193// #define GWIN_SLIDER_NOSNAP FALSE
194// #define GWIN_SLIDER_DEAD_BAND 5
195// #define GWIN_SLIDER_TOGGLE_INC 20
196// #define GWIN_NEED_CHECKBOX FALSE
197// #define GWIN_NEED_IMAGE FALSE
198// #define GWIN_NEED_IMAGE_ANIMATION FALSE
199// #define GWIN_NEED_RADIO FALSE
200// #define GWIN_NEED_LIST FALSE
201// #define GWIN_NEED_LIST_IMAGES FALSE
202// #define GWIN_NEED_PROGRESSBAR FALSE
203// #define GWIN_PROGRESSBAR_AUTO FALSE
204// #define GWIN_NEED_KEYBOARD FALSE
205// #define GWIN_KEYBOARD_DEFAULT_LAYOUT VirtualKeyboard_English1
206// #define GWIN_NEED_KEYBOARD_ENGLISH1 TRUE
207// #define GWIN_NEED_TEXTEDIT FALSE
208// #define GWIN_FLAT_STYLING FALSE
209// #define GWIN_WIDGET_TAGS FALSE
210
211//#define GWIN_NEED_CONTAINERS FALSE
212// #define GWIN_NEED_CONTAINER FALSE
213// #define GWIN_NEED_FRAME FALSE
214// #define GWIN_NEED_TABSET FALSE
215// #define GWIN_TABSET_TABHEIGHT 18
216
217
218///////////////////////////////////////////////////////////////////////////
219// GEVENT //
220///////////////////////////////////////////////////////////////////////////
221#define GFX_USE_GEVENT TRUE
222
223//#define GEVENT_ASSERT_NO_RESOURCE FALSE
224//#define GEVENT_MAXIMUM_SIZE 32
225//#define GEVENT_MAX_SOURCE_LISTENERS 32
226
227
228///////////////////////////////////////////////////////////////////////////
229// GTIMER //
230///////////////////////////////////////////////////////////////////////////
231#define GFX_USE_GTIMER FALSE
232
233//#define GTIMER_THREAD_PRIORITY HIGH_PRIORITY
234//#define GTIMER_THREAD_WORKAREA_SIZE 2048
235
236
237///////////////////////////////////////////////////////////////////////////
238// GQUEUE //
239///////////////////////////////////////////////////////////////////////////
240#define GFX_USE_GQUEUE FALSE
241
242//#define GQUEUE_NEED_ASYNC FALSE
243//#define GQUEUE_NEED_GSYNC FALSE
244//#define GQUEUE_NEED_FSYNC FALSE
245//#define GQUEUE_NEED_BUFFERS FALSE
246
247///////////////////////////////////////////////////////////////////////////
248// GINPUT //
249///////////////////////////////////////////////////////////////////////////
250#define GFX_USE_GINPUT FALSE
251
252//#define GINPUT_NEED_MOUSE FALSE
253// #define GINPUT_TOUCH_STARTRAW FALSE
254// #define GINPUT_TOUCH_NOTOUCH FALSE
255// #define GINPUT_TOUCH_NOCALIBRATE FALSE
256// #define GINPUT_TOUCH_NOCALIBRATE_GUI FALSE
257// #define GINPUT_MOUSE_POLL_PERIOD 25
258// #define GINPUT_MOUSE_CLICK_TIME 300
259// #define GINPUT_TOUCH_CXTCLICK_TIME 700
260// #define GINPUT_TOUCH_USER_CALIBRATION_LOAD FALSE
261// #define GINPUT_TOUCH_USER_CALIBRATION_SAVE FALSE
262// #define GMOUSE_DRIVER_LIST GMOUSEVMT_Win32, GMOUSEVMT_Win32
263//#define GINPUT_NEED_KEYBOARD FALSE
264// #define GINPUT_KEYBOARD_POLL_PERIOD 200
265// #define GKEYBOARD_DRIVER_LIST GKEYBOARDVMT_Win32, GKEYBOARDVMT_Win32
266// #define GKEYBOARD_LAYOUT_OFF FALSE
267// #define GKEYBOARD_LAYOUT_SCANCODE2_US FALSE
268//#define GINPUT_NEED_TOGGLE FALSE
269//#define GINPUT_NEED_DIAL FALSE
270
271
272///////////////////////////////////////////////////////////////////////////
273// GFILE //
274///////////////////////////////////////////////////////////////////////////
275#define GFX_USE_GFILE FALSE
276
277//#define GFILE_NEED_PRINTG FALSE
278//#define GFILE_NEED_SCANG FALSE
279//#define GFILE_NEED_STRINGS FALSE
280//#define GFILE_NEED_FILELISTS FALSE
281//#define GFILE_NEED_STDIO FALSE
282//#define GFILE_NEED_NOAUTOMOUNT FALSE
283//#define GFILE_NEED_NOAUTOSYNC FALSE
284
285//#define GFILE_NEED_MEMFS FALSE
286//#define GFILE_NEED_ROMFS FALSE
287//#define GFILE_NEED_RAMFS FALSE
288//#define GFILE_NEED_FATFS FALSE
289//#define GFILE_NEED_NATIVEFS FALSE
290//#define GFILE_NEED_CHBIOSFS FALSE
291
292//#define GFILE_ALLOW_FLOATS FALSE
293//#define GFILE_ALLOW_DEVICESPECIFIC FALSE
294//#define GFILE_MAX_GFILES 3
295
296///////////////////////////////////////////////////////////////////////////
297// GADC //
298///////////////////////////////////////////////////////////////////////////
299#define GFX_USE_GADC FALSE
300
301//#define GADC_MAX_LOWSPEED_DEVICES 4
302
303
304///////////////////////////////////////////////////////////////////////////
305// GAUDIO //
306///////////////////////////////////////////////////////////////////////////
307#define GFX_USE_GAUDIO FALSE
308// There seems to be a bug in the ugfx code, the wrong define is used
309// So define it in order to avoid warnings
310#define GFX_USE_GAUDIN GFX_USE_GAUDIO
311// #define GAUDIO_NEED_PLAY FALSE
312// #define GAUDIO_NEED_RECORD FALSE
313
314
315///////////////////////////////////////////////////////////////////////////
316// GMISC //
317///////////////////////////////////////////////////////////////////////////
318#define GFX_USE_GMISC TRUE
319
320//#define GMISC_NEED_ARRAYOPS FALSE
321//#define GMISC_NEED_FASTTRIG FALSE
322//#define GMISC_NEED_FIXEDTRIG FALSE
323//#define GMISC_NEED_INVSQRT FALSE
324// #define GMISC_INVSQRT_MIXED_ENDIAN FALSE
325// #define GMISC_INVSQRT_REAL_SLOW FALSE
326#define GMISC_NEED_MATRIXFLOAT2D TRUE
327#define GMISC_NEED_MATRIXFIXED2D FALSE
328
329#endif /* _GFXCONF_H */
diff --git a/keyboards/whitefox/halconf.h b/keyboards/whitefox/halconf.h
index 46b37a4f4..b38031529 100644
--- a/keyboards/whitefox/halconf.h
+++ b/keyboards/whitefox/halconf.h
@@ -76,7 +76,7 @@
76 * @brief Enables the I2C subsystem. 76 * @brief Enables the I2C subsystem.
77 */ 77 */
78#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) 78#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
79#define HAL_USE_I2C FALSE 79#define HAL_USE_I2C TRUE
80#endif 80#endif
81 81
82/** 82/**
diff --git a/keyboards/whitefox/keymaps/jetpacktuxedo/Makefile b/keyboards/whitefox/keymaps/jetpacktuxedo/Makefile
new file mode 100644
index 000000000..8eb483103
--- /dev/null
+++ b/keyboards/whitefox/keymaps/jetpacktuxedo/Makefile
@@ -0,0 +1,5 @@
1ifndef QUANTUM_DIR
2 include ../../../Makefile
3endif
4
5BACKLIGHT_ENABLE = yes
diff --git a/keyboards/whitefox/keymaps/jetpacktuxedo/keymap.c b/keyboards/whitefox/keymaps/jetpacktuxedo/keymap.c
index 09f6ca34d..82de17173 100644
--- a/keyboards/whitefox/keymaps/jetpacktuxedo/keymap.c
+++ b/keyboards/whitefox/keymaps/jetpacktuxedo/keymap.c
@@ -31,11 +31,11 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
31 * `---------------------------------------------------------------' 31 * `---------------------------------------------------------------'
32 */ 32 */
33 [0] = KEYMAP( \ 33 [0] = KEYMAP( \
34 KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,KC_EQL,KC_NO,KC_BSPC,KC_INS, \ 34 KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,KC_EQL,KC_NO,KC_BSPC,KC_INS, \
35 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,KC_RBRC, KC_BSLS, KC_DEL, \ 35 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,KC_RBRC, KC_BSLS, KC_DEL, \
36 MO(1), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT,KC_NUHS, KC_ENT, KC_PGUP,\ 36 MO(1), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT,KC_NUHS, KC_ENT, KC_PGUP,\
37 KC_LSFT,KC_NUBS,KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,\ 37 KC_LSFT, KC_NUBS,KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_PGDN,\
38 KC_LCTL,KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RCTL,KC_NO, KC_LEFT,KC_DOWN,KC_RGHT \ 38 KC_LCTL, KC_LGUI,KC_LALT, KC_SPC, KC_RALT,KC_RCTL,KC_NO, KC_LEFT,KC_DOWN,KC_RGHT \
39 ), 39 ),
40 /* Layer 1: FN Layer 40 /* Layer 1: FN Layer
41 * ,---------------------------------------------------------------. 41 * ,---------------------------------------------------------------.
@@ -52,8 +52,8 @@ const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
52 */ 52 */
53 [1] = KEYMAP( \ 53 [1] = KEYMAP( \
54 KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS,KC_TRNS,KC_MUTE,\ 54 KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS,KC_TRNS,KC_MUTE,\
55 KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_PSCR,KC_SLCK,KC_PAUS,KC_TRNS, KC_TRNS,\ 55 KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,BL_TOGG,KC_TRNS,KC_TRNS,BL_INC, KC_TRNS,KC_PSCR,KC_SLCK,KC_PAUS,KC_TRNS, KC_TRNS,\
56 KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_VOLU,\ 56 KC_TRNS,KC_TRNS,KC_TRNS,BL_DEC, KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_VOLU,\
57 KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_PGUP,KC_VOLD,\ 57 KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_PGUP,KC_VOLD,\
58 KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_HOME,KC_PGDN,KC_END \ 58 KC_TRNS,KC_TRNS,KC_TRNS, KC_TRNS, KC_TRNS,KC_TRNS,KC_TRNS, KC_HOME,KC_PGDN,KC_END \
59 ), 59 ),
diff --git a/keyboards/whitefox/rules.mk b/keyboards/whitefox/rules.mk
index 18b690f49..565381e16 100644
--- a/keyboards/whitefox/rules.mk
+++ b/keyboards/whitefox/rules.mk
@@ -1,6 +1,7 @@
1# project specific files 1# project specific files
2SRC = matrix.c \ 2SRC = matrix.c \
3 led.c 3 led.c \
4 animations.c
4 5
5## chip/board settings 6## chip/board settings
6# - the next two should match the directories in 7# - the next two should match the directories in
@@ -66,3 +67,7 @@ COMMAND_ENABLE ?= yes # Commands for debug and configuration
66#SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend 67#SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend
67NKRO_ENABLE ?= yes # USB Nkey Rollover 68NKRO_ENABLE ?= yes # USB Nkey Rollover
68CUSTOM_MATRIX ?= yes # Custom matrix file 69CUSTOM_MATRIX ?= yes # Custom matrix file
70BACKLIGHT_ENABLE ?= yes
71VISUALIZER_ENABLE ?= yes
72
73include $(KEYBOARD_PATH)/drivers/gdisp/IS31FL3731C/driver.mk
diff --git a/keyboards/whitefox/visualizer.c b/keyboards/whitefox/visualizer.c
new file mode 100644
index 000000000..167e0ec4d
--- /dev/null
+++ b/keyboards/whitefox/visualizer.c
@@ -0,0 +1,60 @@
1/* Copyright 2017 Fred Sundvik
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef KEYBOARDS_WHITEFOX_SIMPLE_VISUALIZER_H_
18#define KEYBOARDS_WHITEFOX_SIMPLE_VISUALIZER_H_
19
20#include "visualizer.h"
21#include "visualizer_keyframes.h"
22#include "led.h"
23#include "animations.h"
24
25
26static bool initial_update = true;
27
28// Feel free to modify the animations below, or even add new ones if needed
29
30void initialize_user_visualizer(visualizer_state_t* state) {
31 // The brightness will be dynamically adjustable in the future
32 // But for now, change it here.
33 initial_update = true;
34 start_keyframe_animation(&default_startup_animation);
35}
36
37
38void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) {
39 // Add more tests, change the colors and layer texts here
40 // Usually you want to check the high bits (higher layers first)
41 // because that's the order layers are processed for keypresses
42 // You can for check for example:
43 // state->status.layer
44 // state->status.default_layer
45 // state->status.leds (see led.h for available statuses)
46
47 if (initial_update) { initial_update=false; start_keyframe_animation(&led_test_animation); }
48}
49
50
51void user_visualizer_suspend(visualizer_state_t* state) {
52 start_keyframe_animation(&default_suspend_animation);
53}
54
55void user_visualizer_resume(visualizer_state_t* state) {
56 initial_update = true;
57 start_keyframe_animation(&default_startup_animation);
58}
59
60#endif /* KEYBOARDS_WHITEFOX_SIMPLE_VISUALIZER_H_ */
diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c
index 4f7bc525e..eb39c8fe0 100644
--- a/quantum/keycode_config.c
+++ b/quantum/keycode_config.c
@@ -88,3 +88,31 @@ uint16_t keycode_config(uint16_t keycode) {
88 return keycode; 88 return keycode;
89 } 89 }
90} 90}
91
92uint8_t mod_config(uint8_t mod) {
93 keymap_config.raw = eeconfig_read_keymap();
94 if (keymap_config.swap_lalt_lgui) {
95 if ((mod & MOD_RGUI) == MOD_LGUI) {
96 mod &= ~MOD_LGUI;
97 mod |= MOD_LALT;
98 } else if ((mod & MOD_RALT) == MOD_LALT) {
99 mod &= ~MOD_LALT;
100 mod |= MOD_LGUI;
101 }
102 }
103 if (keymap_config.swap_ralt_rgui) {
104 if ((mod & MOD_RGUI) == MOD_RGUI) {
105 mod &= ~MOD_RGUI;
106 mod |= MOD_RALT;
107 } else if ((mod & MOD_RALT) == MOD_RALT) {
108 mod &= ~MOD_RALT;
109 mod |= MOD_RGUI;
110 }
111 }
112 if (keymap_config.no_gui) {
113 mod &= ~MOD_LGUI;
114 mod &= ~MOD_RGUI;
115 }
116
117 return mod;
118} \ No newline at end of file
diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h
index 293fefecf..022f4bd19 100644
--- a/quantum/keycode_config.h
+++ b/quantum/keycode_config.h
@@ -16,11 +16,13 @@
16 16
17#include "eeconfig.h" 17#include "eeconfig.h"
18#include "keycode.h" 18#include "keycode.h"
19#include "action_code.h"
19 20
20#ifndef KEYCODE_CONFIG_H 21#ifndef KEYCODE_CONFIG_H
21#define KEYCODE_CONFIG_H 22#define KEYCODE_CONFIG_H
22 23
23uint16_t keycode_config(uint16_t keycode); 24uint16_t keycode_config(uint16_t keycode);
25uint8_t mod_config(uint8_t mod);
24 26
25/* NOTE: Not portable. Bit field order depends on implementation */ 27/* NOTE: Not portable. Bit field order depends on implementation */
26typedef union { 28typedef union {
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c
index 9dafc8b51..b1460c53c 100644
--- a/quantum/keymap_common.c
+++ b/quantum/keymap_common.c
@@ -123,7 +123,8 @@ action_t action_for_key(uint8_t layer, keypos_t key)
123 action.code = ACTION_LAYER_TAP_TOGGLE(keycode & 0xFF); 123 action.code = ACTION_LAYER_TAP_TOGGLE(keycode & 0xFF);
124 break; 124 break;
125 case QK_MOD_TAP ... QK_MOD_TAP_MAX: 125 case QK_MOD_TAP ... QK_MOD_TAP_MAX:
126 action.code = ACTION_MODS_TAP_KEY((keycode >> 0x8) & 0x1F, keycode & 0xFF); 126 mod = mod_config((keycode >> 0x8) & 0x1F);
127 action.code = ACTION_MODS_TAP_KEY(mod, keycode & 0xFF);
127 break; 128 break;
128 #ifdef BACKLIGHT_ENABLE 129 #ifdef BACKLIGHT_ENABLE
129 case BL_0 ... BL_15: 130 case BL_0 ... BL_15:
diff --git a/quantum/keymap_extras/keymap_swedish.h b/quantum/keymap_extras/keymap_swedish.h
new file mode 100644
index 000000000..dcfad720d
--- /dev/null
+++ b/quantum/keymap_extras/keymap_swedish.h
@@ -0,0 +1,52 @@
1/* Copyright 2017 Andreas Lindhé
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef KEYMAP_SWEDISH_H
18#define KEYMAP_SWEDISH_H
19
20#include "keymap_nordic.h"
21
22// There are slight differrences in the keyboards in the nordic contries
23
24// Swedish redifinitions from the nordic keyset
25#undef NO_AE
26#define NO_AE KC_QUOT // ä
27#undef NO_CIRC
28#define NO_CIRC LSFT(KC_RBRC) // ^
29#undef NO_GRV
30#define NO_GRV LSFT(NO_BSLS) //
31#undef NO_OSLH
32#define NO_OSLH KC_SCLN // ö
33
34// Additional Swedish keys not defined in the nordic keyset
35#define NO_AA KC_LBRC // å
36#define NO_ASTR LSFT(KC_BSLS) // *
37
38// Norwegian unique MAC characters (not vetted for Swedish)
39#define NO_ACUT_MAC KC_EQL // =
40#define NO_APOS_MAC KC_NUBS // '
41#define NO_AT_MAC KC_BSLS // @
42#define NO_BSLS_MAC ALGR(LSFT(KC_7)) // '\'
43#define NO_DLR_MAC LSFT(KC_4) // $
44#define NO_GRV_MAC ALGR(NO_BSLS) // `
45#define NO_GRTR_MAC LSFT(KC_GRV) // >
46#define NO_LCBR_MAC ALGR(LSFT(KC_8)) // }
47#define NO_LESS_MAC KC_GRV // >
48#define NO_PIPE_MAC ALGR(KC_7) // |
49#define NO_RCBR_MAC ALGR(LSFT(KC_9)) // }
50
51#endif
52
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 3b5e52ff1..5bb7b04d5 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -530,7 +530,7 @@ void send_string(const char *str) {
530 shift = false; 530 shift = false;
531 } 531 }
532 else { 532 else {
533 int hi = ascii_code>>4 & 0x0f; 533 int hi = ascii_code>>4 & 0x0f,
534 lo = ascii_code & 0x0f; 534 lo = ascii_code & 0x0f;
535 keycode = pgm_read_byte(&ascii_to_keycode_lut[hi][lo]); 535 keycode = pgm_read_byte(&ascii_to_keycode_lut[hi][lo]);
536 shift = !!( pgm_read_word(&ascii_to_shift_lut[hi]) & (0x8000u>>lo) ); 536 shift = !!( pgm_read_word(&ascii_to_shift_lut[hi]) & (0x8000u>>lo) );
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h
index c34ecafa5..6038e31c4 100644
--- a/quantum/quantum_keycodes.h
+++ b/quantum/quantum_keycodes.h
@@ -550,13 +550,13 @@ enum quantum_keycodes {
550#define OSL(layer) (layer | QK_ONE_SHOT_LAYER) 550#define OSL(layer) (layer | QK_ONE_SHOT_LAYER)
551 551
552// One-shot mod 552// One-shot mod
553#define OSM(mod) (mod | QK_ONE_SHOT_MOD) 553#define OSM(mod) ((mod) | QK_ONE_SHOT_MOD)
554 554
555// Layer tap-toggle 555// Layer tap-toggle
556#define TT(layer) (layer | QK_LAYER_TAP_TOGGLE) 556#define TT(layer) (layer | QK_LAYER_TAP_TOGGLE)
557 557
558// M-od, T-ap - 256 keycode max 558// M-od, T-ap - 256 keycode max
559#define MT(mod, kc) (kc | QK_MOD_TAP | ((mod & 0x1F) << 8)) 559#define MT(mod, kc) (kc | QK_MOD_TAP | (((mod) & 0x1F) << 8))
560 560
561#define CTL_T(kc) MT(MOD_LCTL, kc) 561#define CTL_T(kc) MT(MOD_LCTL, kc)
562#define LCTL_T(kc) MT(MOD_LCTL, kc) 562#define LCTL_T(kc) MT(MOD_LCTL, kc)
diff --git a/quantum/visualizer/led_keyframes.c b/quantum/visualizer/led_keyframes.c
index 2f4e20043..7e6e5d1ab 100644
--- a/quantum/visualizer/led_keyframes.c
+++ b/quantum/visualizer/led_keyframes.c
@@ -41,8 +41,8 @@ static void keyframe_fade_all_leds_from_to(keyframe_animation_t* animation, uint
41} 41}
42 42
43// TODO: Should be customizable per keyboard 43// TODO: Should be customizable per keyboard
44#define NUM_ROWS 7 44#define NUM_ROWS LED_NUM_ROWS
45#define NUM_COLS 7 45#define NUM_COLS LED_NUM_COLS
46 46
47static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS]; 47static uint8_t crossfade_start_frame[NUM_ROWS][NUM_COLS];
48static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS]; 48static uint8_t crossfade_end_frame[NUM_ROWS][NUM_COLS];
diff --git a/quantum/visualizer/visualizer.c b/quantum/visualizer/visualizer.c
index a4b3ea7e4..cc99d1e3b 100644
--- a/quantum/visualizer/visualizer.c
+++ b/quantum/visualizer/visualizer.c
@@ -105,15 +105,19 @@ static remote_object_t* remote_objects[] = {
105GDisplay* LCD_DISPLAY = 0; 105GDisplay* LCD_DISPLAY = 0;
106GDisplay* LED_DISPLAY = 0; 106GDisplay* LED_DISPLAY = 0;
107 107
108#ifdef LCD_DISPLAY_NUMBER
108__attribute__((weak)) 109__attribute__((weak))
109GDisplay* get_lcd_display(void) { 110GDisplay* get_lcd_display(void) {
110 return gdispGetDisplay(0); 111 return gdispGetDisplay(LCD_DISPLAY_NUMBER);
111} 112}
113#endif
112 114
115#ifdef LED_DISPLAY_NUMBER
113__attribute__((weak)) 116__attribute__((weak))
114GDisplay* get_led_display(void) { 117GDisplay* get_led_display(void) {
115 return gdispGetDisplay(1); 118 return gdispGetDisplay(LED_DISPLAY_NUMBER);
116} 119}
120#endif
117 121
118void start_keyframe_animation(keyframe_animation_t* animation) { 122void start_keyframe_animation(keyframe_animation_t* animation) {
119 animation->current_frame = -1; 123 animation->current_frame = -1;
@@ -251,9 +255,9 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
251 .mods = 0xFF, 255 .mods = 0xFF,
252 .leds = 0xFFFFFFFF, 256 .leds = 0xFFFFFFFF,
253 .suspended = false, 257 .suspended = false,
254#ifdef VISUALIZER_USER_DATA_SIZE 258 #ifdef VISUALIZER_USER_DATA_SIZE
255 .user_data = {0}, 259 .user_data = {0},
256#endif 260 #endif
257 }; 261 };
258 262
259 visualizer_state_t state = { 263 visualizer_state_t state = {
@@ -379,25 +383,26 @@ static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
379void visualizer_init(void) { 383void visualizer_init(void) {
380 gfxInit(); 384 gfxInit();
381 385
382#ifdef LCD_BACKLIGHT_ENABLE 386 #ifdef LCD_BACKLIGHT_ENABLE
383 lcd_backlight_init(); 387 lcd_backlight_init();
384#endif 388 #endif
385 389
386#ifdef SERIAL_LINK_ENABLE 390 #ifdef SERIAL_LINK_ENABLE
387 add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*) ); 391 add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*) );
388#endif 392 #endif
389 393
390#ifdef LCD_ENABLE 394 #ifdef LCD_ENABLE
391 LCD_DISPLAY = get_lcd_display(); 395 LCD_DISPLAY = get_lcd_display();
392#endif 396 #endif
393#ifdef BACKLIGHT_ENABLE 397
398 #ifdef BACKLIGHT_ENABLE
394 LED_DISPLAY = get_led_display(); 399 LED_DISPLAY = get_led_display();
395#endif 400 #endif
396 401
397 // We are using a low priority thread, the idea is to have it run only 402 // We are using a low priority thread, the idea is to have it run only
398 // when the main thread is sleeping during the matrix scanning 403 // when the main thread is sleeping during the matrix scanning
399 gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack), 404 gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack),
400 VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL); 405 VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL);
401} 406}
402 407
403void update_status(bool changed) { 408void update_status(bool changed) {
diff --git a/quantum/visualizer/visualizer.mk b/quantum/visualizer/visualizer.mk
index 6f97603bd..0f7d8636c 100644
--- a/quantum/visualizer/visualizer.mk
+++ b/quantum/visualizer/visualizer.mk
@@ -51,19 +51,23 @@ GFXSRC := $(patsubst $(TOP_DIR)/%,%,$(GFXSRC))
51GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS))) 51GFXDEFS := $(patsubst %,-D%,$(patsubst -D%,%,$(GFXDEFS)))
52 52
53ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","") 53ifneq ("$(wildcard $(KEYMAP_PATH)/visualizer.c)","")
54 SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c 54 SRC += keyboards/$(KEYBOARD)/keymaps/$(KEYMAP)/visualizer.c
55else 55else
56 ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","") 56 ifeq ("$(wildcard $(SUBPROJECT_PATH)/keymaps/$(KEYMAP)/visualizer.c)","")
57 ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","") 57 ifeq ("$(wildcard $(SUBPROJECT_PATH)/visualizer.c)","")
58$(error "$(KEYMAP_PATH)/visualizer.c" does not exist) 58 ifeq ("$(wildcard $(KEYBOARD_PATH)/visualizer.c)","")
59 else 59$(error "visualizer.c" not found")
60 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/visualizer.c 60 else
61 endif 61 SRC += keyboards/$(KEYBOARD)/visualizer.c
62 else 62 endif
63 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c 63 else
64 endif 64 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/visualizer.c
65 endif
66 else
67 SRC += keyboards/$(KEYBOARD)/$(SUBPROJECT)/keymaps/$(KEYMAP)/visualizer.c
68 endif
65endif 69endif
66 70
67ifdef EMULATOR 71ifdef EMULATOR
68UINCDIR += $(TMK_DIR)/common 72UINCDIR += $(TMK_DIR)/common
69endif \ No newline at end of file 73endif