diff options
Diffstat (limited to 'keyboards/infinity60/led_controller.c')
| -rw-r--r-- | keyboards/infinity60/led_controller.c | 333 |
1 files changed, 260 insertions, 73 deletions
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 |
| 89 | const uint8_t is31_ic60_leds_mask[0x12] = { | 93 | const 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 | ||
| 99 | const uint8_t pwm_levels[5] = { | ||
| 100 | 0x00, 0x16, 0x4E, 0xA1, 0xFF | ||
| 101 | }; | ||
| 102 | |||
| 103 | // array to write to pwm register | ||
| 104 | uint8_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 | ||
| 193 | backlight_status = 0; | ||
| 194 | lock_status = 0;//TODO: does keyboard remember locks? | ||
| 195 | led_step = 4; //full brightness | ||
| 196 | active_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 | * ======================== */ | ||
| 374 | void 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 | |||
| 390 | void 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 | |||
| 414 | void 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 | * ===================== */ |
| 251 | void led_controller_init(void) { | 435 | void 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. */ |
