From 1b1adf35bb746a875c2b846e1b1b405075c94847 Mon Sep 17 00:00:00 2001 From: jpetermans Date: Thu, 13 Apr 2017 17:15:24 -0700 Subject: [PATCH] more flexible led processing functions, all and on/off/toggle functioning --- .../infinity60/keymaps/jpetermans/keymap.c | 4 +- keyboards/infinity60/led.c | 14 +- keyboards/infinity60/led_controller.c | 147 +++++++++++------- keyboards/infinity60/led_controller.h | 10 +- 4 files changed, 97 insertions(+), 78 deletions(-) diff --git a/keyboards/infinity60/keymaps/jpetermans/keymap.c b/keyboards/infinity60/keymaps/jpetermans/keymap.c index 2eb66b50..6f14b66c 100644 --- a/keyboards/infinity60/keymaps/jpetermans/keymap.c +++ b/keyboards/infinity60/keymaps/jpetermans/keymap.c @@ -210,14 +210,14 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) { case ACTION_LEDS_NAV: if(record->event.pressed) { // signal the LED controller thread - msg=(TOGGLE_LAYER_LEDS << 8) | 3; + msg=(OFF_LED << 8) | 12; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; case ACTION_LEDS_NUMPAD: if(record->event.pressed) { // signal the LED controller thread - msg=(TOGGLE_LAYER_LEDS << 8) | 4; + msg=(ON_LED << 8) | 12; chMBPost(&led_mailbox, msg, TIME_IMMEDIATE); } break; diff --git a/keyboards/infinity60/led.c b/keyboards/infinity60/led.c index c78e2d11..92069dc5 100644 --- a/keyboards/infinity60/led.c +++ b/keyboards/infinity60/led.c @@ -16,7 +16,6 @@ along with this program. If not, see . */ #include "hal.h" -#include "print.h" #include "led.h" @@ -28,16 +27,7 @@ along with this program. If not, see . */ void led_set(uint8_t usb_led) { msg_t msg; -/* - // PTA5: LED (1:on/0:off) - GPIOA->PDDR |= (1<<1); - PORTA->PCR[5] |= PORTx_PCRn_DSE | PORTx_PCRn_MUX(1); - if (usb_led & (1<PSOR |= (1<<5); - } else { - GPIOA->PCOR |= (1<<5); - } - */ + if (usb_led & (1< 0) {//check current led page to prevent double blink + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + } + layer_status = 7; + break; + case ON_LED: + xprintf("ON_LED\n"); + set_led_bit(7, control_register_word, msg_led, 1); + is31_write_data (7, control_register_word, 0x02); + if (layer_status > 7) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + } + layer_status = 7; + break; case TOGGLE_LED: - //TODO: toggle existing indicator off, or let user do this, but write frame 7 for every led change - //turn on single led, msg_led = row/col of led xprintf("TOGGLE_LED\n"); - set_led_bit(led_control_reg, msg_led, 1); + set_led_bit(7, control_register_word, msg_led, 2); - is31_write_data (7, led_control_reg, 0x12+1); - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + is31_write_data (7, control_register_word, 0x02); + if (layer_status > 7) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7); + } layer_status = 7; break; case TOGGLE_ALL: xprintf("TOGGLE_ALL\n"); //msg_led = unused, TODO: consider using msg_led to toggle layer display - is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); - //if LED_ALL is on then toggle off, any other layer, turn on LED_ALL - if(temp == 1) { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); + is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 1 off + + led_control_reg[0] = 0; + if (temp==0) { + xprintf("all leds on"); + __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12); } else { - is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 1); + xprintf("all leds off"); + __builtin_memset(led_control_reg+1, 0, 0x12); } - is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); + + is31_write_data(0, led_control_reg, 0x13); + if (layer_status > 0) { + is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0); + } + layer_status=0; + //TODO: Double blink when all on break; case TOGGLE_BACKLIGHT: //msg_led = unused //TODO: consider Frame 0 as on/off layer and toggle led control register here + //TODO: need to test tracking of active layer with layer_state from qmk xprintf("TOGGLE_BACKLIGHT\n"); backlight_status ^= 1; is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp); @@ -274,6 +303,7 @@ layer_status = 0; case MODE_BREATH: break; case STEP_BRIGHTNESS: + //TEST: Step brightness code //pwm_levels[] bounds checking, loop through array //TODO: find a cleaner way to walk through this logic if (msg_led == 0 && led_step_status == 0) { @@ -336,30 +366,42 @@ layer_status = 0; } -/* ======================== - * led bit processing - * ======================== */ -void set_led_bit (uint8_t *led_control_reg, uint8_t msg_led, uint8_t toggle_on) { - uint8_t row_byte, column_bit; - //msg_led tens column is pin# - //ones column is bit position in 8-bit mask - //first byte is register address 0x00 - row_byte = ((msg_led / 10) % 10 - 1 ) * 2 + 1;// A register is every other 8 bits - column_bit = 1<<(msg_led % 10 - 1); - - if (toggle_on) { - led_control_reg[row_byte] |= 1<<(column_bit); - } else { - led_control_reg[row_byte] &= ~1<<(column_bit); +/* ============================== + * led processing functions + * ============================== */ + +void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint8_t action) { + //returns 2 bytes led control register address and byte mask to write + + uint8_t control_reg_addr, column_bit, column_byte, temp; + //first byte is led control register address 0x00 + //msg_led tens column is pin#, ones column is bit position in 8-bit mask + control_reg_addr = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte + column_bit = 1<<(led_addr % 10 - 1); + + is31_read_register(page,control_reg_addr,&temp);//need to maintain status of leds in this row (1 byte) + column_byte = temp; + + switch(action) { + case 0: + column_byte &= ~1<<(column_bit); + break; + case 1: + column_byte |= 1<<(column_bit); + break; + case 2: + column_byte ^= 1<<(column_bit); + break; } + + led_control_reg[0] = control_reg_addr; + led_control_reg[1] = column_byte; } -//TODO: not toggling off correctly -//TODO: confirm led_off page still has FF pwm for all -void set_lock_leds(uint8_t lock_type, uint8_t lock_status) { - uint8_t page; - uint8_t led_addr, temp; - uint8_t control_reg[2] = {0};//register address and led bits +void set_lock_leds(uint8_t lock_type, uint8_t led_on) { + uint8_t page, led_addr; + uint8_t led_control_write[2] = {0}; + //TODO: consolidate control register to top level array vs. three scattered around switch(lock_type) { case USB_LED_NUM_LOCK: @@ -384,44 +426,30 @@ void set_lock_leds(uint8_t lock_type, uint8_t lock_status) { break; #endif } - xprintf("led_addr: %X\n", led_addr); - chThdSleepMilliseconds(30); - control_reg[0] = ((led_addr / 10) % 10 - 1 ) * 0x02;// A-register is every other byte - xprintf("control_reg: %X\n", control_reg[0]); - chThdSleepMilliseconds(30); for(page=BACKLIGHT_OFF_LOCK_LED_OFF; page<8; page++) { //set in led_controller.h - is31_read_register(page,control_reg[0],&temp);//need to maintain status of leds in this row (1 byte) - chThdSleepMilliseconds(30); - xprintf("1lock byte: %X\n", temp); - chThdSleepMilliseconds(30); - if (lock_status) { - temp |= 1<<(led_addr % 10 - 1); - } else { - temp &= ~1<<(led_addr % 10 - 1); - } - chThdSleepMilliseconds(30); - xprintf("2lock byte: %X\n", temp); - chThdSleepMilliseconds(30); - control_reg[1] = temp; - is31_write_data (page, control_reg, 0x02); + //TODO: check if frame2 (or frame1, first byte all on), and ignore if true + //also if BACKLIGHT_OFF_LOCK_LED_OFF set + set_led_bit(page,led_control_write,led_addr,led_on); + is31_write_data (page, led_control_write, 0x02); } } void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count) { uint8_t i; uint8_t row, col; - uint8_t temp_control_reg[0x13] = {0};//led control register start address + 0x12 bytes + uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes for(i=0;i