aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojciech Siewierski <wojciech.siewierski@onet.pl>2018-10-06 16:49:04 +0200
committerDrashna Jaelre <drashna@live.com>2018-10-06 07:49:04 -0700
commit60f5ce8890453751a00ab63b150dded25c39db42 (patch)
treebf3f69c38b45afc92941d90ad13801cd5b2fb0c1
parent2c1402aa3208d450a7724790b0eb9f2d352a1d9d (diff)
downloadqmk_firmware-60f5ce8890453751a00ab63b150dded25c39db42.tar.gz
qmk_firmware-60f5ce8890453751a00ab63b150dded25c39db42.zip
Keymap: Update keyboards/planck/keymaps/vifon (#4084)
* Implement macro recording * Remove off-by-one from the macro recorder * Holding both modifiers enables the third layer * Exit the 3rd layer into one of the secondary ones * Regular Enter and Escape on the secondary layers Useful for the macro recording because the "tap" modifiers always act as modifiers there. * Remove the buffer overflow from the macro recorder When the limit is reached, the backlight blinks with each keypress. * More robust macro recording implementation * Macro record refactoring and improvement - support for a second macro (saved using the end of the macro buffer) - improved reliability * Add comments to my macros * Macro recording: remove a redundant code * Separate the raise+lower layer from the special layer * Add back/forward keys * Bind mouse movement * More readable KC_TRNS * Improve the mouse bindings * Use a convenience macro instead of the low-level ACTION macro * Add mouse to the Dual layer; make most of the layer transparent * New "mouse" layer; clean up the "special" layer * CapsLock, NumLock and ScrollLock on the Special layer * Enable my fix for the stuck modifiers and adjust the dual layer to it * Fix the macro recording after enabling the stuck mods fix * Click with Lower/Raise+Space * Reduce the memory used by the macro recording Previously the auxiliary layers were numbered 30 and 31 which resulted in all 32 array elements being allocated regardless of the actually used layers in the user code. * Optimize source_layers_cache for the cache memory Swapping the array indices should increase the locality of the memory access. * Remove the mouse layer * Use update_tri_layer to simplify the code * Add some custom per-keymap build options * Add ShiftLock * Secure the reset button * Add numeric layer * Remove explicit layer keys on LW and RS layers * Replace Alt+left/right with Back/Forward keys * Sleep/delay key (for macro recording) * App/menu key * Fix stuff after merging to master * Local per-keymap config.h; minor cleanup * Remove the old macro_record.h Replaced with dynamic_macro.h * Adjust my keymap to the current API * Pure Pro Gaming layer Accessible by double tapping the Pure Pro layer. It features switched Lower and Raise layers, for one-handed access to numbers. * Pure Pro Gaming layer: no Mod4, persistent number layer under RShift * Pure Pro Gaming layer activated with long press, not double press * Reduce the size of the vifon keymap See: issue #930 * Increase the dynamic macro buffer The default was actually decreased. The actual used value didn't change. * Add the context menu key * No more strange ideas in the gaming layer * Reduce the firmware size by disabling API_SYSEX_ENABLE * Make slash available on the PP layer (replaces the RESET key) * Add a generic "hold this key" macro * Add a missing undef * Turn LGUI in the gaming layer into LW instead of disabling it It's not as disruptive as LGUI and it makes the LW/RS order kind of more consistent (LW on the left, RS on the right). * Refactor the Pure Pro Gaming layer * Try out the 1st party qmk KC_LOCK (vs my own KM_HOLD) * Alternative way to switch keyboard layouts with the left hand * Add dot & slash to the Pure Pro layer (but not to the Gaming layer) * Now that there is a second KM_LW, we can simplify the layout a bit It was confusing to have the modifiers completely swapped. Just moving them is much more natural. * Disable the console now that qmk got bigger * Update the keymap for the modern qmk standards
-rw-r--r--keyboards/planck/keymaps/vifon/keymap.c179
-rw-r--r--keyboards/planck/keymaps/vifon/rules.mk2
2 files changed, 105 insertions, 76 deletions
diff --git a/keyboards/planck/keymaps/vifon/keymap.c b/keyboards/planck/keymaps/vifon/keymap.c
index 0fa8d9066..6398accc2 100644
--- a/keyboards/planck/keymaps/vifon/keymap.c
+++ b/keyboards/planck/keymaps/vifon/keymap.c
@@ -1,11 +1,5 @@
1 1
2#pragma message "You may need to add LAYOUT_planck_grid to your keymap layers - see default for an example" 2#include QMK_KEYBOARD_H
3#include "planck.h"
4#ifdef BACKLIGHT_ENABLE
5# include "backlight.h"
6#endif
7#include "timer.h"
8#include <bootloader.h>
9 3
10// Each layer gets a name for readability, which is then used in the keymap matrix below. 4// Each layer gets a name for readability, which is then used in the keymap matrix below.
11// The underscores don't mean anything - you can have a layer called STUFF or any other name. 5// The underscores don't mean anything - you can have a layer called STUFF or any other name.
@@ -27,90 +21,98 @@ enum planck_keycodes {
27 KM_LW = SAFE_RANGE, 21 KM_LW = SAFE_RANGE,
28 KM_RS, 22 KM_RS,
29 KM_SHLK, /* ShiftLock */ 23 KM_SHLK, /* ShiftLock */
24 KM_HOLD, /* Any-key Lock */
30 KM_RST, /* Reset */ 25 KM_RST, /* Reset */
31 KM_NUM, /* Numeric layer */ 26 KM_NUM, /* Numeric layer */
32 KM_SLP, /* Sleep 250 ms */ 27 KM_SLP, /* Sleep 250 ms */
33 KM_PPLR, /* Pure Pro layer */ 28 KM_PP_GAME, /* Pure Pro Gaming layer */
29 KM_PP_HOLD, /* Pure Pro / PP Gaming layer */
34 DYNAMIC_MACRO_RANGE, 30 DYNAMIC_MACRO_RANGE,
35}; 31};
36 32
37#include "dynamic_macro.h" 33#include "dynamic_macro.h"
38 34
39#define _______ KC_TRNS
40#define XXXXXXX KC_NO
41
42const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { 35const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
43[_QW] = { /* Qwerty */ 36 [_QW] = LAYOUT_planck_mit( /* Qwerty */
44 {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC}, 37 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
45 {CTL_T(KC_ESC), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT}, 38 CTL_T(KC_ESC), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
46 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_FN0 }, 39 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MT(MOD_RSFT, KC_ENT),
47 {KC_LCTL, MO(_DYN),KC_LGUI, KC_LALT, KM_LW, KC_SPC, KC_SPC, KM_RS, KC_RALT, KC_DOWN, KC_UP, KC_RCTL} 40 KC_LCTL, MO(_DYN), KC_LGUI, KC_LALT, KM_LW, KC_SPC, KM_RS, KC_RALT, KC_DOWN, KC_UP, KC_RCTL
48}, 41 ),
49[_CM] = { /* Colemak */ 42 [_CM] = LAYOUT_planck_mit( /* Colemak */
50 {KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC}, 43 KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_BSPC,
51 {CTL_T(KC_ESC), KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT}, 44 CTL_T(KC_ESC), KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT,
52 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_FN0 }, 45 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, MT(MOD_RSFT, KC_ENT),
53 {KC_LCTL, MO(_DYN),KC_LGUI, KC_LALT, KM_LW, KC_SPC, KC_SPC, KM_RS, KC_RALT, KC_DOWN, KC_UP, KC_RCTL} 46 KC_LCTL, MO(_DYN), KC_LGUI, KC_LALT, KM_LW, KC_SPC, KM_RS, KC_RALT, KC_DOWN, KC_UP, KC_RCTL
54}, 47 ),
55[_PP] = { /* Pure Pro */ 48 [_PP] = LAYOUT_planck_mit( /* Pure Pro */
56 {KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC}, 49 KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
57 {KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT }, 50 KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,
58 {KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_RSFT, KC_UP, KC_RCTL}, 51 KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, MT(MOD_RSFT, KC_DOT), KC_UP, MT(MOD_RCTL, KC_SLSH),
59 {KC_LCTL, MO(_DYN),KC_LGUI, KC_LALT, KM_LW, KC_SPC, KC_SPC, KM_RS, KC_RALT, KC_LEFT, KC_DOWN, KC_RGHT} 52 KC_LCTL, MO(_DYN), KC_LGUI, KC_LALT, KM_LW, KC_SPC, KM_RS, KC_RALT, KC_LEFT, KC_DOWN, KC_RGHT
60}, 53 ),
61[_PPG] = { /* Pure Pro: Gaming */ 54 [_PPG] = LAYOUT_planck_mit( /* Pure Pro: Gaming */
62 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}, 55 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
63 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}, 56 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
64 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}, 57 _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_RSFT, _______, KC_RCTL,
65 {_______, _______, XXXXXXX, _______, KM_RS , _______, _______, KM_LW , _______, _______, _______, _______}, 58 _______, _______, KM_LW, _______, KM_RS, _______, KM_RS , _______, _______, _______, _______
66}, 59 ),
67[_NM] = { /* Numeric */ 60 [_NM] = LAYOUT_planck_mit( /* Numeric */
68 {KC_TAB, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC}, 61 KC_TAB, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
69 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}, 62 _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
70 {KC_LSFT, _______, _______, _______, _______, _______, _______, _______, KC_COMM, KC_DOT, _______, KC_FN0 }, 63 KC_LSFT, _______, _______, _______, _______, _______, _______, _______, KC_COMM, KC_DOT, _______, MT(MOD_RSFT, KC_ENT),
71 {_______, _______, _______, _______, _______, KC_SPC, KC_SPC, _______, _______, _______, _______, _______} 64 _______, _______, _______, _______, _______, KC_SPC, _______, _______, _______, _______, _______
72}, 65 ),
73[_LW]= { /* LOWER */ 66 [_LW] = LAYOUT_planck_mit( /* LOWER */
74 {KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC}, 67 KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC,
75 {KC_ESC, LGUI(KC_1), LGUI(KC_2), LGUI(KC_3), LGUI(KC_4), LGUI(KC_5), KM_NUM, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE}, 68 KC_ESC, LGUI(KC_1), LGUI(KC_2), LGUI(KC_3), LGUI(KC_4), LGUI(KC_5), KM_NUM, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
76 {_______, LGUI(KC_6), LGUI(KC_7), LGUI(KC_8), LGUI(KC_9), LGUI(KC_0), KM_SLP, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_ENT }, 69 _______, LGUI(KC_6), LGUI(KC_7), LGUI(KC_8), LGUI(KC_9), LGUI(KC_0), KM_SLP, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_ENT,
77 {_______, BL_TOGG, _______, _______, _______, KC_BTN1, KC_BTN1, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT} 70 _______, BL_TOGG, _______, _______, _______, KC_BTN1, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
78}, 71 ),
79[_RS]= { /* RAISE */ 72 [_RS] = LAYOUT_planck_mit( /* RAISE */
80 {KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL }, 73 KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DEL,
81 {KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS}, 74 KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
82 {_______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, DF(_QW), DF(_CM), KM_PPLR, KM_RST, KC_ENT }, 75 _______, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, DF(_QW), DF(_CM), KM_PP_HOLD, KM_RST, KC_ENT,
83 {_______, BL_STEP, _______, _______, _______, KC_BTN2, KC_BTN2, _______, KC_MPLY, KC_VOLD, KC_VOLU, _______} 76 _______, BL_STEP, _______, _______, _______, KC_BTN2, _______, KC_MPLY, KC_VOLD, KC_VOLU, _______
84}, 77 ),
85[_DL]= { /* DUAL */ 78 [_DL] = LAYOUT_planck_mit( /* DUAL */
86 {_______, _______, KC_WH_U, KC_MS_U, KC_WH_D, _______, _______, KC_APP, KC_INS, _______, KC_PSCR, _______}, 79 _______, _______, KC_WH_U, KC_MS_U, KC_WH_D, _______, _______, KC_APP, KC_INS, _______, KC_PSCR, _______,
87 {_______, _______, KC_MS_L, KC_MS_D, KC_MS_R, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_ACL0, KC_ACL2}, 80 _______, _______, KC_MS_L, KC_MS_D, KC_MS_R, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_ACL0, KC_ACL2,
88 {_______, _______, KC_BTN2, KC_BTN3, KC_BTN1, KC_WWW_BACK, KC_WWW_FORWARD, KC_MUTE, _______, _______, _______, _______}, 81 _______, _______, KC_BTN2, KC_BTN3, KC_BTN1, KC_WWW_BACK, KC_WWW_FORWARD, KC_MUTE, _______, _______, _______, _______,
89 {_______, _______, KC_LGUI, KC_LALT, _______, _______, _______, _______, _______, _______, _______, _______} 82 _______, _______, KC_LGUI, KC_LALT, _______, _______, _______, _______, _______, _______, _______
90}, 83 ),
91[_DYN]= { /* special */ 84 [_DYN] = LAYOUT_planck_mit( /* special */
92 {_______, DYN_REC_START1, DYN_MACRO_PLAY1, _______, _______, _______, _______, KC_APP, KC_INS, _______, KC_PSCR, KC_PAUS}, 85 KM_HOLD, DYN_REC_START1, DYN_MACRO_PLAY1, _______, _______, _______, _______, KC_APP, KC_INS, _______, KC_PSCR, KC_PAUS,
93 {_______, DYN_REC_START2, DYN_MACRO_PLAY2, _______, _______, _______, _______, _______, _______, KC_CAPS, KC_SLCK, KC_NLCK}, 86 KC_LOCK, DYN_REC_START2, DYN_MACRO_PLAY2, _______, _______, _______, _______, _______, _______, KC_CAPS, KC_SLCK, KC_NLCK,
94 {KM_SHLK, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}, 87 KM_SHLK, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
95 {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______} 88 _______, _______, _______, _______, KM_PP_GAME, DF(_QW), DF(_PP), _______, _______, _______, _______
96}, 89 ),
97};
98
99#undef _______
100
101const uint16_t PROGMEM fn_actions[] = {
102 ACTION_MODS_TAP_KEY(MOD_RSFT, KC_ENT),
103}; 90};
104 91
92/* It's a pseudo-layer composed of two real layers, we need a function for this. */
93void enable_gaming_layer(void) {
94 default_layer_set((1UL << _PP) | (1UL << _PPG));
95#ifdef BACKLIGHT_ENABLE
96 backlight_toggle();
97 _delay_ms(100);
98 backlight_toggle();
99#endif
100}
105 101
106bool process_record_user(uint16_t keycode, keyrecord_t *record) { 102bool process_record_user(uint16_t keycode, keyrecord_t *record) {
107 static uint16_t key_timer; 103 static uint16_t key_timer;
104 static uint8_t ignore_up_events = 0;
108 105
109 uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode); 106 uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode);
110 if (!process_record_dynamic_macro(macro_kc, record)) { 107 if (!process_record_dynamic_macro(macro_kc, record)) {
111 return false; 108 return false;
112 } 109 }
113 110
111 if (ignore_up_events > 0 && keycode != MO(_DYN) && keycode != KM_HOLD && !record->event.pressed) {
112 ignore_up_events -= 1;
113 return false;
114 }
115
114 switch (keycode) { 116 switch (keycode) {
115 case KM_LW: 117 case KM_LW:
116 if (record->event.pressed) { 118 if (record->event.pressed) {
@@ -133,7 +135,30 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
133 case KM_SHLK: 135 case KM_SHLK:
134 register_code(KC_LSFT); 136 register_code(KC_LSFT);
135 break; 137 break;
138 case KM_HOLD:
139 if (!record->event.pressed) {
140 ignore_up_events += 1;
141 }
142 break;
136 case KM_RST: 143 case KM_RST:
144 {
145 /* Make slash available on the PP layer. */
146 if ((1UL << _PP) & default_layer_state) {
147 int32_t old_default_layer_state = default_layer_state;
148 int32_t old_layer_state = layer_state;
149
150 layer_state = 0;
151 default_layer_state = (1UL << _QW);
152
153 process_record(record);
154
155 layer_state = old_layer_state;
156 default_layer_state = old_default_layer_state;
157
158 return false;
159 }
160 }
161
137 if (record->event.pressed) { 162 if (record->event.pressed) {
138 key_timer = timer_read(); 163 key_timer = timer_read();
139 } else { 164 } else {
@@ -146,15 +171,17 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
146 } 171 }
147 } 172 }
148 break; 173 break;
149 case KM_PPLR: 174 case KM_PP_GAME:
175 if (!record->event.pressed) {
176 enable_gaming_layer();
177 }
178 break;
179 case KM_PP_HOLD:
150 if (record->event.pressed) { 180 if (record->event.pressed) {
151 key_timer = timer_read(); 181 key_timer = timer_read();
152 } else { 182 } else {
153 if (timer_elapsed(key_timer) >= 250) { 183 if (timer_elapsed(key_timer) >= 250) {
154 default_layer_set((1UL << _PP) | (1UL << _PPG)); 184 enable_gaming_layer();
155 backlight_toggle();
156 _delay_ms(100);
157 backlight_toggle();
158 } else { 185 } else {
159 default_layer_set(1UL << _PP); 186 default_layer_set(1UL << _PP);
160 } 187 }
diff --git a/keyboards/planck/keymaps/vifon/rules.mk b/keyboards/planck/keymaps/vifon/rules.mk
index 15a7b736f..da83096d6 100644
--- a/keyboards/planck/keymaps/vifon/rules.mk
+++ b/keyboards/planck/keymaps/vifon/rules.mk
@@ -16,6 +16,8 @@ AUDIO_ENABLE = no # Audio output on port C6
16UNICODE_ENABLE = no # Unicode 16UNICODE_ENABLE = no # Unicode
17BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID 17BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
18RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time. 18RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
19API_SYSEX_ENABLE = no # https://www.reddit.com/r/olkb/comments/5swhij/_/ddie6zq/
20KEY_LOCK_ENABLE = yes
19 21
20# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE 22# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
21SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend 23SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend