aboutsummaryrefslogtreecommitdiff
path: root/keyboards/infinity60/led_controller.c
diff options
context:
space:
mode:
authorjpetermans <tibcmhhm@gmail.com>2017-04-13 17:15:24 -0700
committerjpetermans <tibcmhhm@gmail.com>2017-04-13 17:15:24 -0700
commit1b1adf35bb746a875c2b846e1b1b405075c94847 (patch)
tree4c7a2530a88175388e04ec06babf2f377afb1460 /keyboards/infinity60/led_controller.c
parent15635817b5ae6068c5c79a9b67a0d97839893a7e (diff)
downloadqmk_firmware-1b1adf35bb746a875c2b846e1b1b405075c94847.tar.gz
qmk_firmware-1b1adf35bb746a875c2b846e1b1b405075c94847.zip
more flexible led processing functions, all and on/off/toggle
functioning
Diffstat (limited to 'keyboards/infinity60/led_controller.c')
-rw-r--r--keyboards/infinity60/led_controller.c147
1 files changed, 88 insertions, 59 deletions
diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c
index ea1449d76..eb3ccafc1 100644
--- a/keyboards/infinity60/led_controller.c
+++ b/keyboards/infinity60/led_controller.c
@@ -91,7 +91,7 @@ uint8_t full_page[0xB4+1] = {0};
91// See page comment above, control alternates CA matrix/CB matrix 91// See page comment above, control alternates CA matrix/CB matrix
92// IC60 pcb uses only CA matrix. 92// IC60 pcb uses only CA matrix.
93// Each byte is a control pin for 8 leds ordered 8-1 93// Each byte is a control pin for 8 leds ordered 8-1
94const uint8_t is31_ic60_leds_mask[0x12] = { 94const uint8_t all_on_leds_mask[0x12] = {
95 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 95 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF,
96 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0x00 96 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0x00, 0x00
97}; 97};
@@ -171,10 +171,11 @@ static THD_FUNCTION(LEDthread, arg) {
171 chRegSetThreadName("LEDthread"); 171 chRegSetThreadName("LEDthread");
172 172
173 uint8_t i, page; 173 uint8_t i, page;
174 uint8_t control_register_word[2] = {0};
175 uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes
174 176
175 //persistent status variables 177 //persistent status variables
176 uint8_t backlight_status, lock_status, led_step_status, layer_status; 178 uint8_t backlight_status, led_step_status, layer_status;
177 uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes
178 179
179 //mailbox variables 180 //mailbox variables
180 uint8_t temp, msg_type, msg_led; 181 uint8_t temp, msg_type, msg_led;
@@ -187,7 +188,6 @@ static THD_FUNCTION(LEDthread, arg) {
187 188
188// initialize persistent variables 189// initialize persistent variables
189backlight_status = 0; 190backlight_status = 0;
190lock_status = 0;//TODO: does keyboard remember locks?
191led_step_status = 4; //full brightness 191led_step_status = 4; //full brightness
192layer_status = 0; 192layer_status = 0;
193 193
@@ -207,34 +207,63 @@ layer_status = 0;
207 //TODO: lighting key led on keypress 207 //TODO: lighting key led on keypress
208 break; 208 break;
209 209
210 //turn on/off/toggle single led, msg_led = row/col of led
211 case OFF_LED:
212 xprintf("OFF_LED\n");
213 set_led_bit(7, control_register_word, msg_led, 0);
214 is31_write_data (7, control_register_word, 0x02);
215 if (layer_status > 0) {//check current led page to prevent double blink
216 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
217 }
218 layer_status = 7;
219 break;
220 case ON_LED:
221 xprintf("ON_LED\n");
222 set_led_bit(7, control_register_word, msg_led, 1);
223 is31_write_data (7, control_register_word, 0x02);
224 if (layer_status > 7) {
225 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
226 }
227 layer_status = 7;
228 break;
210 case TOGGLE_LED: 229 case TOGGLE_LED:
211 //TODO: toggle existing indicator off, or let user do this, but write frame 7 for every led change
212 //turn on single led, msg_led = row/col of led
213 xprintf("TOGGLE_LED\n"); 230 xprintf("TOGGLE_LED\n");
214 set_led_bit(led_control_reg, msg_led, 1); 231 set_led_bit(7, control_register_word, msg_led, 2);
215 232
216 is31_write_data (7, led_control_reg, 0x12+1); 233 is31_write_data (7, control_register_word, 0x02);
217 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); 234 if (layer_status > 7) {
235 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
236 }
218 layer_status = 7; 237 layer_status = 7;
219 break; 238 break;
220 239
221 case TOGGLE_ALL: 240 case TOGGLE_ALL:
222 xprintf("TOGGLE_ALL\n"); 241 xprintf("TOGGLE_ALL\n");
223 //msg_led = unused, TODO: consider using msg_led to toggle layer display 242 //msg_led = unused, TODO: consider using msg_led to toggle layer display
224 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
225 243
226 //if LED_ALL is on then toggle off, any other layer, turn on LED_ALL 244 is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 1 off
227 if(temp == 1) { 245
228 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); 246 led_control_reg[0] = 0;
247 if (temp==0) {
248 xprintf("all leds on");
249 __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12);
229 } else { 250 } else {
230 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 1); 251 xprintf("all leds off");
252 __builtin_memset(led_control_reg+1, 0, 0x12);
231 } 253 }
232 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); 254
255 is31_write_data(0, led_control_reg, 0x13);
256 if (layer_status > 0) {
257 is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0);
258 }
259 layer_status=0;
260 //TODO: Double blink when all on
233 break; 261 break;
234 262
235 case TOGGLE_BACKLIGHT: 263 case TOGGLE_BACKLIGHT:
236 //msg_led = unused 264 //msg_led = unused
237 //TODO: consider Frame 0 as on/off layer and toggle led control register here 265 //TODO: consider Frame 0 as on/off layer and toggle led control register here
266 //TODO: need to test tracking of active layer with layer_state from qmk
238 xprintf("TOGGLE_BACKLIGHT\n"); 267 xprintf("TOGGLE_BACKLIGHT\n");
239 backlight_status ^= 1; 268 backlight_status ^= 1;
240 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); 269 is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
@@ -274,6 +303,7 @@ layer_status = 0;
274 case MODE_BREATH: 303 case MODE_BREATH:
275 break; 304 break;
276 case STEP_BRIGHTNESS: 305 case STEP_BRIGHTNESS:
306 //TEST: Step brightness code
277 //pwm_levels[] bounds checking, loop through array 307 //pwm_levels[] bounds checking, loop through array
278 //TODO: find a cleaner way to walk through this logic 308 //TODO: find a cleaner way to walk through this logic
279 if (msg_led == 0 && led_step_status == 0) { 309 if (msg_led == 0 && led_step_status == 0) {
@@ -336,30 +366,42 @@ layer_status = 0;
336} 366}
337 367
338 368
339/* ======================== 369/* ==============================
340 * led bit processing 370 * led processing functions
341 * ======================== */ 371 * ============================== */
342void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) { 372
343 uint8_t row_byte, column_bit; 373void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint8_t action) {
344 //msg_led tens column is pin# 374 //returns 2 bytes led control register address and byte mask to write
345 //ones column is bit position in 8-bit mask 375
346 //first byte is register address 0x00 376 uint8_t control_reg_addr, column_bit, column_byte, temp;
347 row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1;// A register is every other 8 bits 377 //first byte is led control register address 0x00
348 column_bit = 1<<(msg_led % 10 - 1); 378 //msg_led tens column is pin#, ones column is bit position in 8-bit mask
349 379 control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte
350 if (toggle_on) { 380 column_bit = 1<<(led_addr % 10 - 1);
351 led_control_reg[row_byte] |= 1<<(column_bit); 381
352 } else { 382 is31_read_register(page,control_reg_addr,&temp);//need to maintain status of leds in this row (1 byte)
353 led_control_reg[row_byte] &= ~1<<(column_bit); 383 column_byte = temp;
384
385 switch(action) {
386 case 0:
387 column_byte &= ~1<<(column_bit);
388 break;
389 case 1:
390 column_byte |= 1<<(column_bit);
391 break;
392 case 2:
393 column_byte ^= 1<<(column_bit);
394 break;
354 } 395 }
396
397 led_control_reg[0] = control_reg_addr;
398 led_control_reg[1] = column_byte;
355} 399}
356 400
357//TODO: not toggling off correctly 401void set_lock_leds(uint8_t lock_type, uint8_t led_on) {
358//TODO: confirm led_off page still has FF pwm for all 402 uint8_t page, led_addr;
359void set_lock_leds(uint8_t lock_type, uint8_t lock_status) { 403 uint8_t led_control_write[2] = {0};
360 uint8_t page; 404 //TODO: consolidate control register to top level array vs. three scattered around
361 uint8_t led_addr, temp;
362 uint8_t control_reg[2] = {0};//register address and led bits
363 405
364 switch(lock_type) { 406 switch(lock_type) {
365 case USB_LED_NUM_LOCK: 407 case USB_LED_NUM_LOCK:
@@ -384,44 +426,30 @@ void set_lock_leds(uint8_t lock_type, uint8_t lock_status) {
384 break; 426 break;
385 #endif 427 #endif
386 } 428 }
387 xprintf("led_addr: %X\n", led_addr);
388 chThdSleepMilliseconds(30);
389 control_reg[0] = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte
390 xprintf("control_reg: %X\n", control_reg[0]);
391 chThdSleepMilliseconds(30);
392 429
393 for(page=BACKLIGHT_OFF_LOCK_LED_OFF; page<8; page++) { //set in led_controller.h 430 for(page=BACKLIGHT_OFF_LOCK_LED_OFF; page<8; page++) { //set in led_controller.h
394 is31_read_register(page,control_reg[0],&temp);//need to maintain status of leds in this row (1 byte) 431 //TODO: check if frame2 (or frame1, first byte all on), and ignore if true
395 chThdSleepMilliseconds(30); 432 //also if BACKLIGHT_OFF_LOCK_LED_OFF set
396 xprintf("1lock byte: %X\n", temp); 433 set_led_bit(page,led_control_write,led_addr,led_on);
397 chThdSleepMilliseconds(30); 434 is31_write_data (page, led_control_write, 0x02);
398 if (lock_status) {
399 temp |= 1<<(led_addr % 10 - 1);
400 } else {
401 temp &= ~1<<(led_addr % 10 - 1);
402 }
403 chThdSleepMilliseconds(30);
404 xprintf("2lock byte: %X\n", temp);
405 chThdSleepMilliseconds(30);
406 control_reg[1] = temp;
407 is31_write_data (page, control_reg, 0x02);
408 } 435 }
409} 436}
410 437
411void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count) { 438void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count) {
412 uint8_t i; 439 uint8_t i;
413 uint8_t row, col; 440 uint8_t row, col;
414 uint8_t temp_control_reg[0x13] = {0};//led control register start address + 0x12 bytes 441 uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes
415 442
416 for(i=0;i<led_count;i++){ 443 for(i=0;i<led_count;i++){
417 row = ((led_array[i] / 10) % 10 - 1 ) * 2 + 1;//includes 1 byte shift for led register 0x00 address 444 row = ((led_array[i] / 10) % 10 - 1 ) * 2 + 1;//includes 1 byte shift for led register 0x00 address
418 col = led_array[i] % 10 - 1; 445 col = led_array[i] % 10 - 1;
419 446
420 temp_control_reg[row] |= 1<<(col); 447 led_control_register[row] |= 1<<(col);
421 } 448 }
422 449
423 is31_write_data(page, temp_control_reg, 0x13); 450 is31_write_data(page, led_control_register, 0x13);
424} 451}
452
425/* ===================== 453/* =====================
426 * hook into user keymap 454 * hook into user keymap
427 * ===================== */ 455 * ===================== */
@@ -458,8 +486,9 @@ void led_controller_init(void) {
458 } 486 }
459 487
460 //set all led bits on for Frame 2 LEDS_ALL 488 //set all led bits on for Frame 2 LEDS_ALL
489 //TODO: set all off in init
461 full_page[0] = 0; 490 full_page[0] = 0;
462 __builtin_memcpy(full_page+1, is31_ic60_leds_mask, 0x12); 491 __builtin_memset(full_page+1, 0, 0x12);
463 is31_write_data(1, full_page, 1+0x12); 492 is31_write_data(1, full_page, 1+0x12);
464 493
465 /* enable breathing when the displayed page changes */ 494 /* enable breathing when the displayed page changes */