]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - quantum/quantum.c
Added Grave Escape (#1391)
[qmk_firmware.git] / quantum / quantum.c
index 45ea8cb73c0553452aa9e1fc4a29e082a85ad4a2..f5fb1e35c874c6dc537fc44b2feeeec7f214c2f5 100644 (file)
@@ -1,3 +1,19 @@
+/* Copyright 2016-2017 Jack Humbert
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
 #include "quantum.h"
 #ifdef PROTOCOL_LUFA
 #include "outputselect.h"
@@ -7,6 +23,13 @@
 #define TAPPING_TERM 200
 #endif
 
+#include "backlight.h"
+extern backlight_config_t backlight_config;
+
+#ifdef FAUXCLICKY_ENABLE
+#include "fauxclicky.h"
+#endif
+
 static void do_code16 (uint16_t code, void (*f) (uint8_t)) {
   switch (code) {
   case QK_MODS ... QK_MODS_MAX:
@@ -91,8 +114,8 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 
 void reset_keyboard(void) {
   clear_keyboard();
-#ifdef AUDIO_ENABLE
-  stop_all_notes();
+#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_ENABLE_BASIC))
+  music_all_notes_off();
   shutdown_user();
 #endif
   wait_ms(250);
@@ -112,7 +135,7 @@ void reset_keyboard(void) {
 #endif
 
 static bool shift_interrupted[2] = {0, 0};
-static uint16_t scs_timer = 0;
+static uint16_t scs_timer[2] = {0, 0};
 
 bool process_record_quantum(keyrecord_t *record) {
 
@@ -146,10 +169,13 @@ bool process_record_quantum(keyrecord_t *record) {
 
   if (!(
     process_record_kb(keycode, record) &&
-  #ifdef MIDI_ENABLE
+  #if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
     process_midi(keycode, record) &&
   #endif
   #ifdef AUDIO_ENABLE
+    process_audio(keycode, record) &&
+  #endif
+  #if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))
     process_music(keycode, record) &&
   #endif
   #ifdef TAP_DANCE_ENABLE
@@ -196,6 +222,26 @@ bool process_record_quantum(keyrecord_t *record) {
       }
          return false;
       break;
+  #ifdef FAUXCLICKY_ENABLE
+  case FC_TOG:
+    if (record->event.pressed) {
+      FAUXCLICKY_TOGGLE;
+    }
+    return false;
+    break;
+  case FC_ON:
+    if (record->event.pressed) {
+      FAUXCLICKY_ON;
+    }
+    return false;
+    break;
+  case FC_OFF:
+    if (record->event.pressed) {
+      FAUXCLICKY_OFF;
+    }
+    return false;
+    break;
+  #endif
        #ifdef RGBLIGHT_ENABLE
        case RGB_TOG:
                if (record->event.pressed) {
@@ -267,14 +313,6 @@ bool process_record_quantum(keyrecord_t *record) {
       return false;
       break;
     #endif
-    #ifdef ADAFRUIT_BLE_ENABLE
-    case OUT_BLE:
-      if (record->event.pressed) {
-        set_output(OUTPUT_ADAFRUIT_BLE);
-      }
-      return false;
-      break;
-    #endif
     #endif
     case MAGIC_SWAP_CONTROL_CAPSLOCK ... MAGIC_TOGGLE_NKRO:
       if (record->event.pressed) {
@@ -357,7 +395,7 @@ bool process_record_quantum(keyrecord_t *record) {
     case KC_LSPO: {
       if (record->event.pressed) {
         shift_interrupted[0] = false;
-        scs_timer = timer_read ();
+        scs_timer[0] = timer_read ();
         register_mods(MOD_BIT(KC_LSFT));
       }
       else {
@@ -367,7 +405,7 @@ bool process_record_quantum(keyrecord_t *record) {
             shift_interrupted[1] = true;
           }
         #endif
-        if (!shift_interrupted[0] && timer_elapsed(scs_timer) < TAPPING_TERM) {
+        if (!shift_interrupted[0] && timer_elapsed(scs_timer[0]) < TAPPING_TERM) {
           register_code(LSPO_KEY);
           unregister_code(LSPO_KEY);
         }
@@ -380,7 +418,7 @@ bool process_record_quantum(keyrecord_t *record) {
     case KC_RSPC: {
       if (record->event.pressed) {
         shift_interrupted[1] = false;
-        scs_timer = timer_read ();
+        scs_timer[1] = timer_read ();
         register_mods(MOD_BIT(KC_RSFT));
       }
       else {
@@ -390,7 +428,7 @@ bool process_record_quantum(keyrecord_t *record) {
             shift_interrupted[1] = true;
           }
         #endif
-        if (!shift_interrupted[1] && timer_elapsed(scs_timer) < TAPPING_TERM) {
+        if (!shift_interrupted[1] && timer_elapsed(scs_timer[1]) < TAPPING_TERM) {
           register_code(RSPC_KEY);
           unregister_code(RSPC_KEY);
         }
@@ -399,6 +437,14 @@ bool process_record_quantum(keyrecord_t *record) {
       return false;
       // break;
     }
+    case GRAVE_ESC: {
+      void (*method)(uint8_t) = (record->event.pressed) ? &add_key : &del_key;
+      uint8_t shifted = get_mods() & ((MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)
+                                      |MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)));
+
+      method(shifted ? KC_GRAVE : KC_ESCAPE);
+      send_keyboard_report(); 
+    }
     default: {
       shift_interrupted[0] = true;
       shift_interrupted[1] = true;
@@ -577,6 +623,10 @@ void matrix_scan_quantum() {
     matrix_scan_combo();
   #endif
 
+  #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_PIN)
+    backlight_task();
+  #endif
+
   matrix_scan_kb();
 }
 
@@ -644,13 +694,13 @@ __attribute__ ((weak))
 void backlight_set(uint8_t level)
 {
   // Prevent backlight blink on lowest level
-  #if BACKLIGHT_ON_STATE == 0
-    // PORTx &= ~n
-    _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
-  #else
-    // PORTx |= n
-    _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
-  #endif
+  // #if BACKLIGHT_ON_STATE == 0
+  //   // PORTx &= ~n
+  //   _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
+  // #else
+  //   // PORTx |= n
+  //   _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
+  // #endif
 
   if ( level == 0 ) {
     #ifndef NO_BACKLIGHT_CLOCK
@@ -658,13 +708,13 @@ void backlight_set(uint8_t level)
       TCCR1A &= ~(_BV(COM1x1));
       OCR1x = 0x0;
     #else
-      #if BACKLIGHT_ON_STATE == 0
-        // PORTx |= n
-        _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
-      #else
-        // PORTx &= ~n
-        _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
-      #endif
+      // #if BACKLIGHT_ON_STATE == 0
+      //   // PORTx |= n
+      //   _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
+      // #else
+      //   // PORTx &= ~n
+      //   _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
+      // #endif
     #endif
   } 
   #ifndef NO_BACKLIGHT_CLOCK
@@ -687,6 +737,30 @@ void backlight_set(uint8_t level)
   #endif
 }
 
+uint8_t backlight_tick = 0;
+
+void backlight_task(void) {
+  #ifdef NO_BACKLIGHT_CLOCK
+  if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) { 
+    #if BACKLIGHT_ON_STATE == 0
+      // PORTx &= ~n
+      _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
+    #else
+      // PORTx |= n
+      _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
+    #endif
+  } else {
+    #if BACKLIGHT_ON_STATE == 0
+      // PORTx |= n
+      _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF);
+    #else
+      // PORTx &= ~n
+      _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF);
+    #endif
+  }
+  backlight_tick = (backlight_tick + 1) % 16;
+  #endif
+}
 
 #ifdef BACKLIGHT_BREATHING
 
@@ -948,6 +1022,19 @@ void send_nibble(uint8_t number) {
     }
 }
 
+
+__attribute__((weak))
+uint16_t hex_to_keycode(uint8_t hex)
+{
+  if (hex == 0x0) {
+    return KC_0;
+  } else if (hex < 0xA) {
+    return KC_1 + (hex - 0x1);
+  } else {
+    return KC_A + (hex - 0xA);
+  }
+}
+
 void api_send_unicode(uint32_t unicode) {
 #ifdef API_ENABLE
     uint8_t chunk[4];