]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Simplified processing in led_controller; more control at user level.
authorjpetermans <tibcmhhm@gmail.com>
Thu, 27 Apr 2017 06:12:25 +0000 (23:12 -0700)
committerjpetermans <tibcmhhm@gmail.com>
Thu, 27 Apr 2017 06:12:25 +0000 (23:12 -0700)
keyboards/infinity60/led_controller.c
keyboards/infinity60/led_controller.h

index d88ae14b15a6f52b6a1eb729da370bbc84abc676..4dc9b92342747c2653fe50f0ba10ff9869fd6c8d 100644 (file)
@@ -25,6 +25,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #include "hal.h"
 #include "print.h"
 #include "led.h"
+#include "action_layer.h"
+#include "host.h"
 
 #include "led_controller.h"
 
@@ -70,7 +72,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #define BREATHE_LED_ADDRESS CAPS_LOCK_LED_ADDRESS
 #endif
 
-#define DEBUG_ENABLED 1
+#define DEBUG_ENABLED 0
 
 /* =================
  * ChibiOS I2C setup
@@ -172,12 +174,12 @@ static THD_FUNCTION(LEDthread, arg) {
   (void)arg;
   chRegSetThreadName("LEDthread");
 
-  uint8_t i, j, page;
+  uint8_t i;
   uint8_t control_register_word[2] = {0};//2 bytes: register address, byte to write
   uint8_t led_control_reg[0x13] = {0};//led control register start address + 0x12 bytes
 
   //persistent status variables
-  uint8_t backlight_status, pwm_step_status, page_status;
+  uint8_t pwm_step_status, page_status;
 
   //mailbox variables
   uint8_t temp, msg_type, msg_led;
@@ -189,7 +191,6 @@ static THD_FUNCTION(LEDthread, arg) {
 */
 
 // initialize persistent variables
-backlight_status = 0; //start backlight off
 pwm_step_status = 4; //full brightness
 page_status = 0; //start frame 0 (all off/on)
 
@@ -202,68 +203,63 @@ page_status = 0; //start frame 0 (all off/on)
     msg_led = (msg) & 0xFF; //second byte is action information
 
     xprintf("--------------------\n");
+            chThdSleepMilliseconds(10);
     xprintf("mailbox fetch\nmsg: %X\n", msg);
+            chThdSleepMilliseconds(10);
     xprintf("type: %X - led: %X\n", msg_type, msg_led); 
+            chThdSleepMilliseconds(10);
 
     switch (msg_type){
       case KEY_LIGHT:
       //TODO: lighting key led on keypress
       break;
       
+      //TODO: custom page that is written using keypresses
+      //TODO: BLINK_ON/OFF_LED
+
       case OFF_LED:      
       //on/off/toggle single led, msg_led = row/col of led
       xprintf("OFF_LED\n");
+            chThdSleepMilliseconds(10);
         set_led_bit(7, control_register_word, msg_led, 0);
         is31_write_data (7, control_register_word, 0x02);
-
-        if (page_status < 7) {
-          is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
-        }
-        page_status = 7;
         break;
 
       case ON_LED:      
       xprintf("ON_LED\n");
+            chThdSleepMilliseconds(10);
         set_led_bit(7, control_register_word, msg_led, 1);
         is31_write_data (7, control_register_word, 0x02);
-
-        if (page_status < 7) {//check current led page to prevent double blink
-          is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
-        }
-        page_status = 7;
         break;
 
       case TOGGLE_LED:      
       xprintf("TOGGLE_LED\n");
+            chThdSleepMilliseconds(10);
         set_led_bit(7, control_register_word, msg_led, 2);
-
         is31_write_data (7, control_register_word, 0x02);
-        if (page_status > 7) {
-          is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
-        }
-        page_status = 7;
         break;
 
       case TOGGLE_ALL:
       xprintf("TOGGLE_ALL\n");
+            chThdSleepMilliseconds(10);
         //msg_led = unused
-
         is31_read_register(0, 0x00, &temp);//if first byte is on, then toggle frame 0 off
-
         led_control_reg[0] = 0;
         if (temp==0 || page_status > 0) {
           xprintf("all leds on");
+            chThdSleepMilliseconds(10);
           __builtin_memcpy(led_control_reg+1, all_on_leds_mask, 0x12);
         } else {
           xprintf("all leds off");
+            chThdSleepMilliseconds(10);
           __builtin_memset(led_control_reg+1, 0, 0x12);
         }
-
         is31_write_data(0, led_control_reg, 0x13);
+
         if (page_status > 0) {
           is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 0);
         }
-        
+
         //maintain lock leds
         if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) {
           set_lock_leds(USB_LED_NUM_LOCK, 1);
@@ -276,30 +272,46 @@ page_status = 0; //start frame 0 (all off/on)
         break;
 
       case TOGGLE_BACKLIGHT:
-        //msg_led = unused
-        //TODO: need to test tracking of active layer with layer_state from qmk
-        //TODO: this code still assumes on/off frame 0/1, combine this with
-        //toggle_all with 0,1,2 msg_leds for off/on/toggle-current?
+        //msg_led = on/off
       xprintf("TOGGLE_BACKLIGHT\n");
-        backlight_status ^= 1;
-        is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
-        page_status = temp;
+            chThdSleepMilliseconds(10);
 
-        page = backlight_status == 0 ? 0 : page_status;
-        is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, page);
+        //populate the 9 byte rows to be written to each pin, first byte is register (pin) address
+        if (msg_led == 1) {
+          __builtin_memset(pwm_register_array+1, pwm_levels[pwm_step_status], 8);
+        } else {
+          __builtin_memset(pwm_register_array+1, 0, 8);
+        }
+
+        for(i=0; i<8; i++) {
+        //first byte is register address, every 0x10 9 bytes is A-register pwm pins
+          pwm_register_array[0] = 0x24 + (i * 0x10);
+          is31_write_data(0,pwm_register_array,9);
+        }
         break;
 
-      case TOGGLE_PAGE_LEDS://show single layer indicator or full map of layer
+      case DISPLAY_PAGE://show single layer indicator or full map of layer
         //msg_led = page to toggle on
-      xprintf("TOGGLE_LAYER_LEDS\n");
-        is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &temp);
-
-        if(temp == msg_led) {
-          is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, 7);
-          page_status = 7;
-        } else {
+      xprintf("DISPLAY_PAGE\n");
+            chThdSleepMilliseconds(10);
+        if (page_status != msg_led) {
           is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, msg_led);
-          page_status = msg_led;
+        }
+        page_status = msg_led;
+        break;
+
+      case RESET_PAGE:
+        //led_msg = page to reset
+        led_control_reg[0] = 0;
+        __builtin_memset(led_control_reg+1, 0, 0x12);
+        is31_write_data(msg_led, led_control_reg, 0x13);
+
+        //maintain lock leds
+        if (host_keyboard_leds() & (1<<USB_LED_NUM_LOCK)) {
+          set_lock_leds(USB_LED_NUM_LOCK, 1);
+        }
+        if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
+          set_lock_leds(USB_LED_CAPS_LOCK, 1);
         }
         break;
         
@@ -313,10 +325,12 @@ page_status = 0; //start frame 0 (all off/on)
         set_lock_leds(USB_LED_CAPS_LOCK, msg_led);
         break;
 
+      //TODO: MODE_BREATH
       case MODE_BREATH:
         break;
       case STEP_BRIGHTNESS:
       xprintf("TOGGLE_BACKLIGHT\n");
+            chThdSleepMilliseconds(10);
         //led_msg = step pwm up or down
       switch (msg_led) {
         case 0:
@@ -336,66 +350,70 @@ page_status = 0; //start frame 0 (all off/on)
           break;
       }
 
-        //populate the 9 byte rows to be written to each pin, first byte is register (pin) address
-        __builtin_memset(pwm_register_array+1, pwm_levels[pwm_step_status], 8);
+      //populate 8 byte rows to write on each pin
+      //first byte is register address, every 0x10 9 bytes are A-register pwm pins
+      __builtin_memset(pwm_register_array+1, pwm_levels[pwm_step_status], 8);
 
-        for(i=0; i<8; i++) {
-        //first byte is register address, every 0x10 9 bytes is A-register pwm pins
-          pwm_register_array[0] = 0x24 + (i * 0x10);
-          is31_write_data(0,pwm_register_array,9);
-        }
+      for(i=0; i<8; i++) {
+        pwm_register_array[0] = 0x24 + (i * 0x10);
+        is31_write_data(0,pwm_register_array,9);
+      }
       break;
 
-/*        case LED_MSG_SLEEP_LED_ON:
-          // save current settings
-          is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &save_page);
-          is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, &save_breath1);
-          is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, &save_breath2);
-          // use pages 7 and 8 for (hardware) breathing (assuming they're empty)
-          is31_write_register(6, BREATHE_LED_ADDRESS, 0xFF);
-          is31_write_register(7, BREATHE_LED_ADDRESS, 0x00);
-          is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (6<<4)|6);
-          is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
-          retval = MSG_TIMEOUT;
-          temp = 6;
-          while(retval == MSG_TIMEOUT) {
-            // switch to the other page
-            is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, temp);
-            temp = (temp == 6 ? 7 : 6);
-            // the times should be sufficiently long for IS31 to finish switching pages
-            retval = chMBFetch(&led_mailbox, &msg, MS2ST(temp == 6 ? 4000 : 6000));
-          }
-          // received a message (should be a wakeup), so restore previous state
-          chThdSleepMilliseconds(3000); // need to wait until the page change finishes
-          // note: any other messages are queued
-          is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, save_breath1);
-          is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, save_breath2);
-          is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, save_page);
-          break;
-        case LED_MSG_SLEEP_LED_OFF: 
-          // should not get here; wakeup should be received in the branch above break;
-          break;
+/*    case LED_MSG_SLEEP_LED_ON:
+      // save current settings
+        is31_read_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, &save_page);
+        is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, &save_breath1);
+        is31_read_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, &save_breath2);
+        // use pages 7 and 8 for (hardware) breathing (assuming they're empty)
+        is31_write_register(6, BREATHE_LED_ADDRESS, 0xFF);
+        is31_write_register(7, BREATHE_LED_ADDRESS, 0x00);
+        is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, (6<<4)|6);
+        is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, IS31_REG_BREATHCTRL2_ENABLE|3);
+        retval = MSG_TIMEOUT;
+        temp = 6;
+        while(retval == MSG_TIMEOUT) {
+          // switch to the other page
+          is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, temp);
+          temp = (temp == 6 ? 7 : 6);
+          // the times should be sufficiently long for IS31 to finish switching pages
+          retval = chMBFetch(&led_mailbox, &msg, MS2ST(temp == 6 ? 4000 : 6000));
+        }
+        // received a message (should be a wakeup), so restore previous state
+        chThdSleepMilliseconds(3000); // need to wait until the page change finishes
+        // note: any other messages are queued
+        is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL1, save_breath1);
+        is31_write_register(IS31_FUNCTIONREG, IS31_REG_BREATHCTRL2, save_breath2);
+        is31_write_register(IS31_FUNCTIONREG, IS31_REG_PICTDISP, save_page);
+        break;
+      case LED_MSG_SLEEP_LED_OFF: 
+        // should not get here; wakeup should be received in the branch above break;
+        break;
 */  
       xprintf("--------------------\n");
+            chThdSleepMilliseconds(10);
     }
-#ifdef DEBUG_ENABLED
+#if DEBUG_ENABLED
+    uint8_t j, page;
     //debugging code - print full led/blink/pwm registers on each frame
+          xprintf("----layer state----: %X\n", layer_state);
       for(i=0;i<8;i++) {
           xprintf("page: %d", i);
+            chThdSleepMilliseconds(2);
         for(j=0;j<0xB4;j++){
-              is31_read_register(i,j,&temp);
-            chThdSleepMilliseconds(1);
+            is31_read_register(i,j,&temp);
+            chThdSleepMilliseconds(2);
             xprintf("%02X, ", temp);
             if(j % 9 == 0){
-            xprintf("\n", temp);
+            xprintf("\n");
               if(j % 18 ==0){
-              xprintf("register", temp);
-              xprintf("\n", temp);
+              xprintf("register");
+              xprintf("\n");
               }
             }
             chThdSleepMilliseconds(1);
         }
-            xprintf("\n", temp);
+            xprintf("\n");
       }
 #endif
   }
@@ -406,16 +424,21 @@ page_status = 0; //start frame 0 (all off/on)
  * ============================== */
 
 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
+  //returns 2 bytes led control register address and byte to write
 
   uint8_t control_reg_addr, column_bit, column_byte, temp;
-  //
+  //check for valid led address
+  if (led_addr < 0 || led_addr > 90 || led_addr % 10 > 8) {
+    xprintf("Invalid address: %d\n", led_addr);
+    return;
+  }
+
   //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)
+  is31_read_register(page, control_reg_addr, &temp);//maintain status of leds on this byte
   column_byte = temp;
 
   switch(action) {
@@ -437,9 +460,11 @@ void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint
 
 void set_lock_leds(uint8_t lock_type, uint8_t led_on) {
   uint8_t page, led_addr, start, temp;
-  uint8_t led_control_write[2] = {0};
-  //TODO: consolidate control register to top level array vs. three scattered around
+  uint8_t led_control_word[2] = {0};
+  //TODO: this function call could send led address vs lock_type.
+  //however, the switch/case allows for additional steps, like audio, depending on type
 
+  led_addr = 0;
   switch(lock_type) {
       case USB_LED_NUM_LOCK:
           led_addr = NUM_LOCK_LED_ADDRESS;
@@ -465,16 +490,18 @@ void set_lock_leds(uint8_t lock_type, uint8_t led_on) {
   }          
 
   //ignore frame0 if all leds are on or if option set in led_controller.h
+  //TODO: blink of all leds are on, clear blink register if not
   is31_read_register(0, 0x00, &temp);
-  start = (temp>0 || BACKLIGHT_OFF_LOCK_LED_OFF) ? 1 : 0; 
+  led_addr += temp == 0 ? 0 : 0x12;//send bit to blink register instead
+  start = BACKLIGHT_OFF_LOCK_LED_OFF ? 1 : 0; 
 
   for(page=start; page<8; page++) { 
-    set_led_bit(page,led_control_write,led_addr,led_on);
-    is31_write_data(page, led_control_write, 0x02);
+    set_led_bit(page,led_control_word,led_addr,led_on);
+    is31_write_data(page, led_control_word, 0x02);
   }
 }
 
-void write_led_page (uint8_t page, const uint8_t *user_led_array, uint8_t led_count) {
+void write_led_page (uint8_t page, uint8_t *user_led_array, uint8_t led_count) {
   uint8_t i;
   uint8_t row, col;
   uint8_t led_control_register[0x13] = {0};//led control register start address + 0x12 bytes
@@ -516,7 +543,6 @@ void led_controller_init(void) {
   //set Display Option Register so all pwm intensity is controlled from Frame 0
   is31_write_register(IS31_FUNCTIONREG, IS31_REG_DISPLAYOPT, IS31_REG_DISPLAYOPT_INTENSITY_SAME);
 
-    //TODO: test new init pwm loop
   /* set full pwm on Frame 1 */
   pwm_register_array[0] = 0;
   __builtin_memset(pwm_register_array+1, 0xFF, 8);
index 1511004714526c8957939523433d716e1c100064..b06113b0775b4fbdb44902e1f5de253ba5d7537b 100644 (file)
@@ -94,7 +94,7 @@ extern mailbox_t led_mailbox;
 
 void set_led_bit (uint8_t page, uint8_t *led_control_reg, uint8_t led_addr, uint8_t action);
 void set_lock_leds (uint8_t lock_type, uint8_t led_on);
-void write_led_page (uint8_t page, const uint8_t *led_array, uint8_t led_count);
+void write_led_page (uint8_t page, uint8_t *led_array, uint8_t led_count);
 
 // constants for signaling the LED controller thread
 enum led_msg_t {
@@ -104,7 +104,8 @@ enum led_msg_t {
     TOGGLE_LED,
     TOGGLE_ALL,
     TOGGLE_BACKLIGHT,
-    TOGGLE_PAGE_LEDS,
+    DISPLAY_PAGE,
+    RESET_PAGE,
     TOGGLE_NUM_LOCK,
     TOGGLE_CAPS_LOCK,
     MODE_BREATH,