aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjpetermans <tibcmhhm@gmail.com>2017-04-10 17:36:47 -0700
committerjpetermans <tibcmhhm@gmail.com>2017-04-10 17:36:47 -0700
commitdda858c437e2fd0336f070ccb5d1f6e412815d9a (patch)
treefb94cde2ebfd5cef5b90520efc84aab94ec75f03
parenta2ac8837790030b771744402aac8d8ab0e1967aa (diff)
downloadqmk_firmware-dda858c437e2fd0336f070ccb5d1f6e412815d9a.tar.gz
qmk_firmware-dda858c437e2fd0336f070ccb5d1f6e412815d9a.zip
revised led controller code to allow for more options
unable to switch picture displays
-rw-r--r--keyboards/infinity60/keymaps/jpetermans/keymap.c103
-rw-r--r--keyboards/infinity60/led.c4
-rw-r--r--keyboards/infinity60/led_controller.c333
-rw-r--r--keyboards/infinity60/led_controller.h33
4 files changed, 340 insertions, 133 deletions
diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c
index c7145ed78..cfc288916 100644
--- a/keyboards/infinity60/keymaps/jpetermans/keymap.c
+++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c
@@ -98,8 +98,6 @@ enum macro_id {
98 * LED MAPPING 98 * LED MAPPING
99 * ==================================*/ 99 * ==================================*/
100 100
101//TODO: ACTION_LED_LAYER which reads current layer and turns on appropriate LED
102
103/* 101/*
104 Configuring led control can be done as 102 Configuring led control can be done as
105 1. full keyboard at a time - define led array, or 103 1. full keyboard at a time - define led array, or
@@ -121,43 +119,50 @@ enum macro_id {
121 array translates to row and column positions 119 array translates to row and column positions
122*/ 120*/
123 121
124//"WASD" 122//LED Layer indicator (1 per layer 3-7)
125const uint8_t led_game[72] = { 123const uint8_t led_single_layer[5] = {
126 0x24, 124 12,13,14,15,16
127 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x34,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x44,
131 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x54,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
134 0x64,
135 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x74,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x84,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x94,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142}; 125};
143 126//LED Page 1 - All off
144const uint8_t led_all[72] = { 127//LED Page 2 - All on
145 0x24, 128//LED Page 3 - _Nav
146 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 129const uint8_t led_nav[33] = {
147 0x34, 130 11,12,13,14,15,16,17,18,21,22,23,24,25,
148 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 131 28, 37,38,41,42,45,
149 0x44, 132 46,47,48, 54,55,56,57,58,
150 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 133 64,65,66, 71,
151 0x54, 134 84,85
152 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 135};
153 0x64, 136//LED Page 4 - _Numpad
154 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 137const uint8_t led_numpad[17] = {
155 0x74, 138 18,21,22,23,
156 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 139 37,38,41,42,
157 0x84, 140 55,56,57,58,
158 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 141 72,73,74,75,
159 0x94, 142 85
160 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 143};
144//LED Page 5 - _Media
145const uint8_t led_media[12] = {
146 23,24,25,
147 38,
148 55,56,57,
149 73,74,75,
150 83, 86
151};
152//LED Page 6 - _Game
153const uint8_t led_game[5] = {
154 //row 1
155 11,
156 //row 2
157 //row 3
158 32,
159 //row 4
160 47, 48,
161 //row 5
162 51
163 //row 6
164 //row 7
165 //row 8
161}; 166};
162 167
163const uint16_t fn_actions[] = { 168const uint16_t fn_actions[] = {
@@ -172,17 +177,20 @@ const uint16_t fn_actions[] = {
172/* custom action function */ 177/* custom action function */
173void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { 178void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
174 (void)opt; 179 (void)opt;
180 msg_t msg;
175 switch(id) { 181 switch(id) {
176 case ACTION_LEDS_ALL: 182 case ACTION_LEDS_ALL:
177 if(record->event.pressed) { 183 if(record->event.pressed) {
178 // signal the LED controller thread 184 // signal the LED controller thread
179 chMBPost(&led_mailbox, 1, TIME_IMMEDIATE); 185 msg=(TOGGLE_LED << 8) | 12;
186 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
180 } 187 }
181 break; 188 break;
182 case ACTION_LEDS_GAME: 189 case ACTION_LEDS_GAME:
183 if(record->event.pressed) { 190 if(record->event.pressed) {
184 // signal the LED controller thread 191 // signal the LED controller thread
185 chMBPost(&led_mailbox, 2, TIME_IMMEDIATE); 192 msg=(TOGGLE_LAYER_LEDS << 8) | 5;
193 chMBPost(&led_mailbox, msg, TIME_IMMEDIATE);
186 } 194 }
187 break; 195 break;
188 case ACTION_LED_1: 196 case ACTION_LED_1:
@@ -212,19 +220,22 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
212 220
213// Runs just one time when the keyboard initializes. 221// Runs just one time when the keyboard initializes.
214void matrix_init_user(void) { 222void matrix_init_user(void) {
215 uint8_t j;
216 223
217 led_controller_init(); 224 led_controller_init();
218 225
219//TODO: do pages need to be written at init or ok on demand? 226//TODO: do pages need to be written at init or ok on demand?
220 /* Write pages */ 227/* Write pages */
221 for(j=0; j<8; j++) { 228 write_led_page(3, led_nav, 33);
222 is31_write_data(1,(uint8_t *)(led_game+(9*j)),9);
223 chThdSleepMilliseconds(5); 229 chThdSleepMilliseconds(5);
224 is31_write_data(2,(uint8_t *)(led_all+(9*j)),9); 230
231 write_led_page(4, led_numpad, 17);
225 chThdSleepMilliseconds(5); 232 chThdSleepMilliseconds(5);
226 }
227 233
234 write_led_page(5, led_media, 12);
235 chThdSleepMilliseconds(5);
236
237 write_led_page(6, led_game, 5);
238 chThdSleepMilliseconds(5);
228}; 239};
229 240
230// Runs constantly in the background, in a loop. 241// Runs constantly in the background, in a loop.
diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c
index 815a529fc..d2f554549 100644
--- a/keyboards/infinity60/led.c
+++ b/keyboards/infinity60/led.c
@@ -42,12 +42,12 @@ void led_set(uint8_t usb_led) {
42 if (usb_led & (1<<USB_LED_CAPS_LOCK)) { 42 if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
43 // signal the LED control thread 43 // signal the LED control thread
44 chSysUnconditionalLock(); 44 chSysUnconditionalLock();
45 chMBPostI(&led_mailbox, LED_MSG_CAPS_ON); 45 chMBPostI(&led_mailbox, 0x59);
46 chSysUnconditionalUnlock(); 46 chSysUnconditionalUnlock();
47 } else { 47 } else {
48 // signal the LED control thread 48 // signal the LED control thread
49 chSysUnconditionalLock(); 49 chSysUnconditionalLock();
50 chMBPostI(&led_mailbox, LED_MSG_CAPS_OFF); 50 chMBPostI(&led_mailbox, 0x59);
51 chSysUnconditionalUnlock(); 51 chSysUnconditionalUnlock();
52 } 52 }
53} 53}
diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c
index e0350bd93..03f061a20 100644
--- a/keyboards/infinity60/led_controller.c
+++ b/keyboards/infinity60/led_controller.c
@@ -57,7 +57,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
57 * The usual Caps Lock position is C4-6, so the address is 57 * The usual Caps Lock position is C4-6, so the address is
58 * 0x24 + (4-1)*0x10 + (8-1) = 0x59 */ 58 * 0x24 + (4-1)*0x10 + (8-1) = 0x59 */
59#if !defined(CAPS_LOCK_LED_ADDRESS) 59#if !defined(CAPS_LOCK_LED_ADDRESS)
60#define CAPS_LOCK_LED_ADDRESS 0x59 60#define CAPS_LOCK_LED_ADDRESS 0x46
61#endif
62
63#if !defined(NUM_LOCK_LED_ADDRESS)
64#define NUM_LOCK_LED_ADDRESS 0x85
61#endif 65#endif
62 66
63/* Which LED should breathe during sleep */ 67/* Which LED should breathe during sleep */
@@ -85,12 +89,21 @@ uint8_t full_page[0xB4+1] = {0};
85// LED mask (which LEDs are present, selected by bits) 89// LED mask (which LEDs are present, selected by bits)
86// See page comment above, control alternates CA matrix/CB matrix 90// See page comment above, control alternates CA matrix/CB matrix
87// IC60 pcb uses only CA matrix. 91// IC60 pcb uses only CA matrix.
88// Each byte is a control pin for 8 leds 8-1 92// Each byte is a control pin for 8 leds ordered 8-1
89const uint8_t is31_ic60_leds_mask[0x12] = { 93const uint8_t is31_ic60_leds_mask[0x12] = {
90 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 94 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
91 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0x00 95 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0x00
92}; 96};
93 97
98// array to hold brightness pwm steps
99const uint8_t pwm_levels[5] = {
100 0x00, 0x16, 0x4E, 0xA1, 0xFF
101};
102
103// array to write to pwm register
104uint8_t pwm_reg_array[9] = {0};
105
106
94/* ============================ 107/* ============================
95 * communication functions 108 * communication functions
96 * ============================ */ 109 * ============================ */
@@ -109,6 +122,7 @@ msg_t is31_write_register(uint8_t page, uint8_t reg, uint8_t data) {
109 is31_select_page(page); 122 is31_select_page(page);
110 tx[0] = reg; 123 tx[0] = reg;
111 tx[1] = data; 124 tx[1] = data;
125 xprintf("page display: %X\n", page);
112 return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT)); 126 return i2cMasterTransmitTimeout(&I2CD1, IS31_ADDR_DEFAULT, tx, 2, NULL, 0, US2ST(IS31_TIMEOUT));
113} 127}
114 128
@@ -160,98 +174,267 @@ static THD_FUNCTION(LEDthread, arg) {
160 (void)arg; 174 (void)arg;
161 chRegSetThreadName("LEDthread"); 175 chRegSetThreadName("LEDthread");
162 176
163 uint8_t i; 177 uint8_t i, page;
164 uint8_t temp, pwm; 178
165 uint8_t save_page, save_breath1, save_breath2; 179 //persistent status variables
180 uint8_t backlight_status, lock_status, led_step, active_layer;
181 uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes
182
183 //mailbox variables
184 uint8_t temp, msg_type, msg_led;
185 msg_t msg;
186
187/* //control register variables
188 uint8_t page, save_page, save_breath1, save_breath2;
166 msg_t msg, retval; 189 msg_t msg, retval;
190*/
191
192// initialize persistent variables
193backlight_status = 0;
194lock_status = 0;//TODO: does keyboard remember locks?
195led_step = 4; //full brightness
196active_layer = 0;
167 197
168 while(true) { 198 while(true) {
169 // wait for a message (asynchronous) 199 // wait for a message (asynchronous)
170 // (messages are queued (up to LED_MAILBOX_NUM_MSGS) if they can't 200 // (messages are queued (up to LED_MAILBOX_NUM_MSGS) if they can't
171 // be processed right away) 201 // be processed right away)
172 chMBFetch(&led_mailbox, &msg, TIME_INFINITE); 202 chMBFetch(&led_mailbox, &msg, TIME_INFINITE);
203 msg_type = (msg >> 8) & 0xFF; //first byte is msg type
204 msg_led = (msg) & 0xFF; //second byte is action information
173 205
174 // process 'msg' here
175 // if msg between 0-7, then process as page#, otherwise a specific LED address
176 xprintf("--------------------\n"); 206 xprintf("--------------------\n");
177 xprintf("mailbox fetch\ntemp: %X - msg: %X\n", temp, msg); 207 xprintf("mailbox fetch\nmsg: %X\n", msg);
178 if (msg < 8) { 208 xprintf("type: %X - led: %X\n", msg_type, msg_led); //test if msg_type is 1 or 2 bytes after mask
179 209 switch (msg_type){
180 // read current page into 'temp' 210 case KEY_LIGHT:
181 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); 211 //TODO: lighting key led on keypress
182 chThdSleepMilliseconds(1); 212 break;
183 // If page is already in layer, switch off (layer 0) 213
184 xprintf("Layer: post-read\ntemp: %X\n", temp); 214 case TOGGLE_LED:
185 if(temp == msg) { 215 //TODO: toggle existing indicator off, or let user do this, but write frame 7 for every led change
186 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); 216 //turn on single led, msg_led = row/col of led
187 } else { 217 set_led_bit(led_control_reg, msg_led, 1);
188 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg); 218
189 } 219 is31_write_data (7, led_control_reg, 0x12+1);
190 xprintf("Layer: post-change\ntemp: %X\n", temp); 220 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
191 221 active_layer = 7;
192 } else { 222 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
193 223 xprintf("page display: %X\n", temp);
194 switch(msg) { 224 break;
195//TODO: make this generic and able to turn on/off any address and loop through all(or current) pages 225
196//TODO: set number of layers somewhere and loop through all when setting specific led 226 case TOGGLE_ALL:
197 case LED_MSG_SLEEP_LED_ON: 227 xprintf("TOGGLE_ALL\n");
198 // save current settings 228 //msg_led = unused, TODO: consider using msg_led to toggle layer display
199 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &save_page); 229 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
200 is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, &save_breath1); 230
201 is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, &save_breath2); 231 xprintf("temp: %X\n", temp);
202 // use pages 7 and 8 for (hardware) breathing (assuming they're empty) 232 //if LED_ALL is on then toggle off, any other layer, turn on LED_ALL
203 is31_write_register(6, BREATHE_LED_ADDRESS, 0xFF); 233 if(temp == 1) {
204 is31_write_register(7, BREATHE_LED_ADDRESS, 0x00); 234 xprintf("page display true: %X\n", temp);
205 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (6<<4)|6); 235 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0);
206 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3); 236 } else {
207 retval = MSG_TIMEOUT; 237 xprintf("page display false: %X\n", temp);
208 temp = 6; 238 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 1);
209 while(retval == MSG_TIMEOUT) { 239 }
210 // switch to the other page 240 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
211 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, temp); 241 xprintf("page display: %X\n", temp);
212 temp = (temp == 6 ? 7 : 6); 242 break;
213 // the times should be sufficiently long for IS31 to finish switching pages 243
214 retval = chMBFetch(&led_mailbox, &msg, MS2ST(temp == 6 ? 4000 : 6000)); 244 case TOGGLE_BACKLIGHT:
245 //msg_led = unused
246 backlight_status ^= 1;
247 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
248 active_layer = temp;
249
250 page = backlight_status == 0 ? 0 : active_layer;
251 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, page);
252 break;
253
254 case TOGGLE_LAYER_LEDS://show layer indicator or full map of layer keys.
255 //TODO: change so user can flag which they want, indiv or full map in fn_actions
256 //msg_led = layer to toggle on
257 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
258
259 if(temp == msg_led) {
260 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
261 active_layer = 7;
262 } else {
263 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led);
264 active_layer = msg_led;
265 }
266 break;
267
268 case TOGGLE_LOCK_LED:
269 //msg_led = 0-3 for lock flags
270 lock_status ^= msg_led; //TODO: confirm toggling works and doesn't get out of sync
271 set_lock_leds(led_control_reg, lock_status);
272 break;
273
274 case MODE_BREATH:
275 break;
276 case STEP_BRIGHTNESS:
277 //pwm_levels[] bounds checking, loop through array
278 //TODO: find a cleaner way to walk through this logic
279 if (msg_led == 0) {
280 if (led_step == 0) {
281 led_step = 4;
282 } else {
283 led_step--;
215 } 284 }
216 // received a message (should be a wakeup), so restore previous state 285 } else {
217 chThdSleepMilliseconds(3000); // need to wait until the page change finishes 286 if (led_step == 4) {
218 // note: any other messages are queued 287 led_step = 0;
219 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, save_breath1); 288 } else {
220 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, save_breath2); 289 led_step++;
221 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, save_page); 290 }
222 break; 291 }
223 case LED_MSG_SLEEP_LED_OFF: 292
224 // should not get here; wakeup should be received in the branch above break; 293 //TODO: this seems a messy way to populate the pwm register
225 break; 294 //populate the 9 byte rows to be written to each pin, first byte is register (pin) address
226 default: 295 for(i=1; i<9; i++) {
227 if(msg >= 0x24) { 296 pwm_reg_array[i]=pwm_levels[led_step];
228 xprintf("Power pre-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); 297 }
298 for(i=0; i<8; i++) {
299 pwm_reg_array[0] = 0x24 + (i * 0x10);//first byte of 9 bytes must be register address
300 is31_write_data(0, pwm_reg_array, 9);
301 chThdSleepMilliseconds(5);
302 }
303 break;
304
305/* case LED_MSG_SLEEP_LED_ON:
306 // save current settings
307 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &save_page);
308 is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, &save_breath1);
309 is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, &save_breath2);
310 // use pages 7 and 8 for (hardware) breathing (assuming they're empty)
311 is31_write_register(6, BREATHE_LED_ADDRESS, 0xFF);
312 is31_write_register(7, BREATHE_LED_ADDRESS, 0x00);
313 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (6<<4)|6);
314 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
315 retval = MSG_TIMEOUT;
316 temp = 6;
317 while(retval == MSG_TIMEOUT) {
318 // switch to the other page
319 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, temp);
320 temp = (temp == 6 ? 7 : 6);
321 // the times should be sufficiently long for IS31 to finish switching pages
322 retval = chMBFetch(&led_mailbox, &msg, MS2ST(temp == 6 ? 4000 : 6000));
323 }
324 // received a message (should be a wakeup), so restore previous state
325 chThdSleepMilliseconds(3000); // need to wait until the page change finishes
326 // note: any other messages are queued
327 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, save_breath1);
328 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, save_breath2);
329 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, save_page);
330 break;
331 case LED_MSG_SLEEP_LED_OFF:
332 // should not get here; wakeup should be received in the branch above break;
333 break;
334 default:
335 //TODO: individual led state unchanged if page arrays are selected in code above
336 //avoidable if full pages are written on the fly
337 //or use pg8 for individual leds, have pointer to currently on led address for toggling
338 if (msg == 0x59 || msg == 0x84) {
339 //toggle lock keys on all layers
340 for (i=0,i<8,i++) {
229 is31_read_register(0, msg, &temp); 341 is31_read_register(0, msg, &temp);
230 chThdSleepMilliseconds(10);
231 xprintf("Post-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm);
232 chThdSleepMilliseconds(10);
233 pwm = (temp > 0x00 ? 0x00 : 0xFF); 342 pwm = (temp > 0x00 ? 0x00 : 0xFF);
234 xprintf("pwm after: %X\n", pwm); 343 is31_write_register(i,msg,pwm);
235 chThdSleepMilliseconds(10); 344 }
236 for(i=0; i<8; i++) { 345
237 is31_write_register(i, msg, pwm); 346 } else if(msg >= 0x24) {
238 } 347 xprintf("Power pre-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm);
239 xprintf("Power post-change\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm); 348 is31_read_register(7, msg, &temp);
240 chThdSleepMilliseconds(10); 349 xprintf("Post-read\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm);
350 if (msg == active_led) {
351 //toggle led power
352 pwm = (temp > 0x00 ? 0x00 : 0xFF);
353
354 //Use 8th led page for individual led indicators
355 is31_write_register(7, msg, pwm);
356 } else {
357 is31_write_register(7, active_led, 0x00);
358 is31_write_register(7, msg, 0xFF);
359 }
360 xprintf("Power post-change\ntemp: %X - msg: %X - pwm: %X\n", temp, msg, pwm);
361 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
241 } 362 }
242 break; 363 break;
243 } 364*/
244 } 365 }
245 xprintf("--------------------\n"); 366 xprintf("--------------------\n");
246 } 367 }
247} 368}
369
370
371/* ========================
372 * led bit processing
373 * ======================== */
374void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) {
375 uint8_t row_byte, column_bit;
376 //msg_led tens column is pin#, A-control register is every other 8 bits
377 //ones column is bit position in 8-bit mask
378 //control register will be one bit shifted into position along register's full 0x12 bytes
379 ////first byte is register address 0x00
380 row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1;
381 column_bit = 1<<(msg_led % 10 - 1);
382
383 if (toggle_on) {
384 led_control_reg[row_byte] |= 1<<(column_bit);
385 } else {
386 led_control_reg[row_byte] &= ~1<<(column_bit);
387 }
388}
389
390void set_lock_leds(uint8_t *led_control_reg, uint8_t lock_status) {
391 uint8_t i;
392
393 switch (lock_status) {
394 case 1:
395 set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1);//TODO: define lock addresses by matrix#, and loop for all frames
396 set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 0);
397 break;
398 case 2:
399 set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 0);
400 set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 1);
401 break;
402 case 3:
403 set_led_bit(led_control_reg, NUM_LOCK_LED_ADDRESS, 1);
404 set_led_bit(led_control_reg, CAPS_LOCK_LED_ADDRESS, 1);
405 break;
406 }
407
408 for(i=1; i<8; i++) { //keep LED_OFF layer all off, including locks
409 is31_write_data (i, led_control_reg, 0x12+1);
410 chThdSleepMilliseconds(5);
411 }
412}
413
414void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count) {
415//TODO: init function that accepts array of led addresses and sets them by row
416 uint8_t i;
417 uint8_t row, col;
418 uint8_t temp_control_reg[0x13] = {0};//led control register start address + 0x12 bytes
419 xprintf("-------------\n");
420 xprintf("write page %X\n", page);
421
422 for(i=0;i<led_count;i++){
423 row = ((led_array[i] / 10) % 10 - 1 ) * 2 + 1;//includes 1 byte shift for 0x00 address
424 col = 1<<(led_array[i] % 10 - 1);
425
426 temp_control_reg[row] |= 1<<(col);
427 }
428
429 is31_write_data(page, temp_control_reg, 0x13);
430 xprintf("-------------\n");
431}
248/* ===================== 432/* =====================
249 * hook into user keymap 433 * hook into user keymap
250 * ===================== */ 434 * ===================== */
251void led_controller_init(void) { 435void led_controller_init(void) {
252 uint8_t i; 436 uint8_t i;
253 437
254 xprintf("led_controller_init");
255 /* initialise I2C */ 438 /* initialise I2C */
256 /* I2C pins */ 439 /* I2C pins */
257 palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL 440 palSetPadMode(GPIOB, 0, PAL_MODE_ALTERNATIVE_2); // PTB0/I2C0/SCL
@@ -275,14 +458,18 @@ void led_controller_init(void) {
275 is31_write_data(i, full_page, 1+0x12); 458 is31_write_data(i, full_page, 1+0x12);
276 } 459 }
277 460
461 //set Display Option Register so all pwm intensity is controlled from Frame 1
462 is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME);
463
278 /* enable breathing when the displayed page changes */ 464 /* enable breathing when the displayed page changes */
279 // Fade-in Fade-out, time = 26ms * 2^N, N=3 465 // Fade-in Fade-out, time = 26ms * 2^N, N=3
280 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (3<<4)|3); 466 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (3<<4)|3);
281 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3); 467 is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
282 468
283 // clean up the capslock LED 469 // clean up the lock LEDs
284 is31_write_register(1, CAPS_LOCK_LED_ADDRESS, 0); 470 //TODO: adjust for new addressing and additional frames
285 is31_write_register(2, CAPS_LOCK_LED_ADDRESS, 0); 471 //is31_write_register(1, CAPS_LOCK_LED_ADDRESS, 0);
472 //is31_write_register(2, CAPS_LOCK_LED_ADDRESS, 0);
286 473
287 /* more time consuming LED processing should be offloaded into 474 /* more time consuming LED processing should be offloaded into
288 * a thread, with asynchronous messaging. */ 475 * a thread, with asynchronous messaging. */
diff --git a/keyboards/infinity60/led_controller.h b/keyboards/infinity60/led_controller.h
index 7db02389f..75819ec4e 100644
--- a/keyboards/infinity60/led_controller.h
+++ b/keyboards/infinity60/led_controller.h
@@ -26,12 +26,15 @@ msg_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); 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); 27msg_t is31_read_register(uint8_t page, uint8_t reg, uint8_t *result);
28 28
29/* ========================= 29/* ============================
30 * init functions 30 * init functions/definitions
31 * ========================= */ 31 * ============================*/
32 32
33void led_controller_init(void); 33void led_controller_init(void);
34 34
35#define CAPS_LOCK_LED_ADDRESS 0x46
36#define NUM_LOCK_LED_ADDRESS 0x85
37
35/* ============================= 38/* =============================
36 * IS31 chip related definitions 39 * IS31 chip related definitions
37 * ============================= */ 40 * ============================= */
@@ -82,20 +85,26 @@ void led_controller_init(void);
82 85
83#define IS31_TIMEOUT 10000 // needs to be long enough to write a whole page 86#define IS31_TIMEOUT 10000 // needs to be long enough to write a whole page
84 87
85/* ============================== 88/* ========================================
86 * LED Thread related definitions 89 * LED Thread related definitions/functions
87 * ============================== */ 90 * ========================================*/
88 91
89extern mailbox_t led_mailbox; 92extern mailbox_t led_mailbox;
90 93
94void set_led_bit (uint8_t *led_control_reg, uint8_t led_msg, uint8_t toggle_on);
95void set_lock_leds (uint8_t *led_control_reg, uint8_t lock_status);
96void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count);
97
91// constants for signaling the LED controller thread 98// constants for signaling the LED controller thread
92enum led_msg_t { 99enum led_msg_t {
93 LED_MSG_CAPS_ON, 100 KEY_LIGHT,
94 LED_MSG_CAPS_OFF, 101 TOGGLE_LED,
95 LED_MSG_SLEEP_LED_ON, 102 TOGGLE_ALL,
96 LED_MSG_SLEEP_LED_OFF, 103 TOGGLE_BACKLIGHT,
97 LED_MSG_ALL_TOGGLE, 104 TOGGLE_LAYER_LEDS,
98 LED_MSG_GAME_TOGGLE 105 TOGGLE_LOCK_LED,
106 MODE_BREATH,
107 STEP_BRIGHTNESS
99}; 108};
100 109
101#endif /* _LED_CONTROLLER_H_ */ 110#endif /* _LED_CONTROLLER_H_ */