diff options
| author | jpetermans <tibcmhhm@gmail.com> | 2017-04-15 14:37:55 -0700 |
|---|---|---|
| committer | jpetermans <tibcmhhm@gmail.com> | 2017-04-15 14:37:55 -0700 |
| commit | 046f1baf30f046922f0918b1957f810f1610333e (patch) | |
| tree | de7ef655444e9d6947f98dee39d99dec2a91d05d /keyboards/infinity60/led_controller.c | |
| parent | c0ec1756afda7a49848faff23781bf54cd9fa3c3 (diff) | |
| download | qmk_firmware-046f1baf30f046922f0918b1957f810f1610333e.tar.gz qmk_firmware-046f1baf30f046922f0918b1957f810f1610333e.zip | |
more stable lock led process, added debugging code
Diffstat (limited to 'keyboards/infinity60/led_controller.c')
| -rw-r--r-- | keyboards/infinity60/led_controller.c | 117 |
1 files changed, 70 insertions, 47 deletions
diff --git a/keyboards/infinity60/led_controller.c b/keyboards/infinity60/led_controller.c index cb91f9f35..d88ae14b1 100644 --- a/keyboards/infinity60/led_controller.c +++ b/keyboards/infinity60/led_controller.c | |||
| @@ -70,6 +70,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
| 70 | #define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS | 70 | #define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS |
| 71 | #endif | 71 | #endif |
| 72 | 72 | ||
| 73 | #define DEBUG_ENABLED 1 | ||
| 74 | |||
| 73 | /* ================= | 75 | /* ================= |
| 74 | * ChibiOS I2C setup | 76 | * ChibiOS I2C setup |
| 75 | * ================= */ | 77 | * ================= */ |
| @@ -171,11 +173,11 @@ static THD_FUNCTION(LEDthread, arg) { | |||
| 171 | chRegSetThreadName("LEDthread"); | 173 | chRegSetThreadName("LEDthread"); |
| 172 | 174 | ||
| 173 | uint8_t i, j, page; | 175 | uint8_t i, j, page; |
| 174 | uint8_t control_register_word[2] = {0};//register address - byte to write | 176 | uint8_t control_register_word[2] = {0};//2 bytes: register address, byte to write |
| 175 | uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes | 177 | uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes |
| 176 | 178 | ||
| 177 | //persistent status variables | 179 | //persistent status variables |
| 178 | uint8_t backlight_status, pwm_step_status, layer_status; | 180 | uint8_t backlight_status, pwm_step_status, page_status; |
| 179 | 181 | ||
| 180 | //mailbox variables | 182 | //mailbox variables |
| 181 | uint8_t temp, msg_type, msg_led; | 183 | uint8_t temp, msg_type, msg_led; |
| @@ -189,7 +191,7 @@ static THD_FUNCTION(LEDthread, arg) { | |||
| 189 | // initialize persistent variables | 191 | // initialize persistent variables |
| 190 | backlight_status = 0; //start backlight off | 192 | backlight_status = 0; //start backlight off |
| 191 | pwm_step_status = 4; //full brightness | 193 | pwm_step_status = 4; //full brightness |
| 192 | layer_status = 0; //start frame 0 (all off/on) | 194 | page_status = 0; //start frame 0 (all off/on) |
| 193 | 195 | ||
| 194 | while(true) { | 196 | while(true) { |
| 195 | // wait for a message (asynchronous) | 197 | // wait for a message (asynchronous) |
| @@ -201,74 +203,89 @@ layer_status = 0; //start frame 0 (all off/on) | |||
| 201 | 203 | ||
| 202 | xprintf("--------------------\n"); | 204 | xprintf("--------------------\n"); |
| 203 | xprintf("mailbox fetch\nmsg: %X\n", msg); | 205 | xprintf("mailbox fetch\nmsg: %X\n", msg); |
| 204 | xprintf("type: %X - led: %X\n", msg_type, msg_led); //test if msg_type is 1 or 2 bytes after mask | 206 | xprintf("type: %X - led: %X\n", msg_type, msg_led); |
| 205 | 207 | ||
| 206 | switch (msg_type){ | 208 | switch (msg_type){ |
| 207 | case KEY_LIGHT: | 209 | case KEY_LIGHT: |
| 208 | //TODO: lighting key led on keypress | 210 | //TODO: lighting key led on keypress |
| 209 | break; | 211 | break; |
| 210 | 212 | ||
| 211 | //turn on/off/toggle single led, msg_led = row/col of led | ||
| 212 | case OFF_LED: | 213 | case OFF_LED: |
| 214 | //on/off/toggle single led, msg_led = row/col of led | ||
| 213 | xprintf("OFF_LED\n"); | 215 | xprintf("OFF_LED\n"); |
| 214 | set_led_bit(7, control_register_word, msg_led, 0); | 216 | set_led_bit(7, control_register_word, msg_led, 0); |
| 215 | is31_write_data (7, control_register_word, 0x02); | 217 | is31_write_data (7, control_register_word, 0x02); |
| 216 | if (layer_status > 0) {//check current led page to prevent double blink | 218 | |
| 219 | if (page_status < 7) { | ||
| 217 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); | 220 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); |
| 218 | } | 221 | } |
| 219 | layer_status = 7; | 222 | page_status = 7; |
| 220 | break; | 223 | break; |
| 224 | |||
| 221 | case ON_LED: | 225 | case ON_LED: |
| 222 | xprintf("ON_LED\n"); | 226 | xprintf("ON_LED\n"); |
| 223 | set_led_bit(7, control_register_word, msg_led, 1); | 227 | set_led_bit(7, control_register_word, msg_led, 1); |
| 224 | is31_write_data (7, control_register_word, 0x02); | 228 | is31_write_data (7, control_register_word, 0x02); |
| 225 | if (layer_status > 7) { | 229 | |
| 230 | if (page_status < 7) {//check current led page to prevent double blink | ||
| 226 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); | 231 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); |
| 227 | } | 232 | } |
| 228 | layer_status = 7; | 233 | page_status = 7; |
| 229 | break; | 234 | break; |
| 235 | |||
| 230 | case TOGGLE_LED: | 236 | case TOGGLE_LED: |
| 231 | xprintf("TOGGLE_LED\n"); | 237 | xprintf("TOGGLE_LED\n"); |
| 232 | set_led_bit(7, control_register_word, msg_led, 2); | 238 | set_led_bit(7, control_register_word, msg_led, 2); |
| 233 | 239 | ||
| 234 | is31_write_data (7, control_register_word, 0x02); | 240 | is31_write_data (7, control_register_word, 0x02); |
| 235 | if (layer_status > 7) { | 241 | if (page_status > 7) { |
| 236 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); | 242 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); |
| 237 | } | 243 | } |
| 238 | layer_status = 7; | 244 | page_status = 7; |
| 239 | break; | 245 | break; |
| 240 | 246 | ||
| 241 | case TOGGLE_ALL: | 247 | case TOGGLE_ALL: |
| 242 | xprintf("TOGGLE_ALL\n"); | 248 | xprintf("TOGGLE_ALL\n"); |
| 243 | //msg_led = unused | 249 | //msg_led = unused |
| 244 | 250 | ||
| 245 | is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 1 off | 251 | is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 0 off |
| 246 | 252 | ||
| 247 | led_control_reg[0] = 0; | 253 | led_control_reg[0] = 0; |
| 248 | if (temp==0) { | 254 | if (temp==0 || page_status > 0) { |
| 249 | xprintf("all leds on"); | 255 | xprintf("all leds on"); |
| 250 | __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); | 256 | __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); |
| 251 | } else { | 257 | } else { |
| 252 | xprintf("all leds off"); | 258 | xprintf("all leds off"); |
| 253 | __builtin_memset(led_control_reg+1, 0, 0x12); | 259 | __builtin_memset(led_control_reg+1, 0, 0x12); |
| 254 | } | 260 | } |
| 255 | 261 | ||
| 256 | is31_write_data(0, led_control_reg, 0x13); | 262 | is31_write_data(0, led_control_reg, 0x13); |
| 257 | if (layer_status > 0) { | 263 | if (page_status > 0) { |
| 258 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); | 264 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); |
| 259 | } | 265 | } |
| 260 | layer_status=0; | 266 | |
| 267 | //maintain lock leds | ||
| 268 | if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) { | ||
| 269 | set_lock_leds(USB_LED_NUM_LOCK, 1); | ||
| 270 | } | ||
| 271 | if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) { | ||
| 272 | set_lock_leds(USB_LED_CAPS_LOCK, 1); | ||
| 273 | } | ||
| 274 | |||
| 275 | page_status=0; | ||
| 261 | break; | 276 | break; |
| 262 | 277 | ||
| 263 | case TOGGLE_BACKLIGHT: | 278 | case TOGGLE_BACKLIGHT: |
| 264 | //msg_led = unused | 279 | //msg_led = unused |
| 265 | //TODO: need to test tracking of active layer with layer_state from qmk | 280 | //TODO: need to test tracking of active layer with layer_state from qmk |
| 281 | //TODO: this code still assumes on/off frame 0/1, combine this with | ||
| 282 | //toggle_all with 0,1,2 msg_leds for off/on/toggle-current? | ||
| 266 | xprintf("TOGGLE_BACKLIGHT\n"); | 283 | xprintf("TOGGLE_BACKLIGHT\n"); |
| 267 | backlight_status ^= 1; | 284 | backlight_status ^= 1; |
| 268 | is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); | 285 | is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); |
| 269 | layer_status = temp; | 286 | page_status = temp; |
| 270 | 287 | ||
| 271 | page = backlight_status == 0 ? 0 : layer_status; | 288 | page = backlight_status == 0 ? 0 : page_status; |
| 272 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, page); | 289 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, page); |
| 273 | break; | 290 | break; |
| 274 | 291 | ||
| @@ -279,10 +296,10 @@ layer_status = 0; //start frame 0 (all off/on) | |||
| 279 | 296 | ||
| 280 | if(temp == msg_led) { | 297 | if(temp == msg_led) { |
| 281 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); | 298 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); |
| 282 | layer_status = 7; | 299 | page_status = 7; |
| 283 | } else { | 300 | } else { |
| 284 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); | 301 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led); |
| 285 | layer_status = msg_led; | 302 | page_status = msg_led; |
| 286 | } | 303 | } |
| 287 | break; | 304 | break; |
| 288 | 305 | ||
| @@ -301,8 +318,6 @@ layer_status = 0; //start frame 0 (all off/on) | |||
| 301 | case STEP_BRIGHTNESS: | 318 | case STEP_BRIGHTNESS: |
| 302 | xprintf("TOGGLE_BACKLIGHT\n"); | 319 | xprintf("TOGGLE_BACKLIGHT\n"); |
| 303 | //led_msg = step pwm up or down | 320 | //led_msg = step pwm up or down |
| 304 | //TODO: test step brightness code | ||
| 305 | //pwm_levels[] bounds checking, loop through array | ||
| 306 | switch (msg_led) { | 321 | switch (msg_led) { |
| 307 | case 0: | 322 | case 0: |
| 308 | if (pwm_step_status == 0) { | 323 | if (pwm_step_status == 0) { |
| @@ -327,8 +342,6 @@ layer_status = 0; //start frame 0 (all off/on) | |||
| 327 | for(i=0; i<8; i++) { | 342 | for(i=0; i<8; i++) { |
| 328 | //first byte is register address, every 0x10 9 bytes is A-register pwm pins | 343 | //first byte is register address, every 0x10 9 bytes is A-register pwm pins |
| 329 | pwm_register_array[0] = 0x24 + (i * 0x10); | 344 | pwm_register_array[0] = 0x24 + (i * 0x10); |
| 330 | for(j=0; j<9; j++) { | ||
| 331 | } | ||
| 332 | is31_write_data(0,pwm_register_array,9); | 345 | is31_write_data(0,pwm_register_array,9); |
| 333 | } | 346 | } |
| 334 | break; | 347 | break; |
| @@ -365,6 +378,26 @@ layer_status = 0; //start frame 0 (all off/on) | |||
| 365 | */ | 378 | */ |
| 366 | xprintf("--------------------\n"); | 379 | xprintf("--------------------\n"); |
| 367 | } | 380 | } |
| 381 | #ifdef DEBUG_ENABLED | ||
| 382 | //debugging code - print full led/blink/pwm registers on each frame | ||
| 383 | for(i=0;i<8;i++) { | ||
| 384 | xprintf("page: %d", i); | ||
| 385 | for(j=0;j<0xB4;j++){ | ||
| 386 | is31_read_register(i,j,&temp); | ||
| 387 | chThdSleepMilliseconds(1); | ||
| 388 | xprintf("%02X, ", temp); | ||
| 389 | if(j % 9 == 0){ | ||
| 390 | xprintf("\n", temp); | ||
| 391 | if(j % 18 ==0){ | ||
| 392 | xprintf("register", temp); | ||
| 393 | xprintf("\n", temp); | ||
| 394 | } | ||
| 395 | } | ||
| 396 | chThdSleepMilliseconds(1); | ||
| 397 | } | ||
| 398 | xprintf("\n", temp); | ||
| 399 | } | ||
| 400 | #endif | ||
| 368 | } | 401 | } |
| 369 | } | 402 | } |
| 370 | 403 | ||
| @@ -376,46 +409,34 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint | |||
| 376 | //returns 2 bytes led control register address and byte mask to write | 409 | //returns 2 bytes led control register address and byte mask to write |
| 377 | 410 | ||
| 378 | uint8_t control_reg_addr, column_bit, column_byte, temp; | 411 | uint8_t control_reg_addr, column_bit, column_byte, temp; |
| 412 | // | ||
| 379 | //first byte is led control register address 0x00 | 413 | //first byte is led control register address 0x00 |
| 380 | //msg_led tens column is pin#, ones column is bit position in 8-bit mask | 414 | //msg_led tens column is pin#, ones column is bit position in 8-bit mask |
| 381 | chThdSleepMilliseconds(10); | ||
| 382 | xprintf("led_addr: %d ", led_addr); | ||
| 383 | control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte | 415 | control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte |
| 384 | column_bit = 1<<(led_addr % 10 - 1); | 416 | column_bit = 1<<(led_addr % 10 - 1); |
| 385 | 417 | ||
| 386 | is31_read_register(page,control_reg_addr,&temp);//need to maintain status of leds in this row (1 byte) | 418 | is31_read_register(page,control_reg_addr,&temp);//need to maintain status of leds in this row (1 byte) |
| 387 | chThdSleepMilliseconds(10); | ||
| 388 | xprintf("col_bit: %X ", column_bit); | ||
| 389 | column_byte = temp; | 419 | column_byte = temp; |
| 390 | 420 | ||
| 391 | chThdSleepMilliseconds(10); | ||
| 392 | xprintf("action: %X ", action); | ||
| 393 | switch(action) { | 421 | switch(action) { |
| 394 | case 0: | 422 | case 0: |
| 395 | xprintf("off-"); | ||
| 396 | chThdSleepMilliseconds(10); | ||
| 397 | column_byte &= ~column_bit; | 423 | column_byte &= ~column_bit; |
| 398 | break; | 424 | break; |
| 399 | case 1: | 425 | case 1: |
| 400 | xprintf("on-"); | ||
| 401 | chThdSleepMilliseconds(10); | ||
| 402 | column_byte |= column_bit; | 426 | column_byte |= column_bit; |
| 403 | break; | 427 | break; |
| 404 | case 2: | 428 | case 2: |
| 405 | xprintf("toggle-"); | ||
| 406 | chThdSleepMilliseconds(10); | ||
| 407 | column_byte ^= column_bit; | 429 | column_byte ^= column_bit; |
| 408 | break; | 430 | break; |
| 409 | } | 431 | } |
| 410 | 432 | ||
| 433 | //return word to be written in register | ||
| 411 | led_control_reg[0] = control_reg_addr; | 434 | led_control_reg[0] = control_reg_addr; |
| 412 | led_control_reg[1] = column_byte; | 435 | led_control_reg[1] = column_byte; |
| 413 | chThdSleepMilliseconds(10); | ||
| 414 | xprintf("set_bit row: %X set_bit col: %X\n", led_control_reg[0], led_control_reg[1]); | ||
| 415 | } | 436 | } |
| 416 | 437 | ||
| 417 | void set_lock_leds(uint8_t lock_type, uint8_t led_on) { | 438 | void set_lock_leds(uint8_t lock_type, uint8_t led_on) { |
| 418 | uint8_t page, led_addr; | 439 | uint8_t page, led_addr, start, temp; |
| 419 | uint8_t led_control_write[2] = {0}; | 440 | uint8_t led_control_write[2] = {0}; |
| 420 | //TODO: consolidate control register to top level array vs. three scattered around | 441 | //TODO: consolidate control register to top level array vs. three scattered around |
| 421 | 442 | ||
| @@ -443,13 +464,13 @@ void set_lock_leds(uint8_t lock_type, uint8_t led_on) { | |||
| 443 | #endif | 464 | #endif |
| 444 | } | 465 | } |
| 445 | 466 | ||
| 446 | for(page=0; page<8; page++) { //set in led_controller.h | 467 | //ignore frame0 if all leds are on or if option set in led_controller.h |
| 447 | //TODO: check if frame2 (or frame1, first byte all on), and ignore if true | 468 | is31_read_register(0, 0x00, &temp); |
| 448 | //also if BACKLIGHT_OFF_LOCK_LED_OFF set | 469 | start = (temp>0 || BACKLIGHT_OFF_LOCK_LED_OFF) ? 1 : 0; |
| 470 | |||
| 471 | for(page=start; page<8; page++) { | ||
| 449 | set_led_bit(page,led_control_write,led_addr,led_on); | 472 | set_led_bit(page,led_control_write,led_addr,led_on); |
| 450 | xprintf("lock_led row: %X lock_led col%X\n", led_control_write[0], led_control_write[1]); | ||
| 451 | is31_write_data(page, led_control_write, 0x02); | 473 | is31_write_data(page, led_control_write, 0x02); |
| 452 | chThdSleepMilliseconds(10); | ||
| 453 | } | 474 | } |
| 454 | } | 475 | } |
| 455 | 476 | ||
| @@ -458,8 +479,10 @@ void write_led_page (uint8_t page, const uint8_t *user_led_array, uint8_t led_co | |||
| 458 | uint8_t row, col; | 479 | uint8_t row, col; |
| 459 | uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes | 480 | uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes |
| 460 | 481 | ||
| 482 | __builtin_memset(led_control_register,0,13); | ||
| 483 | |||
| 461 | for(i=0;i<led_count;i++){ | 484 | for(i=0;i<led_count;i++){ |
| 462 | row = ((user_led_array[i] / 10) % 10 - 1 ) * 2 + 1;//includes 1 byte shift for led register 0x00 address | 485 | row = ((user_led_array[i] / 10) % 10 - 1 ) * 2 + 1;// 1 byte shift for led register 0x00 address |
| 463 | col = user_led_array[i] % 10 - 1; | 486 | col = user_led_array[i] % 10 - 1; |
| 464 | 487 | ||
| 465 | led_control_register[row] |= 1<<(col); | 488 | led_control_register[row] |= 1<<(col); |
| @@ -490,7 +513,7 @@ void led_controller_init(void) { | |||
| 490 | /* initialise IS31 chip */ | 513 | /* initialise IS31 chip */ |
| 491 | is31_init(); | 514 | is31_init(); |
| 492 | 515 | ||
| 493 | //set Display Option Register so all pwm intensity is controlled from Frame 1 | 516 | //set Display Option Register so all pwm intensity is controlled from Frame 0 |
| 494 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME); | 517 | is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME); |
| 495 | 518 | ||
| 496 | //TODO: test new init pwm loop | 519 | //TODO: test new init pwm loop |
