aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Humbert <jack.humb@gmail.com>2017-06-18 12:38:38 -0400
committerGitHub <noreply@github.com>2017-06-18 12:38:38 -0400
commit517f75d893253e448105401ac638257841ad9e97 (patch)
treed06edd04812ad134aae6d470725fbac5205499b4
parentdd73e14c9b4d74473434fee78a9b1eb84491b1a8 (diff)
parent9af272e4bb685faabd1d879231f2718f0c00b32d (diff)
downloadqmk_firmware-517f75d893253e448105401ac638257841ad9e97.tar.gz
qmk_firmware-517f75d893253e448105401ac638257841ad9e97.zip
Merge pull request #1349 from jpetermans/infinity60
Infinity60 backlight support
-rw-r--r--keyboards/infinity60/config.h2
-rw-r--r--keyboards/infinity60/halconf.h4
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/Makefile4
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/config.h11
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/keymap.c304
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/readme.md87
-rw-r--r--keyboards/infinity60/led.c31
-rw-r--r--keyboards/infinity60/led_controller.c486
-rw-r--r--keyboards/infinity60/led_controller.h120
-rw-r--r--keyboards/infinity60/mcuconf.h11
-rw-r--r--keyboards/infinity60/rules.mk7
11 files changed, 1056 insertions, 11 deletions
diff --git a/keyboards/infinity60/config.h b/keyboards/infinity60/config.h
index f8346fe16..83930901c 100644
--- a/keyboards/infinity60/config.h
+++ b/keyboards/infinity60/config.h
@@ -54,7 +54,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
54//#define INFINITY_PROTOTYPE 54//#define INFINITY_PROTOTYPE
55 55
56/* Keymap for Infinity 1.1a (first revision with LED support) */ 56/* Keymap for Infinity 1.1a (first revision with LED support) */
57//#define INFINITY_LED 57#define INFINITY_LED
58 58
59/* 59/*
60 * Feature disable options 60 * Feature disable options
diff --git a/keyboards/infinity60/halconf.h b/keyboards/infinity60/halconf.h
index 46b37a4f4..f89dfc2e1 100644
--- a/keyboards/infinity60/halconf.h
+++ b/keyboards/infinity60/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/**
@@ -139,7 +139,7 @@
139 * @brief Enables the SERIAL over USB subsystem. 139 * @brief Enables the SERIAL over USB subsystem.
140 */ 140 */
141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) 141#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
142#define HAL_USE_SERIAL_USB TRUE 142#define HAL_USE_SERIAL_USB FALSE
143#endif 143#endif
144 144
145/** 145/**
diff --git a/keyboards/infinity60/keymaps/jpetermans/Makefile b/keyboards/infinity60/keymaps/jpetermans/Makefile
new file mode 100644
index 000000000..df3d1e952
--- /dev/null
+++ b/keyboards/infinity60/keymaps/jpetermans/Makefile
@@ -0,0 +1,4 @@
1
2ifndef QUANTUM_DIR
3 include ../../../../Makefile
4endif
diff --git a/keyboards/infinity60/keymaps/jpetermans/config.h b/keyboards/infinity60/keymaps/jpetermans/config.h
new file mode 100644
index 000000000..72a2ed081
--- /dev/null
+++ b/keyboards/infinity60/keymaps/jpetermans/config.h
@@ -0,0 +1,11 @@
1#ifndef CONFIG_USER_H
2#define CONFIG_USER_H
3
4
5#include "../../config.h"
6
7//overrides
8#undef TAPPING_TOGGLE
9#define TAPPING_TOGGLE 2
10
11#endif
diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c
new file mode 100644
index 000000000..59249ff72
--- /dev/null
+++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c
@@ -0,0 +1,304 @@
1#include "infinity60.h"
2#include "led_controller.h"
3
4//Helpful Defines
5#define _______ KC_TRNS
6
7//Define Layer Names
8#define _BASE 0
9#define _NUMPAD 1
10#define _FNAV 2
11#define _MEDIA 3
12#define _TILDE 4
13
14//IS31 chip has 8 available led pages, using 0 for all leds and 7 for single toggles
15#define max_pages 6
16
17enum ic60_keycodes {
18 NUMPAD,
19 FNAV,
20 MEDIA,
21 TILDE,
22 CTLALTDEL,
23 BACKLIGHT,
24 BRIGHT,
25 DIM,
26 ALL,
27 GAME,
28 MODE_SINGLE,
29 MODE_PAGE,
30 MODE_FLASH
31};
32
33uint8_t current_layer_global = 0;
34uint8_t led_mode_global = MODE_SINGLE;
35uint8_t backlight_status_global = 1; //init on/off state of backlight
36uint32_t led_layer_state = 0;
37
38/* ==================================
39 * KEYMAPS
40 * ==================================*/
41
42const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
43 /* Layer 0: Default Layer
44 * ,-----------------------------------------------------------.
45 * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| Backs|
46 * |-----------------------------------------------------------|
47 * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \|
48 * |-----------------------------------------------------------|
49 * |CapsLo| A| S| D| F| G| H| J| K| L| ;| '|Enter |
50 * |-----------------------------------------------------------|
51 * |Shif| | Z| X| C| V| B| N| M| ,| .| /|Shift |
52 * |-----------------------------------------------------------|
53 * |Ctrl|Gui |Alt | Space |Alt |Gui | FN | Ctrl |
54 * `-----------------------------------------------------------'
55 */
56 /* default */
57 [_BASE] = KEYMAP( \
58 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_BSLS,KC_NO,\
59 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,KC_RBRC,KC_BSPC, \
60 TT(_FNAV), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT,KC_ENT, \
61 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM,KC_DOT, KC_SLSH,F(TILDE),KC_NO, \
62 KC_LCTL, KC_LGUI,KC_LALT, LT(_FNAV, KC_SPC), KC_RALT,TG(_NUMPAD),MO(_MEDIA), KC_RCTL \
63 ),
64
65 /* numpad */
66 [_NUMPAD] = KEYMAP( \
67 _______,_______,_______,_______,_______,_______,_______, KC_P7, KC_P8, KC_P9, KC_PSLS, _______,_______,_______,KC_NO,\
68 _______,_______,_______,_______,_______,_______,_______, KC_P4, KC_P5, KC_P6, KC_PAST, _______,_______,_______, \
69 MO(_FNAV),_______,_______,_______,_______,_______,_______, KC_P1, KC_P2, KC_P3, KC_PMNS, _______,_______, \
70 _______,_______,_______,_______,_______,_______,_______, KC_P0,KC_COMM,KC_PDOT,KC_PPLS, _______,KC_NO, \
71 _______,_______,_______, TO(_BASE), _______,_______,_______,_______ \
72 ),
73
74 /* F-, arrow, and media keys */
75 [_FNAV] = KEYMAP( \
76 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_NO,\
77 KC_CAPS,_______,_______,_______,_______,_______,_______,KC_PGUP,KC_UP,KC_PGDN,KC_PSCR,_______,_______,KC_DEL, \
78 _______,_______,KC_BTN2,_______,_______,_______,KC_HOME,KC_LEFT,KC_DOWN,KC_RGHT,KC_INS,_______,_______, \
79 _______,KC_APP,KC_BTN1,KC_CALC,_______,_______,KC_END,_______,_______,_______,_______,_______,KC_NO, \
80 _______,_______,_______, _______, F(CTLALTDEL),KC_NLCK,_______,_______ \
81 ),
82
83 /* media */
84 [_MEDIA] = KEYMAP( \
85 _______,F(MODE_SINGLE),F(MODE_PAGE),F(MODE_FLASH),_______,_______,_______, _______, _______, _______,KC_MUTE, KC_VOLD, KC_VOLU,_______,KC_NO,\
86 _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,\
87 _______,_______,_______,_______,_______,F(GAME),_______, _______, _______, _______,_______, _______,_______, \
88 _______,_______,F(ALL) ,F(BRIGHT),F(DIM),F(BACKLIGHT),_______, _______, KC_MPRV, KC_MNXT,KC_MSTP, _______,KC_NO, \
89 _______,_______,_______, KC_MPLY, _______,_______, _______,_______ \
90 ),
91 /* ~ */
92 [_TILDE] = KEYMAP( \
93 KC_GRV,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,KC_NO,\
94 _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,\
95 _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______, \
96 _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,KC_NO, \
97 _______,_______,_______, _______, _______,_______, _______,_______ \
98 ),
99 /* template */
100 [5] = KEYMAP( \
101 _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,KC_NO,\
102 _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______,_______,\
103 _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,_______, \
104 _______,_______,_______,_______,_______,_______,_______, _______, _______, _______,_______, _______,KC_NO, \
105 _______,_______,_______, _______, _______,_______, _______,_______ \
106 ),
107};
108
109//id for user defined functions and macros
110enum function_id {
111 NONE,
112};
113
114enum macro_id {
115 ACTION_LEDS_ALL,
116 ACTION_LEDS_GAME,
117 ACTION_LEDS_BACKLIGHT,
118 ACTION_LEDS_BRIGHT,
119 ACTION_LEDS_DIM,
120 ACTION_LEDS_SINGLE,
121 ACTION_LEDS_PAGE,
122 ACTION_LEDS_FLASH
123};
124
125/* ==================================
126 * LED MAPPING
127 * ==================================*/
128
129/*
130 Infinity60 LED MAP
131 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27*
132 28 31 32 33 34 35 36 37 38 41 42 43 44 45
133 46 47 48 51 52 53 54 55 56 57 58 61 62
134 63 64 65 66 67 68 71 72 73 74 75 76 77*
135 78 81 82 83 84 85 86 87
136 *Unused in Alphabet Layout
137*/
138
139//======== full page arrays =========
140//any change in array size needs to be mirrored in matrix_init_user
141uint8_t led_numpad[16] = {
142 18,21,22,23,
143 37,38,41,42,
144 55,56,57,58,
145 72,73,74,75
146};
147//LED Page 2 - _Nav
148uint8_t led_nav[12] = {
149 38,
150 47,48, 55,56,57,
151 64,65,66
152};
153//LED Page 3 - _Media
154uint8_t led_media[15] = {
155 12,13,14, 23,24,25,
156 65,66,67,68, 73,74,75,
157 83, 86
158};
159//LED Page 4 - _Game "WASD"
160uint8_t led_game[5] = {
161 11,
162 32,
163 47,48,51
164};
165
166//======== qmk functions =========
167const uint16_t fn_actions[] = {
168 [CTLALTDEL] = ACTION_KEY(LALT(LCTL(KC_DEL))),
169 [TILDE] = ACTION_LAYER_MODS(_TILDE, MOD_LSFT),
170 [ALL] = ACTION_FUNCTION(ACTION_LEDS_ALL),
171 [GAME] = ACTION_FUNCTION(ACTION_LEDS_GAME),
172 [BACKLIGHT] = ACTION_FUNCTION(ACTION_LEDS_BACKLIGHT),
173 [BRIGHT] = ACTION_FUNCTION(ACTION_LEDS_BRIGHT),
174 [DIM] = ACTION_FUNCTION(ACTION_LEDS_DIM),
175 [MODE_SINGLE] = ACTION_FUNCTION(ACTION_LEDS_SINGLE),
176 [MODE_PAGE] = ACTION_FUNCTION(ACTION_LEDS_PAGE),
177 [MODE_FLASH] = ACTION_FUNCTION(ACTION_LEDS_FLASH),
178};
179
180/* custom action function */
181void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
182 msg_t msg;
183
184 switch(id) {
185 case ACTION_LEDS_ALL:
186 if(record->event.pressed) {
187 led_mode_global = led_mode_global == ALL ? MODE_SINGLE : ALL;
188 msg=TOGGLE_ALL;
189 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
190 }
191 break;
192
193 case ACTION_LEDS_BACKLIGHT:
194 if(record->event.pressed) {
195 backlight_status_global ^= 1;
196 msg=(backlight_status_global << 8) | TOGGLE_BACKLIGHT;
197 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
198 }
199 break;
200
201 case ACTION_LEDS_GAME:
202 if(record->event.pressed) {
203 led_mode_global = led_mode_global == GAME ? MODE_SINGLE : GAME;
204
205 msg=(4 << 8) | DISPLAY_PAGE;
206 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
207 }
208 break;
209
210 case ACTION_LEDS_BRIGHT:
211 if(record->event.pressed) {
212 msg=(1 << 8) | STEP_BRIGHTNESS;
213 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
214 }
215 break;
216
217 case ACTION_LEDS_DIM:
218 if(record->event.pressed) {
219 msg=(0 << 8) | STEP_BRIGHTNESS;
220 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
221 }
222 break;
223
224 //set led_mode for matrix_scan to toggle leds
225 case ACTION_LEDS_SINGLE:
226 led_mode_global = MODE_SINGLE;
227 break;
228 case ACTION_LEDS_PAGE:
229 led_mode_global = MODE_PAGE;
230 break;
231 case ACTION_LEDS_FLASH:
232 led_mode_global = MODE_FLASH;
233 break;
234
235 }
236}
237
238const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
239{
240 return MACRO_NONE;
241};
242
243
244bool process_record_user (uint16_t keycode, keyrecord_t *record) {
245 return true;
246}
247
248// Runs just one time when the keyboard initializes.
249void matrix_init_user(void) {
250
251 led_controller_init();
252
253 // Write predefined led pages.
254 write_led_page(_NUMPAD, led_numpad, 16);
255 chThdSleepMilliseconds(10);
256
257 write_led_page(_FNAV, led_nav, 12);
258 chThdSleepMilliseconds(10);
259
260 write_led_page(_MEDIA, led_media, 15);
261 chThdSleepMilliseconds(10);
262
263 write_led_page(4, led_game, 5);
264 chThdSleepMilliseconds(1000);
265};
266
267// Loops constantly in the background.
268void matrix_scan_user(void) {
269 uint8_t page;
270 uint8_t led_pin_byte;
271 msg_t msg;
272
273 if (backlight_status_global == 0) {//backlight is off, skip the rest
274 return;
275 }
276
277 if (led_layer_state != layer_state && led_mode_global != GAME && led_mode_global != ALL) {
278 //check mode
279 //Turn on layer indicator or page depending on mode
280 switch(led_mode_global) {
281 case MODE_FLASH: //flash preset page leds then single indicator
282 page = biton32(layer_state) > max_pages ? 7 : biton32(layer_state);
283 msg=(page << 8) | DISPLAY_PAGE;
284 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
285 chThdSleepMilliseconds(500);
286 //flow to display single layer leds
287
288 case MODE_SINGLE: //light layer indicators for all active layers
289 led_pin_byte = layer_state & 0xFF;
290 msg=(7 << 8) | DISPLAY_PAGE;
291 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
292 msg=(1 << 16) | (led_pin_byte << 8) | SET_FULL_ROW;
293 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
294 break;
295
296 case MODE_PAGE: //display pre-defined led page
297 page = biton32(layer_state) > max_pages ? 7 : biton32(layer_state);
298 msg=(page << 8) | DISPLAY_PAGE;
299 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
300 break;
301 }
302 led_layer_state = layer_state;
303 }
304}
diff --git a/keyboards/infinity60/keymaps/jpetermans/readme.md b/keyboards/infinity60/keymaps/jpetermans/readme.md
new file mode 100644
index 000000000..b83057ea7
--- /dev/null
+++ b/keyboards/infinity60/keymaps/jpetermans/readme.md
@@ -0,0 +1,87 @@
1Backlight for Infinity60
2========================
3
4## Led Controller Specs
5
6The Infinity60 (revision 1.1a) pcb uses the IS31FL3731C matrix LED driver from ISSI [(datasheet)](http://www.issi.com/WW/pdf/31FL3731C.pdf). The IS31 has the ability to control two led matrices (A & B), each matrix controlling 9 pins, each pin controlling 8 leds. The Infinity only utilizes matrix A.
7
8Infinity60 LED Map:
9digits mean "row" and "col", i.e. 45 means pin 4, column 5 in the IS31 datasheet
10```c
11 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27*
12 28 31 32 33 34 35 36 37 38 41 42 43 44 45
13 46 47 48 51 52 53 54 55 56 57 58 61 62
14 63 64 65 66 67 68 71 72 73 74 75 76 77*
15 78 81 82 83 84 85 86 87
16```
17*Unused in Alphabet Layout
18
19The IS31 includes 8 led pages (or frames) 0-7 than can be displayed, and each page consists of 144 bytes.
20- **bytes 0 - 17** - LED control (on/off).
21 * 18 pins which alternate between A and B matrices (A1, B1, A2, B2, ..).
22 * Each byte controls the 8 leds on that pin with bits (8 to 1).
23- **bytes 8 - 35** - Blink control.
24 * Same as LED control above, but sets blink on/off.
25- **bytes 36 - 143** - PWM control.
26 * One byte per LED, sets PWM from 0 to 255.
27 * Same as above, the register alternates, every 8 *bytes* (not bits) between the A & B matrices.
28
29## Led Controller Code
30In the Infinity60 project folder, led_controller.c sets up ability to write led layers at startup or control leds on demand as part of fn_actions. By default led_controller.c assumes page 0 will be used for full on/off. The remaining 7 pages (1-7) are free for preset led maps or single led actions at init or on demand. Communication with the IS31 is primarily done through the led_mailbox using chMBPost described further below under "Sending messages in Keymap.c". This code is based on work matt3o and flabbergast did for tmk firmware on the [whitefox](https://github.com/tmk/whitefox).
31
32One function is available to directly set leds without the mailbox:
33```
34write_led_page(page#, array of leds by address, # of addresses in array)
35```
36This function saves a full page to the controller using a supplied array of led locations such as:
37```c
38uint8_t led_numpad[16] = {
39 18,21,22,23,
40 37,38,41,42,
41 55,56,57,58,
42 72,73,74,75
43}
44write_led_page(5, led_numpad, 16);
45```
46
47Remaining led control is done through the led mailbox using these message types:
48- **SET_FULL_ROW** (3 bytes) - message type, 8-bit mask, and row#. Sets all leds on one pin per the bit mask.
49- **OFF_LED, ON_LED, TOGGLE_LED** (3 bytes) - message type, led address, and page#. Off/on/toggle specific led.
50- **BLINK_OFF_LED, BLINK_ON_LED, BLINK_OFF_LED** (3 bytes) - message type, led address, and page#. Set blink Off/on/toggle for specific led.
51- **TOGGLE_ALL** (1 byte) - Turn on/off full backlight.
52- **TOGGLE_BACKLIGHT** (2 bytes) - message type, on/off. Sets backlight completely off, no leds will display.
53- **DISPLAY_PAGE** (2 bytes) - message type, page to display. Switch to specific pre-set page.
54- **RESET_PAGE** (2 bytes) - message type, page to reset. Reset/erase specific page.
55- **TOGGLE_NUM_LOCK** (2 bytes) - message type, on/off (NUM_LOCK_LED_ADDRESS). Toggle numlock on/off. Usually run with the `set_leds` function to check state of numlock or capslock. If all leds are on (e.i. TOGGLE_ALL) then this sets numlock to blink instead (this is still a little buggy if toggling on/off quickly).
56- **TOGGLE_CAPS_LOCK** (2 bytes) - message type, on/off (CAPS_LOCK_LED_ADDRESS). Same as numlock.
57- **STEP_BRIGHTNESS** (2 bytes) - message type, and step up (1) or step down (0). Increase or decrease led brightness.
58
59## Sending messages in Keymap.c
60Sending an action to the led mailbox is done using chMBPost:
61```
62chMBPost(&led_mailbox, message, timeout);
63```
64- &led_mailbox - pointer to led mailbox
65- message - up to 4 bytes but most messages use only 2. First byte (LSB) is the message type, the remaining three bytes are the message to process.
66- timeout is TIME_IMMEDIATE
67
68An example:
69```c
70//set the message to be sent. First byte (LSB) is the led address, and second is the message type
71msg=(42 << 8) | ON_LED;
72
73//send msg to the led mailbox
74chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
75```
76
77Another:
78```c
79msg=(46 << 8) | BLINK_TOGGLE_LED;
80chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
81```
82
83Finally, SET_FULL_ROW requires an extra byte with row information in the message so sending this message looks like:
84```c
85msg=(row<<16) | (led_pin_byte << 8) | SET_FULL_ROW;
86chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
87```
diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c
index aed66c7c0..53147a78a 100644
--- a/keyboards/infinity60/led.c
+++ b/keyboards/infinity60/led.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2012 Jun Wako <wakojun@gmail.com> 2Copyright 2015 Jun Wako <wakojun@gmail.com>
3 3
4This program is free software: you can redistribute it and/or modify 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 5it under the terms of the GNU General Public License as published by
@@ -19,6 +19,35 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20#include "led.h" 20#include "led.h"
21 21
22#include "led_controller.h"
22 23
24/* WARNING! This function needs to be callable from
25 * both regular threads and ISRs, unlocked (during resume-from-sleep).
26 * In particular, I2C functions (interrupt-driven) should NOT be called from here.
27 */
23void led_set(uint8_t usb_led) { 28void led_set(uint8_t usb_led) {
29 msg_t msg;
30
31 if (usb_led & (1<<USB_LED_NUM_LOCK)) {
32 chSysUnconditionalLock();
33 msg=(1 << 8) | TOGGLE_NUM_LOCK;
34 chMBPostI(&led_mailbox, msg);
35 chSysUnconditionalUnlock();
36 } else {
37 chSysUnconditionalLock();
38 msg=(0 << 8) | TOGGLE_NUM_LOCK;
39 chMBPostI(&led_mailbox, msg);
40 chSysUnconditionalUnlock();
41 }
42 if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
43 chSysUnconditionalLock();
44 msg=(1 << 8) | TOGGLE_CAPS_LOCK;
45 chMBPostI(&led_mailbox, msg);
46 chSysUnconditionalUnlock();
47 } else {
48 chSysUnconditionalLock();
49 msg=(0 << 8) | TOGGLE_CAPS_LOCK;
50 chMBPostI(&led_mailbox, msg);
51 chSysUnconditionalUnlock();
52 }
24} 53}
diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c
new file mode 100644
index 000000000..21f95a9c1
--- /dev/null
+++ b/keyboards/infinity60/led_controller.c
@@ -0,0 +1,486 @@
1/*
2Copyright 2016 flabbergast <s3+flabbergast@sdfeu.org>
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 * LED controller code
20 * IS31FL3731C matrix LED driver from ISSI
21 * datasheet: http://www.issi.com/WW/pdf/31FL3731C.pdf
22 */
23
24#include "ch.h"
25#include "hal.h"
26#include "print.h"
27#include "led.h"
28#include "host.h"
29
30#include "led_controller.h"
31
32#include "suspend.h"
33
34#include "usb_main.h"
35
36/* Infinity60 LED MAP
37 - digits mean "row" and "col", i.e. 45 means C4-5 in the IS31 datasheet, matrix A
38
39 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27*
40 28 31 32 33 34 35 36 37 38 41 42 43 44 45
41 46 47 48 51 52 53 54 55 56 57 58 61 62
42 63 64 65 66 67 68 71 72 73 74 75 76 77*
43 78 81 82 83 84 85 86 87
44
45*Unused in Alphabet Layout
46*/
47
48/*
49 each page has 0xB4 bytes
50 0 - 0x11: LED control (on/off):
51 order: CA1, CB1, CA2, CB2, .... (CA - matrix A, CB - matrix B)
52 CAn controls Cn-8 .. Cn-1 (LSbit)
53 0x12 - 0x23: blink control (like "LED control")
54 0x24 - 0xB3: PWM control: byte per LED, 0xFF max on
55 order same as above (CA 1st row (8bytes), CB 1st row (8bytes), ...)
56*/
57
58// Which LED should be used for CAPS LOCK indicator
59#if !defined(CAPS_LOCK_LED_ADDRESS)
60#define CAPS_LOCK_LED_ADDRESS 46
61#endif
62
63#if !defined(NUM_LOCK_LED_ADDRESS)
64#define NUM_LOCK_LED_ADDRESS 85
65#endif
66
67/* Which LED should breathe during sleep */
68#if !defined(BREATHE_LED_ADDRESS)
69#define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS
70#endif
71
72/* =================
73 * ChibiOS I2C setup
74 * ================= */
75static const I2CConfig i2ccfg = {
76 400000 // clock speed (Hz); 400kHz max for IS31
77};
78
79/* ==============
80 * variables
81 * ============== */
82// internal communication buffers
83uint8_t tx[2] __attribute__((aligned(2)));
84uint8_t rx[1] __attribute__((aligned(2)));
85
86// buffer for sending the whole page at once (used also as a temp buffer)
87uint8_t full_page[0xB4+1] = {0};
88
89// LED mask (which LEDs are present, selected by bits)
90// IC60 pcb uses only CA matrix.
91// Each byte is a control pin for 8 leds ordered 8-1
92const uint8_t all_on_leds_mask[0x12] = {
93 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
94 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0x00
95};
96
97// array to hold brightness pwm steps
98const uint8_t pwm_levels[5] = {
99 0x00, 0x16, 0x4E, 0xA1, 0xFF
100};
101
102// array to write to pwm register
103uint8_t pwm_register_array[9] = {0};
104
105
106/* ============================
107 * communication functions
108 * ============================ */
109msg_t is31_select_page(uint8_t page) {
110 tx[0] = IS31_COMMANDREGISTER;
111 tx[1] = page;
112 return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT));
113}
114
115msg_t is31_write_data(uint8_t page, uint8_t *buffer, uint8_t size) {
116 is31_select_page(page);
117 return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, buffer, size, NULL, 0, US2ST(IS31_TIMEOUT));
118}
119
120msg_t is31_write_register(uint8_t page, uint8_t reg, uint8_t data) {
121 is31_select_page(page);
122 tx[0] = reg;
123 tx[1] = data;
124 return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT));
125}
126
127msg_t is31_read_register(uint8_t page, uint8_t reg, uint8_t *result) {
128 is31_select_page(page);
129
130 tx[0] = reg;
131 return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 1, result, 1, US2ST(IS31_TIMEOUT));
132}
133
134/* ========================
135 * initialise the IS31 chip
136 * ======================== */
137void is31_init(void) {
138 // just to be sure that it's all zeroes
139 __builtin_memset(full_page,0,0xB4+1);
140 // zero function page, all registers (assuming full_page is all zeroes)
141 is31_write_data(IS31_FUNCTIONREG, full_page, 0xD + 1);
142 // disable hardware shutdown
143 palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL);
144 palSetPad(GPIOB, 16);
145 chThdSleepMilliseconds(10);
146 // software shutdown
147 is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON);
148 chThdSleepMilliseconds(10);
149 // zero function page, all registers
150 is31_write_data(IS31_FUNCTIONREG, full_page, 0xD + 1);
151 chThdSleepMilliseconds(10);
152 // software shutdown disable (i.e. turn stuff on)
153 is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
154 chThdSleepMilliseconds(10);
155 // zero all LED registers on all 8 pages
156 uint8_t i;
157 for(i=0; i<8; i++) {
158 is31_write_data(i, full_page, 0xB4 + 1);
159 chThdSleepMilliseconds(5);
160 }
161}
162
163/* ==================
164 * LED control thread
165 * ================== */
166#define LED_MAILBOX_NUM_MSGS 5
167static msg_t led_mailbox_queue[LED_MAILBOX_NUM_MSGS];
168mailbox_t led_mailbox;
169static THD_WORKING_AREA(waLEDthread, 256);
170static THD_FUNCTION(LEDthread, arg) {
171 (void)arg;
172 chRegSetThreadName("LEDthread");
173
174 uint8_t i;
175 uint8_t control_register_word[2] = {0};//2 bytes: register address, byte to write
176 uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes
177
178 //persistent status variables
179 uint8_t pwm_step_status, page_status, capslock_status, numlock_status;
180
181 //mailbox variables
182 uint8_t temp, msg_type;
183 uint8_t msg_args[3];
184 msg_t msg;
185
186 // initialize persistent variables
187 pwm_step_status = 4; //full brightness
188 page_status = 0; //start frame 0 (all off/on)
189 numlock_status = (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) ? 1 : 0;
190 capslock_status = (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) ? 1 : 0;
191
192 while(true) {
193 // wait for a message (asynchronous)
194 // (messages are queued (up to LED_MAILBOX_NUM_MSGS) if they can't
195 // be processed right away
196 chMBFetch(&led_mailbox, &msg, TIME_INFINITE);
197 msg_type = msg & 0xFF; //first byte is action information
198 msg_args[0] = (msg >> 8) & 0xFF;
199 msg_args[1] = (msg >> 16) & 0XFF;
200 msg_args[2] = (msg >> 24) & 0xFF;
201
202
203 switch (msg_type){
204 case SET_FULL_ROW:
205 //write full byte to pin address, msg_args[1] = pin #, msg_args[0] = 8 bits to write
206 //writes only to currently displayed page
207 write_led_byte(page_status, msg_args[1], msg_args[0]);
208 break;
209
210 case OFF_LED:
211 //on/off/toggle single led, msg_args[0] = row/col of led, msg_args[1] = page
212 set_led_bit(msg_args[1], control_register_word, msg_args[0], 0);
213 break;
214 case ON_LED:
215 set_led_bit(msg_args[1], control_register_word, msg_args[0], 1);
216 break;
217 case TOGGLE_LED:
218 set_led_bit(msg_args[1], control_register_word, msg_args[0], 2);
219 break;
220
221 case BLINK_OFF_LED:
222 //on/off/toggle single led, msg_args[0] = row/col of led
223 set_led_bit(msg_args[1], control_register_word, msg_args[0], 4);
224 break;
225 case BLINK_ON_LED:
226 set_led_bit(msg_args[1], control_register_word, msg_args[0], 5);
227 break;
228 case BLINK_TOGGLE_LED:
229 set_led_bit(msg_args[1], control_register_word, msg_args[0], 6);
230 break;
231
232 case TOGGLE_ALL:
233 //turn on/off all leds, msg_args = unused
234 is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON);
235 chThdSleepMilliseconds(5);
236 is31_read_register(0, 0x00, &temp);
237 is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
238
239 led_control_reg[0] = 0;
240
241 //toggle led mask based on current state (temp)
242 if (temp==0 || page_status > 0) {
243 __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12);
244 } else {
245 __builtin_memset(led_control_reg+1, 0, 0x12);
246 }
247 is31_write_data(0, led_control_reg, 0x13);
248
249 if (page_status > 0) {
250 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0);
251
252 page_status=0;
253
254 //maintain lock leds, reset to off and force recheck to blink of all leds toggled on
255 numlock_status = 0;
256 capslock_status = 0;
257 led_set(host_keyboard_leds());
258 }
259 break;
260
261 case TOGGLE_BACKLIGHT:
262 //msg_args[0] = on/off
263
264 //populate 9 byte rows to be written to each pin, first byte is register (pin) address
265 if (msg_args[0] == 1) {
266 __builtin_memset(pwm_register_array+1, pwm_levels[pwm_step_status], 8);
267 } else {
268 __builtin_memset(pwm_register_array+1, 0, 8);
269 }
270
271 for(i=0; i<8; i++) {
272 //first byte is register address, every 0x10 9 bytes is A-matrix pwm pins
273 pwm_register_array[0] = 0x24 + (i * 0x10);
274 is31_write_data(0,pwm_register_array,9);
275 }
276 break;
277
278 case DISPLAY_PAGE:
279 //msg_args[0] = page to toggle on
280 if (page_status != msg_args[0]) {
281 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_args[0]);
282 page_status = msg_args[0];
283
284 //maintain lock leds, reset to off and force recheck for new page
285 numlock_status = 0;
286 capslock_status = 0;
287 led_set(host_keyboard_leds());
288 }
289 break;
290
291 case RESET_PAGE:
292 //led_args[0] = page to reset
293 led_control_reg[0] = 0;
294 __builtin_memset(led_control_reg+1, 0, 0x12);
295 is31_write_data(msg_args[0], led_control_reg, 0x13);
296
297 //repeat for blink register
298 led_control_reg[0] = 0x12;
299 is31_write_data(msg_args[0], led_control_reg, 0x13);
300 break;
301
302 case TOGGLE_NUM_LOCK:
303 //msg_args[0] = 0 or 1, off/on
304 if (numlock_status != msg_args[0]) {
305 set_lock_leds(NUM_LOCK_LED_ADDRESS, msg_args[0], page_status);
306 numlock_status = msg_args[0];
307 }
308 break;
309 case TOGGLE_CAPS_LOCK:
310 //msg_args[0] = 0 or 1, off/on
311 if (capslock_status != msg_args[0]) {
312 set_lock_leds(CAPS_LOCK_LED_ADDRESS, msg_args[0], page_status);
313 capslock_status = msg_args[0];
314 }
315 break;
316
317 case STEP_BRIGHTNESS:
318 //led_args[0] = step up (1) or down (0)
319 switch (msg_args[0]) {
320 case 0:
321 if (pwm_step_status == 0) {
322 pwm_step_status = 4;
323 } else {
324 pwm_step_status--;
325 }
326 break;
327
328 case 1:
329 if (pwm_step_status == 4) {
330 pwm_step_status = 0;
331 } else {
332 pwm_step_status++;
333 }
334 break;
335 }
336
337 //populate 8 byte arrays to write on each pin
338 //first byte is register address, every 0x10 9 bytes are A-matrix pwm pins
339 __builtin_memset(pwm_register_array+1, pwm_levels[pwm_step_status], 8);
340
341 for(i=0; i<8; i++) {
342 pwm_register_array[0] = 0x24 + (i * 0x10);
343 is31_write_data(0,pwm_register_array,9);
344 }
345 break;
346 }
347 }
348}
349
350/* ==============================
351 * led processing functions
352 * ============================== */
353
354void set_led_bit (uint8_t page, uint8_t *led_control_word, uint8_t led_addr, uint8_t action) {
355 //returns 2 bytes: led control register address and byte to write
356 //action: 0 - off, 1 - on, 2 - toggle, 4 - blink on, 5 - blink off, 6 - toggle blink
357
358 uint8_t control_reg_addr, column_bit, column_byte, temp, blink_bit;
359
360 //check for valid led address
361 if (led_addr < 0 || led_addr > 87 || led_addr % 10 > 8) {
362 return;
363 }
364
365 blink_bit = action>>2;//check for blink bit
366 action &= ~(1<<2); //strip blink bit
367
368 //led_addr tens column is pin#, ones column is bit position in 8-bit mask
369 control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-matrix is every other byte
370 control_reg_addr += blink_bit == 1 ? 0x12 : 0x00;//if blink_bit, shift 12 bytes to blink register
371
372 is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON);
373 chThdSleepMilliseconds(5);
374 is31_read_register(page, control_reg_addr, &temp);//maintain status of leds on this byte
375 is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
376
377 column_bit = 1<<(led_addr % 10 - 1);
378 column_byte = temp;
379
380 switch(action) {
381 case 0:
382 column_byte &= ~column_bit;
383 break;
384 case 1:
385 column_byte |= column_bit;
386 break;
387 case 2:
388 column_byte ^= column_bit;
389 break;
390 }
391
392 //return word to be written in register
393 led_control_word[0] = control_reg_addr;
394 led_control_word[1] = column_byte;
395 is31_write_data (page, led_control_word, 0x02);
396}
397
398void write_led_byte (uint8_t page, uint8_t row, uint8_t led_byte) {
399 uint8_t led_control_word[2] = {0};//register address and on/off byte
400
401 led_control_word[0] = (row - 1 ) * 0x02;// A-matrix is every other byte
402 led_control_word[1] = led_byte;
403 is31_write_data(page, led_control_word, 0x02);
404}
405
406void write_led_page (uint8_t page, uint8_t *user_led_array, uint8_t led_count) {
407 uint8_t i;
408 uint8_t pin, col;
409 uint8_t led_control_register[0x13] = {0};
410
411 __builtin_memset(led_control_register,0,13);
412
413 for(i=0;i<led_count;i++){
414 //shift pin by 1 for led register 0x00 address
415 pin = ((user_led_array[i] / 10) % 10 - 1 ) * 2 + 1;
416 col = user_led_array[i] % 10 - 1;
417 led_control_register[pin] |= 1<<(col);
418 }
419
420 is31_write_data(page, led_control_register, 0x13);
421}
422
423void set_lock_leds(uint8_t led_addr, uint8_t led_action, uint8_t page) {
424 uint8_t temp;
425 uint8_t led_control_word[2] = {0};
426
427 //blink if all leds are on
428 if (page == 0) {
429 is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_ON);
430 chThdSleepMilliseconds(5);
431 is31_read_register(0, 0x00, &temp);
432 is31_write_register(IS31_FUNCTIONREG, IS31_REG_SHUTDOWN, IS31_REG_SHUTDOWN_OFF);
433
434 if (temp == 0xFF) {
435 led_action |= (1<<2); //set blink bit
436 }
437 }
438
439 set_led_bit(page,led_control_word,led_addr,led_action);
440}
441
442/* =====================
443 * hook into user keymap
444 * ===================== */
445void led_controller_init(void) {
446 uint8_t i;
447
448 /* initialise I2C */
449 /* I2C pins */
450 palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL
451 palSetPadMode(GPIOB, 1, PAL_MODE_ALTERNATIVE_2); // PTB1/I2C0/SDA
452 /* start I2C */
453 i2cStart(&I2CD1, &i2ccfg);
454 // try high drive (from kiibohd)
455 I2CD1.i2c->C2 |= I2Cx_C2_HDRS;
456 // try glitch fixing (from kiibohd)
457 I2CD1.i2c->FLT = 4;
458
459 chThdSleepMilliseconds(10);
460
461 /* initialise IS31 chip */
462 is31_init();
463
464 //set Display Option Register so all pwm intensity is controlled from page 0
465 //enable blink and set blink period to 0.27s x rate
466 is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME + IS31_REG_DISPLAYOPT_BLINK_ENABLE + 4);
467
468 /* set full pwm on page 1 */
469 pwm_register_array[0] = 0;
470 __builtin_memset(pwm_register_array+1, 0xFF, 8);
471 for(i=0; i<8; i++) {
472 pwm_register_array[0] = 0x24 + (i * 0x10);//first byte of 9 bytes must be register address
473 is31_write_data(0, pwm_register_array, 9);
474 chThdSleepMilliseconds(5);
475 }
476
477 /* enable breathing when the displayed page changes */
478 // Fade-in Fade-out, time = 26ms * 2^N, N=3
479 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (3<<4)|3);
480 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
481
482 /* more time consuming LED processing should be offloaded into
483 * a thread, with asynchronous messaging. */
484 chMBObjectInit(&led_mailbox, led_mailbox_queue, LED_MAILBOX_NUM_MSGS);
485 chThdCreateStatic(waLEDthread, sizeof(waLEDthread), LOWPRIO, LEDthread, NULL);
486}
diff --git a/keyboards/infinity60/led_controller.h b/keyboards/infinity60/led_controller.h
new file mode 100644
index 000000000..eb6060f26
--- /dev/null
+++ b/keyboards/infinity60/led_controller.h
@@ -0,0 +1,120 @@
1/*
2Copyright 2016 flabbergast <s3+flabbergast@sdfeu.org>
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 _LED_CONTROLLER_H_
19#define _LED_CONTROLLER_H_
20
21/* =========================
22 * communication functions
23 * ========================= */
24
25msg_t is31_write_data(uint8_t page, uint8_t *buffer, uint8_t size);
26msg_t is31_write_register(uint8_t page, uint8_t reg, uint8_t data);
27msg_t is31_read_register(uint8_t page, uint8_t reg, uint8_t *result);
28
29/* ============================
30 * init functions/definitions
31 * ============================*/
32
33void led_controller_init(void);
34
35#define CAPS_LOCK_LED_ADDRESS 46 //pin matrix location
36#define NUM_LOCK_LED_ADDRESS 85
37
38/* =============================
39 * IS31 chip related definitions
40 * ============================= */
41
42#define IS31_ADDR_DEFAULT 0x74
43
44#define IS31_REG_CONFIG 0x00
45// bits in reg
46#define IS31_REG_CONFIG_PICTUREMODE 0x00
47#define IS31_REG_CONFIG_AUTOPLAYMODE 0x08
48#define IS31_REG_CONFIG_AUDIOPLAYMODE 0x18
49// D2:D0 bits are starting frame for autoplay mode
50
51#define IS31_REG_PICTDISP 0x01 // D2:D0 frame select for picture mode
52
53#define IS31_REG_AUTOPLAYCTRL1 0x02
54// D6:D4 number of loops (000=infty)
55// D2:D0 number of frames to be used
56
57#define IS31_REG_AUTOPLAYCTRL2 0x03 // D5:D0 delay time (*11ms)
58
59#define IS31_REG_DISPLAYOPT 0x05
60#define IS31_REG_DISPLAYOPT_INTENSITY_SAME 0x20 // same intensity for all frames
61#define IS31_REG_DISPLAYOPT_BLINK_ENABLE 0x08
62// D2:D0 bits blink period time (*0.27s)
63
64#define IS31_REG_AUDIOSYNC 0x06
65#define IS31_REG_AUDIOSYNC_ENABLE 0x1
66
67#define IS31_REG_FRAMESTATE 0x07
68
69#define IS31_REG_BREATHCTRL1 0x08
70// D6:D4 fade out time (26ms*2^i)
71// D2:D0 fade in time (26ms*2^i)
72
73#define IS31_REG_BREATHCTRL2 0x09
74#define IS31_REG_BREATHCTRL2_ENABLE 0x10
75// D2:D0 extinguish time (3.5ms*2^i)
76
77#define IS31_REG_SHUTDOWN 0x0A
78#define IS31_REG_SHUTDOWN_OFF 0x1
79#define IS31_REG_SHUTDOWN_ON 0x0
80
81#define IS31_REG_AGCCTRL 0x0B
82#define IS31_REG_ADCRATE 0x0C
83
84#define IS31_COMMANDREGISTER 0xFD
85#define IS31_FUNCTIONREG 0x0B // helpfully called 'page nine'
86
87#define IS31_TIMEOUT 10000 // needs to be long enough to write a whole page
88
89/* ========================================
90 * LED Thread related items
91 * ========================================*/
92
93extern mailbox_t led_mailbox;
94
95void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint8_t action);
96void set_lock_leds (uint8_t led_addr, uint8_t led_action, uint8_t page);
97void write_led_byte (uint8_t page, uint8_t row, uint8_t led_byte);
98void write_led_page (uint8_t page, uint8_t *led_array, uint8_t led_count);
99
100// constants for signaling the LED controller thread
101enum led_msg_t {
102 KEY_LIGHT,
103 SET_FULL_ROW,
104 OFF_LED,
105 ON_LED,
106 TOGGLE_LED,
107 BLINK_OFF_LED,
108 BLINK_ON_LED,
109 BLINK_TOGGLE_LED,
110 TOGGLE_ALL,
111 TOGGLE_BACKLIGHT,
112 DISPLAY_PAGE,
113 RESET_PAGE,
114 TOGGLE_NUM_LOCK,
115 TOGGLE_CAPS_LOCK,
116 TOGGLE_BREATH,
117 STEP_BRIGHTNESS
118};
119
120#endif /* _LED_CONTROLLER_H_ */
diff --git a/keyboards/infinity60/mcuconf.h b/keyboards/infinity60/mcuconf.h
index f453304b7..6af85d079 100644
--- a/keyboards/infinity60/mcuconf.h
+++ b/keyboards/infinity60/mcuconf.h
@@ -47,9 +47,12 @@
47 * USB driver settings 47 * USB driver settings
48 */ 48 */
49#define KINETIS_USB_USE_USB0 TRUE 49#define KINETIS_USB_USE_USB0 TRUE
50/* Need to redefine this, since the default is for K20x */ 50#define KINETIS_USB_USB0_IRQ_PRIORITY 5
51/* This is for Teensy LC; you should comment it out (or change to 5) 51
52 * for Teensy 3.x */ 52/*
53#define KINETIS_USB_USB0_IRQ_PRIORITY 2 53 * I2C driver settings
54 */
55#define KINETIS_I2C_USE_I2C0 TRUE
56#define KINETIS_I2C_I2C0_PRIORITY 4
54 57
55#endif /* _MCUCONF_H_ */ 58#endif /* _MCUCONF_H_ */
diff --git a/keyboards/infinity60/rules.mk b/keyboards/infinity60/rules.mk
index 56d6470b5..c19f62401 100644
--- a/keyboards/infinity60/rules.mk
+++ b/keyboards/infinity60/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 led_controller.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
@@ -55,7 +56,7 @@ OPT_DEFS = -DCORTEX_VTOR_INIT=0x00001000
55# Build Options 56# Build Options
56# comment out to disable the options. 57# comment out to disable the options.
57# 58#
58BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration 59BOOTMAGIC_ENABLE ?= no # Virtual DIP switch configuration
59## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.) 60## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.)
60MOUSEKEY_ENABLE ?= yes # Mouse keys 61MOUSEKEY_ENABLE ?= yes # Mouse keys
61EXTRAKEY_ENABLE ?= yes # Audio control and System control 62EXTRAKEY_ENABLE ?= yes # Audio control and System control
@@ -63,4 +64,4 @@ CONSOLE_ENABLE ?= yes # Console for debug
63COMMAND_ENABLE ?= yes # Commands for debug and configuration 64COMMAND_ENABLE ?= yes # Commands for debug and configuration
64SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend 65SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend
65NKRO_ENABLE ?= yes # USB Nkey Rollover 66NKRO_ENABLE ?= yes # USB Nkey Rollover
66CUSTOM_MATRIX ?= yes # Custom matrix file \ No newline at end of file 67CUSTOM_MATRIX ?= yes # Custom matrix file