diff options
25 files changed, 277 insertions, 321 deletions
diff --git a/docs/config_options.md b/docs/config_options.md index a9ff54995..1dd4cdbaa 100644 --- a/docs/config_options.md +++ b/docs/config_options.md | |||
@@ -70,6 +70,10 @@ This is a C header file that is one of the first things included, and will persi | |||
70 | * pin of the backlight - B5, B6, B7 use PWM, others use softPWM | 70 | * pin of the backlight - B5, B6, B7 use PWM, others use softPWM |
71 | * `#define BACKLIGHT_LEVELS 3` | 71 | * `#define BACKLIGHT_LEVELS 3` |
72 | * number of levels your backlight will have (not including off) | 72 | * number of levels your backlight will have (not including off) |
73 | * `#define BACKLIGHT_BREATHING` | ||
74 | * enables backlight breathing (only works with backlight pins B5, B6 and B7) | ||
75 | * `#define BREATHING_PERIOD 6` | ||
76 | * the length of one backlight "breath" in seconds | ||
73 | * `#define DEBOUNCING_DELAY 5` | 77 | * `#define DEBOUNCING_DELAY 5` |
74 | * the delay when reading the value of the pin (5 is default) | 78 | * the delay when reading the value of the pin (5 is default) |
75 | * `#define LOCKING_SUPPORT_ENABLE` | 79 | * `#define LOCKING_SUPPORT_ENABLE` |
diff --git a/docs/faq_keymap.md b/docs/faq_keymap.md index 7093dec20..0fed0445f 100644 --- a/docs/faq_keymap.md +++ b/docs/faq_keymap.md | |||
@@ -127,7 +127,7 @@ https://github.com/tekezo/Karabiner/issues/403 | |||
127 | 127 | ||
128 | ## Esc and <code>`</code> on a Single Key | 128 | ## Esc and <code>`</code> on a Single Key |
129 | 129 | ||
130 | See the [Grave Escape](feature_grave_escape.md) feature. | 130 | See the [Grave Escape](feature_grave_esc.md) feature. |
131 | 131 | ||
132 | ## Arrow on Right Modifier Keys with Dual-Role | 132 | ## Arrow on Right Modifier Keys with Dual-Role |
133 | This turns right modifier keys into arrow keys when the keys are tapped while still modifiers when the keys are hold. In TMK the dual-role function is dubbed **TAP**. | 133 | This turns right modifier keys into arrow keys when the keys are tapped while still modifiers when the keys are hold. In TMK the dual-role function is dubbed **TAP**. |
diff --git a/docs/feature_backlight.md b/docs/feature_backlight.md index aa747f90e..97421c043 100644 --- a/docs/feature_backlight.md +++ b/docs/feature_backlight.md | |||
@@ -10,8 +10,30 @@ These keycodes control the backlight. Most keyboards use this for single color i | |||
10 | |---------|------------------------------------------| | 10 | |---------|------------------------------------------| |
11 | |`BL_TOGG`|Turn the backlight on or off | | 11 | |`BL_TOGG`|Turn the backlight on or off | |
12 | |`BL_STEP`|Cycle through backlight levels | | 12 | |`BL_STEP`|Cycle through backlight levels | |
13 | |`BL_x` |Set a specific backlight level between 0-9| | 13 | |`BL_ON` |Set backlight to max brightness | |
14 | |`BL_ON` |An alias for `BL_9` | | 14 | |`BL_OFF` |Turn backlight off | |
15 | |`BL_OFF` |An alias for `BL_0` | | ||
16 | |`BL_INC` |Increase backlight level | | 15 | |`BL_INC` |Increase backlight level | |
17 | |`BL_DEC` |Decrease backlight level | | 16 | |`BL_DEC` |Decrease backlight level | |
17 | |`BL_BRTG`|Toggle backlight breathing | | ||
18 | |||
19 | Note that for backlight breathing, you need to have `#define BACKLIGHT_BREATHING` in your config.h. | ||
20 | |||
21 | ## Configuration Options in `config.h` | ||
22 | |||
23 | * `BACKLIGHT_PIN B7` defines the pin that controlls the LEDs. Unless you design your own keyboard, you don't need to set this. | ||
24 | * `BACKLIGHT_LEVELS 3` defines the number of brightness levels (excluding OFF). | ||
25 | * `BACKLIGHT_BREATHING` if defined, enables backlight breathing. Note that this is only available if `BACKLIGHT_PIN` is B5, B6 or B7. | ||
26 | * `BREATHING_PERIOD 6` defines the length of one backlight "breath" in seconds. | ||
27 | |||
28 | ## Notes on Implementation | ||
29 | |||
30 | To change the brightness when using pins B5, B6 or B7, the PWM (Pulse Width Modulation) functionality of the on-chip timer is used. | ||
31 | The timer is a counter that counts up to a certain TOP value (`0xFFFF` set in ICR1) before resetting to 0. | ||
32 | We also set an OCR1x register. | ||
33 | When the counter reaches the value stored in that register, the PWM pin drops to low. | ||
34 | The PWM pin is pulled high again when the counter resets to 0. | ||
35 | Therefore, OCR1x basically sets the duty cycle of the LEDs and as such the brightness where `0` is the darkest and `0xFFFF` the brightest setting. | ||
36 | |||
37 | To enable the breathing effect, we register an interrupt handler to be called whenever the counter resets (with `ISR(TIMER1_OVF_vect)`). | ||
38 | In this handler, which gets called roughly 244 times per second, we compute the desired brightness using a precomputed brightness curve. | ||
39 | To disable breathing, we can just disable the respective interrupt vector and reset the brightness to the desired level. | ||
diff --git a/docs/hardware_avr.md b/docs/hardware_avr.md index c6f3881dc..770817045 100644 --- a/docs/hardware_avr.md +++ b/docs/hardware_avr.md | |||
@@ -101,8 +101,9 @@ By default QMK supports backlighting on pins `B5`, `B6`, and `B7`. If you are us | |||
101 | 101 | ||
102 | ``` | 102 | ``` |
103 | #define BACKLIGHT_PIN B7 | 103 | #define BACKLIGHT_PIN B7 |
104 | #define BACKLIGHT_BREATHING | ||
105 | #define BACKLIGHT_LEVELS 3 | 104 | #define BACKLIGHT_LEVELS 3 |
105 | #define BACKLIGHT_BREATHING | ||
106 | #define BREATHING_PERIOD 6 | ||
106 | ``` | 107 | ``` |
107 | 108 | ||
108 | {% hint style='info' %} | 109 | {% hint style='info' %} |
diff --git a/keyboards/atomic/keymaps/pvc/keymap.c b/keyboards/atomic/keymaps/pvc/keymap.c index 4a7cc863e..2e78e64b1 100644 --- a/keyboards/atomic/keymaps/pvc/keymap.c +++ b/keyboards/atomic/keymaps/pvc/keymap.c | |||
@@ -345,14 +345,14 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
345 | case MACRO_BREATH_SPEED_INC: | 345 | case MACRO_BREATH_SPEED_INC: |
346 | if (record->event.pressed) | 346 | if (record->event.pressed) |
347 | { | 347 | { |
348 | breathing_speed_inc(1); | 348 | breathing_period_inc(); |
349 | } | 349 | } |
350 | break; | 350 | break; |
351 | 351 | ||
352 | case MACRO_BREATH_SPEED_DEC: | 352 | case MACRO_BREATH_SPEED_DEC: |
353 | if (record->event.pressed) | 353 | if (record->event.pressed) |
354 | { | 354 | { |
355 | breathing_speed_dec(1); | 355 | breathing_period_dec(); |
356 | } | 356 | } |
357 | break; | 357 | break; |
358 | 358 | ||
@@ -374,7 +374,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
374 | if (record->event.pressed) | 374 | if (record->event.pressed) |
375 | { | 375 | { |
376 | layer_on(LAYER_UPPER); | 376 | layer_on(LAYER_UPPER); |
377 | breathing_speed_set(2); | 377 | breathing_period_set(2); |
378 | breathing_pulse(); | 378 | breathing_pulse(); |
379 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); | 379 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); |
380 | } | 380 | } |
@@ -389,7 +389,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
389 | if (record->event.pressed) | 389 | if (record->event.pressed) |
390 | { | 390 | { |
391 | layer_on(LAYER_LOWER); | 391 | layer_on(LAYER_LOWER); |
392 | breathing_speed_set(2); | 392 | breathing_period_set(2); |
393 | breathing_pulse(); | 393 | breathing_pulse(); |
394 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); | 394 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); |
395 | } | 395 | } |
@@ -403,13 +403,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
403 | case MACRO_FUNCTION: | 403 | case MACRO_FUNCTION: |
404 | if (record->event.pressed) | 404 | if (record->event.pressed) |
405 | { | 405 | { |
406 | breathing_speed_set(3); | 406 | breathing_period_set(3); |
407 | breathing_enable(); | 407 | breathing_enable(); |
408 | layer_on(LAYER_FUNCTION); | 408 | layer_on(LAYER_FUNCTION); |
409 | } | 409 | } |
410 | else | 410 | else |
411 | { | 411 | { |
412 | breathing_speed_set(1); | 412 | breathing_period_set(1); |
413 | breathing_self_disable(); | 413 | breathing_self_disable(); |
414 | layer_off(LAYER_FUNCTION); | 414 | layer_off(LAYER_FUNCTION); |
415 | } | 415 | } |
diff --git a/keyboards/bananasplit/config.h b/keyboards/bananasplit/config.h index 4bb5b85e0..5649ab4aa 100644 --- a/keyboards/bananasplit/config.h +++ b/keyboards/bananasplit/config.h | |||
@@ -42,7 +42,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
42 | //#define MATRIX_HAS_GHOST | 42 | //#define MATRIX_HAS_GHOST |
43 | 43 | ||
44 | /* number of backlight levels */ | 44 | /* number of backlight levels */ |
45 | #define BACKLIGHT_LEVELS 1 | 45 | #define BACKLIGHT_LEVELS 3 |
46 | 46 | ||
47 | /* mapping backlight LEDs to correct Pin */ | 47 | /* mapping backlight LEDs to correct Pin */ |
48 | #define BACKLIGHT_PIN B7 | 48 | #define BACKLIGHT_PIN B7 |
diff --git a/keyboards/bananasplit/keymaps/coloneljesus/config.h b/keyboards/bananasplit/keymaps/coloneljesus/config.h index 5f2cd13fe..92a67f647 100644 --- a/keyboards/bananasplit/keymaps/coloneljesus/config.h +++ b/keyboards/bananasplit/keymaps/coloneljesus/config.h | |||
@@ -21,5 +21,7 @@ | |||
21 | 21 | ||
22 | // place overrides here | 22 | // place overrides here |
23 | #define GRAVE_ESC_CTRL_OVERRIDE | 23 | #define GRAVE_ESC_CTRL_OVERRIDE |
24 | #define BACKLIGHT_BREATHING | ||
25 | #define BREATHING_PERIOD 8 | ||
24 | 26 | ||
25 | #endif | 27 | #endif |
diff --git a/keyboards/bananasplit/keymaps/coloneljesus/keymap.c b/keyboards/bananasplit/keymaps/coloneljesus/keymap.c index ac7f1113a..b5889aa19 100644 --- a/keyboards/bananasplit/keymaps/coloneljesus/keymap.c +++ b/keyboards/bananasplit/keymaps/coloneljesus/keymap.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include "bananasplit.h" | 16 | #include "bananasplit.h" |
17 | 17 | ||
18 | enum custom_keycodes { | 18 | enum custom_keycodes { |
19 | WIN_SWITCH_LAYOUT = SAFE_RANGE | 19 | WIN_SWITCH_LAYOUT = SAFE_RANGE, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | 22 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { |
@@ -57,7 +57,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
57 | _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, \ | 57 | _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, \ |
58 | KC_CAPS, KC_MPRV, KC_VOLU, KC_MNXT, KC_PGUP, KC_INS, KC_HOME, LCTL(KC_LEFT), LCTL(KC_RGHT), KC_END, _______, _______, _______, KC_PSCR, \ | 58 | KC_CAPS, KC_MPRV, KC_VOLU, KC_MNXT, KC_PGUP, KC_INS, KC_HOME, LCTL(KC_LEFT), LCTL(KC_RGHT), KC_END, _______, _______, _______, KC_PSCR, \ |
59 | _______, KC_MUTE, KC_VOLD, KC_MPLY, KC_PGDN, KC_DEL, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______, \ | 59 | _______, KC_MUTE, KC_VOLD, KC_MPLY, KC_PGDN, KC_DEL, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, _______, _______, _______, \ |
60 | _______, _______, _______, _______, _______,_______, LCTL(KC_BSPC), LCTL(KC_DEL), _______, _______, _______, _______, _______, \ | 60 | _______, BL_STEP, BL_BRTG, _______, _______,_______, LCTL(KC_BSPC), LCTL(KC_DEL), _______, _______, _______, _______, _______, \ |
61 | _______, _______, _______, _______, _______,_______, _______, _______, _______, _______, RESET \ | 61 | _______, _______, _______, _______, _______,_______, _______, _______, _______, _______, RESET \ |
62 | ), | 62 | ), |
63 | }; | 63 | }; |
@@ -76,19 +76,19 @@ void matrix_scan_user(void) { | |||
76 | 76 | ||
77 | bool process_record_user(uint16_t keycode, keyrecord_t *record) { | 77 | bool process_record_user(uint16_t keycode, keyrecord_t *record) { |
78 | switch (keycode) { | 78 | switch (keycode) { |
79 | |||
79 | case WIN_SWITCH_LAYOUT: { | 80 | case WIN_SWITCH_LAYOUT: { |
80 | // Sends Alt+Shift on both key down and key up. | 81 | // Sends Alt+Shift on both key down and key up. |
81 | // Designed to switch between two keyboard layouts on Windows using a locking switch. | 82 | // Designed to switch between two keyboard layouts on Windows using a locking switch. |
82 | // Does nothing if right shift is pressed for easy resync. | 83 | // Does nothing if right shift is pressed for easy resync. |
83 | if (!(get_mods() & MOD_BIT(KC_RSFT))) { | 84 | if (!(get_mods() & MOD_BIT(KC_RSFT))) |
84 | SEND_STRING(SS_DOWN(X_LALT)SS_TAP(X_LSHIFT)SS_UP(X_LALT)); | 85 | SEND_STRING(SS_DOWN(X_LALT)SS_TAP(X_LSHIFT)SS_UP(X_LALT)); |
85 | return false; | 86 | return false; |
86 | } | ||
87 | else | ||
88 | return false; | ||
89 | } | 87 | } |
88 | |||
89 | default: | ||
90 | return true; | ||
90 | } | 91 | } |
91 | return true; | ||
92 | } | 92 | } |
93 | 93 | ||
94 | void led_set_user(uint8_t usb_led) { | 94 | void led_set_user(uint8_t usb_led) { |
diff --git a/keyboards/jd45/keymaps/mjt/keymap.c b/keyboards/jd45/keymaps/mjt/keymap.c index 1a7302216..610552ecf 100644 --- a/keyboards/jd45/keymaps/mjt/keymap.c +++ b/keyboards/jd45/keymaps/mjt/keymap.c | |||
@@ -50,13 +50,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
50 | // action_function_tap may also handle this... | 50 | // action_function_tap may also handle this... |
51 | if (record->event.pressed) | 51 | if (record->event.pressed) |
52 | { | 52 | { |
53 | breathing_speed_set(3); | 53 | breathing_period_set(3); |
54 | breathing_enable(); | 54 | breathing_enable(); |
55 | layer_on(1); | 55 | layer_on(1); |
56 | } | 56 | } |
57 | else | 57 | else |
58 | { | 58 | { |
59 | breathing_speed_set(1); | 59 | breathing_period_set(1); |
60 | breathing_self_disable(); | 60 | breathing_self_disable(); |
61 | layer_off(1); | 61 | layer_off(1); |
62 | } | 62 | } |
@@ -64,13 +64,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
64 | case M_LAYER2: | 64 | case M_LAYER2: |
65 | if (record->event.pressed) | 65 | if (record->event.pressed) |
66 | { | 66 | { |
67 | breathing_speed_set(2); | 67 | breathing_period_set(2); |
68 | breathing_pulse(); | 68 | breathing_pulse(); |
69 | layer_on(2); | 69 | layer_on(2); |
70 | } | 70 | } |
71 | else | 71 | else |
72 | { | 72 | { |
73 | breathing_speed_set(1); | 73 | breathing_period_set(1); |
74 | breathing_self_disable(); | 74 | breathing_self_disable(); |
75 | layer_off(2); | 75 | layer_off(2); |
76 | } | 76 | } |
diff --git a/keyboards/planck/keymaps/cbbrowne/keymap.c b/keyboards/planck/keymaps/cbbrowne/keymap.c index d1214dda1..9bae6fb50 100644 --- a/keyboards/planck/keymaps/cbbrowne/keymap.c +++ b/keyboards/planck/keymaps/cbbrowne/keymap.c | |||
@@ -220,7 +220,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
220 | { | 220 | { |
221 | layer_on(_RAISE); | 221 | layer_on(_RAISE); |
222 | #ifdef BACKLIGHT_ENABLE | 222 | #ifdef BACKLIGHT_ENABLE |
223 | breathing_speed_set(2); | 223 | breathing_period_set(2); |
224 | breathing_pulse(); | 224 | breathing_pulse(); |
225 | #endif | 225 | #endif |
226 | update_tri_layer(_LOWER, _RAISE, _ADJUST); | 226 | update_tri_layer(_LOWER, _RAISE, _ADJUST); |
@@ -236,7 +236,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
236 | { | 236 | { |
237 | layer_on(_LOWER); | 237 | layer_on(_LOWER); |
238 | #ifdef BACKLIGHT_ENABLE | 238 | #ifdef BACKLIGHT_ENABLE |
239 | breathing_speed_set(2); | 239 | breathing_period_set(2); |
240 | breathing_pulse(); | 240 | breathing_pulse(); |
241 | #endif | 241 | #endif |
242 | update_tri_layer(_LOWER, _RAISE, _ADJUST); | 242 | update_tri_layer(_LOWER, _RAISE, _ADJUST); |
diff --git a/keyboards/planck/keymaps/experimental/keymap.c b/keyboards/planck/keymaps/experimental/keymap.c index 272c09332..feeb137fa 100644 --- a/keyboards/planck/keymaps/experimental/keymap.c +++ b/keyboards/planck/keymaps/experimental/keymap.c | |||
@@ -242,7 +242,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
242 | if (record->event.pressed) { | 242 | if (record->event.pressed) { |
243 | layer_on(_LOWER); | 243 | layer_on(_LOWER); |
244 | #ifdef BACKLIGHT_ENABLE | 244 | #ifdef BACKLIGHT_ENABLE |
245 | breathing_speed_set(2); | 245 | breathing_period_set(2); |
246 | breathing_pulse(); | 246 | breathing_pulse(); |
247 | #endif | 247 | #endif |
248 | update_tri_layer(_LOWER, _RAISE, _ADJUST); | 248 | update_tri_layer(_LOWER, _RAISE, _ADJUST); |
@@ -256,7 +256,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
256 | if (record->event.pressed) { | 256 | if (record->event.pressed) { |
257 | layer_on(_RAISE); | 257 | layer_on(_RAISE); |
258 | #ifdef BACKLIGHT_ENABLE | 258 | #ifdef BACKLIGHT_ENABLE |
259 | breathing_speed_set(2); | 259 | breathing_period_set(2); |
260 | breathing_pulse(); | 260 | breathing_pulse(); |
261 | #endif | 261 | #endif |
262 | update_tri_layer(_LOWER, _RAISE, _ADJUST); | 262 | update_tri_layer(_LOWER, _RAISE, _ADJUST); |
diff --git a/keyboards/planck/keymaps/khord/keymap.c b/keyboards/planck/keymaps/khord/keymap.c index c8022a389..c515a0d36 100644 --- a/keyboards/planck/keymaps/khord/keymap.c +++ b/keyboards/planck/keymaps/khord/keymap.c | |||
@@ -128,12 +128,12 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { | |||
128 | break; | 128 | break; |
129 | case MACRO_BREATH_SPEED_INC: | 129 | case MACRO_BREATH_SPEED_INC: |
130 | if (record->event.pressed) { | 130 | if (record->event.pressed) { |
131 | breathing_speed_inc(1); | 131 | breathing_period_inc(); |
132 | } | 132 | } |
133 | break; | 133 | break; |
134 | case MACRO_BREATH_SPEED_DEC: | 134 | case MACRO_BREATH_SPEED_DEC: |
135 | if (record->event.pressed) { | 135 | if (record->event.pressed) { |
136 | breathing_speed_dec(1); | 136 | breathing_period_dec(); |
137 | } | 137 | } |
138 | break; | 138 | break; |
139 | case MACRO_BREATH_DEFAULT: | 139 | case MACRO_BREATH_DEFAULT: |
diff --git a/keyboards/planck/keymaps/pvc/keymap.c b/keyboards/planck/keymaps/pvc/keymap.c index 60f6d925a..820018af6 100644 --- a/keyboards/planck/keymaps/pvc/keymap.c +++ b/keyboards/planck/keymaps/pvc/keymap.c | |||
@@ -323,14 +323,14 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
323 | case MACRO_BREATH_SPEED_INC: | 323 | case MACRO_BREATH_SPEED_INC: |
324 | if (record->event.pressed) | 324 | if (record->event.pressed) |
325 | { | 325 | { |
326 | breathing_speed_inc(1); | 326 | breathing_period_inc(); |
327 | } | 327 | } |
328 | break; | 328 | break; |
329 | 329 | ||
330 | case MACRO_BREATH_SPEED_DEC: | 330 | case MACRO_BREATH_SPEED_DEC: |
331 | if (record->event.pressed) | 331 | if (record->event.pressed) |
332 | { | 332 | { |
333 | breathing_speed_dec(1); | 333 | breathing_period_dec(); |
334 | } | 334 | } |
335 | break; | 335 | break; |
336 | 336 | ||
@@ -352,7 +352,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
352 | if (record->event.pressed) | 352 | if (record->event.pressed) |
353 | { | 353 | { |
354 | layer_on(LAYER_UPPER); | 354 | layer_on(LAYER_UPPER); |
355 | breathing_speed_set(2); | 355 | breathing_period_set(2); |
356 | breathing_pulse(); | 356 | breathing_pulse(); |
357 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); | 357 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); |
358 | } | 358 | } |
@@ -367,7 +367,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
367 | if (record->event.pressed) | 367 | if (record->event.pressed) |
368 | { | 368 | { |
369 | layer_on(LAYER_LOWER); | 369 | layer_on(LAYER_LOWER); |
370 | breathing_speed_set(2); | 370 | breathing_period_set(2); |
371 | breathing_pulse(); | 371 | breathing_pulse(); |
372 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); | 372 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); |
373 | } | 373 | } |
@@ -381,13 +381,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
381 | case MACRO_FUNCTION: | 381 | case MACRO_FUNCTION: |
382 | if (record->event.pressed) | 382 | if (record->event.pressed) |
383 | { | 383 | { |
384 | breathing_speed_set(3); | 384 | breathing_period_set(3); |
385 | breathing_enable(); | 385 | breathing_enable(); |
386 | layer_on(LAYER_FUNCTION); | 386 | layer_on(LAYER_FUNCTION); |
387 | } | 387 | } |
388 | else | 388 | else |
389 | { | 389 | { |
390 | breathing_speed_set(1); | 390 | breathing_period_set(1); |
391 | breathing_self_disable(); | 391 | breathing_self_disable(); |
392 | layer_off(LAYER_FUNCTION); | 392 | layer_off(LAYER_FUNCTION); |
393 | } | 393 | } |
diff --git a/keyboards/planck/keymaps/zach/zach_common_functions.c b/keyboards/planck/keymaps/zach/zach_common_functions.c index f824b4033..e6aeaa50a 100644 --- a/keyboards/planck/keymaps/zach/zach_common_functions.c +++ b/keyboards/planck/keymaps/zach/zach_common_functions.c | |||
@@ -270,7 +270,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
270 | PLAY_SONG(tone_ctrl_mod); | 270 | PLAY_SONG(tone_ctrl_mod); |
271 | #endif | 271 | #endif |
272 | #ifdef BACKLIGHT_BREATHING | 272 | #ifdef BACKLIGHT_BREATHING |
273 | breathing_speed_set(2); | 273 | breathing_period_set(2); |
274 | breathing_pulse(); | 274 | breathing_pulse(); |
275 | #endif | 275 | #endif |
276 | } | 276 | } |
diff --git a/keyboards/planck/keymaps/zrichard/keymap.c b/keyboards/planck/keymaps/zrichard/keymap.c index c40492f5e..cf4478cee 100755 --- a/keyboards/planck/keymaps/zrichard/keymap.c +++ b/keyboards/planck/keymaps/zrichard/keymap.c | |||
@@ -332,14 +332,14 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
332 | case MACRO_BREATH_SPEED_INC: | 332 | case MACRO_BREATH_SPEED_INC: |
333 | if (record->event.pressed) | 333 | if (record->event.pressed) |
334 | { | 334 | { |
335 | breathing_speed_inc(1); | 335 | breathing_period_inc(); |
336 | } | 336 | } |
337 | break; | 337 | break; |
338 | 338 | ||
339 | case MACRO_BREATH_SPEED_DEC: | 339 | case MACRO_BREATH_SPEED_DEC: |
340 | if (record->event.pressed) | 340 | if (record->event.pressed) |
341 | { | 341 | { |
342 | breathing_speed_dec(1); | 342 | breathing_period_dec(); |
343 | } | 343 | } |
344 | break; | 344 | break; |
345 | 345 | ||
@@ -361,7 +361,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
361 | if (record->event.pressed) | 361 | if (record->event.pressed) |
362 | { | 362 | { |
363 | layer_on(LAYER_UPPER); | 363 | layer_on(LAYER_UPPER); |
364 | breathing_speed_set(2); | 364 | breathing_period_set(2); |
365 | breathing_pulse(); | 365 | breathing_pulse(); |
366 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); | 366 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); |
367 | } | 367 | } |
@@ -376,7 +376,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
376 | if (record->event.pressed) | 376 | if (record->event.pressed) |
377 | { | 377 | { |
378 | layer_on(LAYER_LOWER); | 378 | layer_on(LAYER_LOWER); |
379 | breathing_speed_set(2); | 379 | breathing_period_set(2); |
380 | breathing_pulse(); | 380 | breathing_pulse(); |
381 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); | 381 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); |
382 | } | 382 | } |
@@ -390,13 +390,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
390 | case MACRO_FUNCTION: | 390 | case MACRO_FUNCTION: |
391 | if (record->event.pressed) | 391 | if (record->event.pressed) |
392 | { | 392 | { |
393 | breathing_speed_set(3); | 393 | breathing_period_set(3); |
394 | breathing_enable(); | 394 | breathing_enable(); |
395 | layer_on(LAYER_FUNCTION); | 395 | layer_on(LAYER_FUNCTION); |
396 | } | 396 | } |
397 | else | 397 | else |
398 | { | 398 | { |
399 | breathing_speed_set(1); | 399 | breathing_period_set(1); |
400 | breathing_self_disable(); | 400 | breathing_self_disable(); |
401 | layer_off(LAYER_FUNCTION); | 401 | layer_off(LAYER_FUNCTION); |
402 | } | 402 | } |
diff --git a/keyboards/preonic/keymaps/zach/zach_common_functions.c b/keyboards/preonic/keymaps/zach/zach_common_functions.c index f824b4033..e6aeaa50a 100644 --- a/keyboards/preonic/keymaps/zach/zach_common_functions.c +++ b/keyboards/preonic/keymaps/zach/zach_common_functions.c | |||
@@ -270,7 +270,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |||
270 | PLAY_SONG(tone_ctrl_mod); | 270 | PLAY_SONG(tone_ctrl_mod); |
271 | #endif | 271 | #endif |
272 | #ifdef BACKLIGHT_BREATHING | 272 | #ifdef BACKLIGHT_BREATHING |
273 | breathing_speed_set(2); | 273 | breathing_period_set(2); |
274 | breathing_pulse(); | 274 | breathing_pulse(); |
275 | #endif | 275 | #endif |
276 | } | 276 | } |
diff --git a/keyboards/vision_division/keymaps/default/keymap.c b/keyboards/vision_division/keymaps/default/keymap.c index c40bf1ef6..31b107661 100644 --- a/keyboards/vision_division/keymaps/default/keymap.c +++ b/keyboards/vision_division/keymaps/default/keymap.c | |||
@@ -406,21 +406,21 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
406 | case MACRO_BREATH_SPEED_INC: | 406 | case MACRO_BREATH_SPEED_INC: |
407 | if (record->event.pressed) | 407 | if (record->event.pressed) |
408 | { | 408 | { |
409 | breathing_speed_inc(1); | 409 | breathing_period_inc(); |
410 | } | 410 | } |
411 | break; | 411 | break; |
412 | 412 | ||
413 | case MACRO_BREATH_SPEED_DEC: | 413 | case MACRO_BREATH_SPEED_DEC: |
414 | if (record->event.pressed) | 414 | if (record->event.pressed) |
415 | { | 415 | { |
416 | breathing_speed_dec(1); | 416 | breathing_period_dec(); |
417 | } | 417 | } |
418 | break; | 418 | break; |
419 | 419 | ||
420 | case MACRO_BREATH_DEFAULT: | 420 | case MACRO_BREATH_DEFAULT: |
421 | if (record->event.pressed) | 421 | if (record->event.pressed) |
422 | { | 422 | { |
423 | breathing_defaults(); | 423 | breathing_period_default(); |
424 | } | 424 | } |
425 | break; | 425 | break; |
426 | 426 | ||
@@ -435,7 +435,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
435 | if (record->event.pressed) | 435 | if (record->event.pressed) |
436 | { | 436 | { |
437 | layer_on(LAYER_UPPER); | 437 | layer_on(LAYER_UPPER); |
438 | breathing_speed_set(2); | 438 | breathing_period_set(2); |
439 | breathing_pulse(); | 439 | breathing_pulse(); |
440 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); | 440 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); |
441 | } | 441 | } |
@@ -450,7 +450,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
450 | if (record->event.pressed) | 450 | if (record->event.pressed) |
451 | { | 451 | { |
452 | layer_on(LAYER_LOWER); | 452 | layer_on(LAYER_LOWER); |
453 | breathing_speed_set(2); | 453 | breathing_period_set(2); |
454 | breathing_pulse(); | 454 | breathing_pulse(); |
455 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); | 455 | update_tri_layer(LAYER_LOWER, LAYER_UPPER, LAYER_ADJUST); |
456 | } | 456 | } |
@@ -464,13 +464,13 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
464 | case MACRO_FUNCTION: | 464 | case MACRO_FUNCTION: |
465 | if (record->event.pressed) | 465 | if (record->event.pressed) |
466 | { | 466 | { |
467 | breathing_speed_set(3); | 467 | breathing_period_set(3); |
468 | breathing_enable(); | 468 | breathing_enable(); |
469 | layer_on(LAYER_FUNCTION); | 469 | layer_on(LAYER_FUNCTION); |
470 | } | 470 | } |
471 | else | 471 | else |
472 | { | 472 | { |
473 | breathing_speed_set(1); | 473 | breathing_period_set(1); |
474 | breathing_self_disable(); | 474 | breathing_self_disable(); |
475 | layer_off(LAYER_FUNCTION); | 475 | layer_off(LAYER_FUNCTION); |
476 | } | 476 | } |
diff --git a/keyboards/xd75/keymaps/cbbrowne/keymap.c b/keyboards/xd75/keymaps/cbbrowne/keymap.c index 5496ed40d..ec98b6d5a 100644 --- a/keyboards/xd75/keymaps/cbbrowne/keymap.c +++ b/keyboards/xd75/keymaps/cbbrowne/keymap.c | |||
@@ -265,7 +265,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
265 | { | 265 | { |
266 | layer_on(_RAISE); | 266 | layer_on(_RAISE); |
267 | #ifdef BACKLIGHT_ENABLE | 267 | #ifdef BACKLIGHT_ENABLE |
268 | breathing_speed_set(2); | 268 | breathing_period_set(2); |
269 | breathing_pulse(); | 269 | breathing_pulse(); |
270 | #endif | 270 | #endif |
271 | update_tri_layer(_LOWER, _RAISE, _ADJUST); | 271 | update_tri_layer(_LOWER, _RAISE, _ADJUST); |
@@ -281,7 +281,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
281 | { | 281 | { |
282 | layer_on(_LOWER); | 282 | layer_on(_LOWER); |
283 | #ifdef BACKLIGHT_ENABLE | 283 | #ifdef BACKLIGHT_ENABLE |
284 | breathing_speed_set(2); | 284 | breathing_period_set(2); |
285 | breathing_pulse(); | 285 | breathing_pulse(); |
286 | #endif | 286 | #endif |
287 | update_tri_layer(_LOWER, _RAISE, _ADJUST); | 287 | update_tri_layer(_LOWER, _RAISE, _ADJUST); |
diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c index b1460c53c..a0d4c1ddb 100644 --- a/quantum/keymap_common.c +++ b/quantum/keymap_common.c | |||
@@ -127,8 +127,11 @@ action_t action_for_key(uint8_t layer, keypos_t key) | |||
127 | action.code = ACTION_MODS_TAP_KEY(mod, keycode & 0xFF); | 127 | action.code = ACTION_MODS_TAP_KEY(mod, keycode & 0xFF); |
128 | break; | 128 | break; |
129 | #ifdef BACKLIGHT_ENABLE | 129 | #ifdef BACKLIGHT_ENABLE |
130 | case BL_0 ... BL_15: | 130 | case BL_ON: |
131 | action.code = ACTION_BACKLIGHT_LEVEL(keycode - BL_0); | 131 | action.code = ACTION_BACKLIGHT_ON(); |
132 | break; | ||
133 | case BL_OFF: | ||
134 | action.code = ACTION_BACKLIGHT_OFF(); | ||
132 | break; | 135 | break; |
133 | case BL_DEC: | 136 | case BL_DEC: |
134 | action.code = ACTION_BACKLIGHT_DECREASE(); | 137 | action.code = ACTION_BACKLIGHT_DECREASE(); |
diff --git a/quantum/quantum.c b/quantum/quantum.c index c80975f21..88617412c 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c | |||
@@ -23,6 +23,10 @@ | |||
23 | #define TAPPING_TERM 200 | 23 | #define TAPPING_TERM 200 |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #ifndef BREATHING_PERIOD | ||
27 | #define BREATHING_PERIOD 6 | ||
28 | #endif | ||
29 | |||
26 | #include "backlight.h" | 30 | #include "backlight.h" |
27 | extern backlight_config_t backlight_config; | 31 | extern backlight_config_t backlight_config; |
28 | 32 | ||
@@ -618,7 +622,17 @@ bool process_record_quantum(keyrecord_t *record) { | |||
618 | } | 622 | } |
619 | 623 | ||
620 | send_keyboard_report(); | 624 | send_keyboard_report(); |
625 | return false; | ||
621 | } | 626 | } |
627 | |||
628 | #if defined(BACKLIGHT_ENABLE) && defined(BACKLIGHT_BREATHING) | ||
629 | case BL_BRTG: { | ||
630 | if (record->event.pressed) | ||
631 | breathing_toggle(); | ||
632 | return false; | ||
633 | } | ||
634 | #endif | ||
635 | |||
622 | default: { | 636 | default: { |
623 | shift_interrupted[0] = true; | 637 | shift_interrupted[0] = true; |
624 | shift_interrupted[1] = true; | 638 | shift_interrupted[1] = true; |
@@ -831,6 +845,7 @@ void matrix_scan_quantum() { | |||
831 | 845 | ||
832 | static const uint8_t backlight_pin = BACKLIGHT_PIN; | 846 | static const uint8_t backlight_pin = BACKLIGHT_PIN; |
833 | 847 | ||
848 | // depending on the pin, we use a different output compare unit | ||
834 | #if BACKLIGHT_PIN == B7 | 849 | #if BACKLIGHT_PIN == B7 |
835 | # define COM1x1 COM1C1 | 850 | # define COM1x1 COM1C1 |
836 | # define OCR1x OCR1C | 851 | # define OCR1x OCR1C |
@@ -841,17 +856,18 @@ static const uint8_t backlight_pin = BACKLIGHT_PIN; | |||
841 | # define COM1x1 COM1A1 | 856 | # define COM1x1 COM1A1 |
842 | # define OCR1x OCR1A | 857 | # define OCR1x OCR1A |
843 | #else | 858 | #else |
844 | # define NO_BACKLIGHT_CLOCK | 859 | # define NO_HARDWARE_PWM |
845 | #endif | 860 | #endif |
846 | 861 | ||
847 | #ifndef BACKLIGHT_ON_STATE | 862 | #ifndef BACKLIGHT_ON_STATE |
848 | #define BACKLIGHT_ON_STATE 0 | 863 | #define BACKLIGHT_ON_STATE 0 |
849 | #endif | 864 | #endif |
850 | 865 | ||
866 | #ifdef NO_HARDWARE_PWM // pwm through software | ||
867 | |||
851 | __attribute__ ((weak)) | 868 | __attribute__ ((weak)) |
852 | void backlight_init_ports(void) | 869 | void backlight_init_ports(void) |
853 | { | 870 | { |
854 | |||
855 | // Setup backlight pin as output and output to on state. | 871 | // Setup backlight pin as output and output to on state. |
856 | // DDRx |= n | 872 | // DDRx |= n |
857 | _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); | 873 | _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); |
@@ -862,83 +878,15 @@ void backlight_init_ports(void) | |||
862 | // PORTx |= n | 878 | // PORTx |= n |
863 | _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); | 879 | _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); |
864 | #endif | 880 | #endif |
865 | |||
866 | #ifndef NO_BACKLIGHT_CLOCK | ||
867 | // Use full 16-bit resolution. | ||
868 | ICR1 = 0xFFFF; | ||
869 | |||
870 | // I could write a wall of text here to explain... but TL;DW | ||
871 | // Go read the ATmega32u4 datasheet. | ||
872 | // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on | ||
873 | |||
874 | // Pin PB7 = OCR1C (Timer 1, Channel C) | ||
875 | // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 | ||
876 | // (i.e. start high, go low when counter matches.) | ||
877 | // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 | ||
878 | // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 | ||
879 | |||
880 | TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; | ||
881 | TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; | ||
882 | #endif | ||
883 | |||
884 | backlight_init(); | ||
885 | #ifdef BACKLIGHT_BREATHING | ||
886 | breathing_defaults(); | ||
887 | #endif | ||
888 | } | 881 | } |
889 | 882 | ||
890 | __attribute__ ((weak)) | 883 | __attribute__ ((weak)) |
891 | void backlight_set(uint8_t level) | 884 | void backlight_set(uint8_t level) {} |
892 | { | ||
893 | // Prevent backlight blink on lowest level | ||
894 | // #if BACKLIGHT_ON_STATE == 0 | ||
895 | // // PORTx &= ~n | ||
896 | // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | ||
897 | // #else | ||
898 | // // PORTx |= n | ||
899 | // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); | ||
900 | // #endif | ||
901 | |||
902 | if ( level == 0 ) { | ||
903 | #ifndef NO_BACKLIGHT_CLOCK | ||
904 | // Turn off PWM control on backlight pin, revert to output low. | ||
905 | TCCR1A &= ~(_BV(COM1x1)); | ||
906 | OCR1x = 0x0; | ||
907 | #else | ||
908 | // #if BACKLIGHT_ON_STATE == 0 | ||
909 | // // PORTx |= n | ||
910 | // _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); | ||
911 | // #else | ||
912 | // // PORTx &= ~n | ||
913 | // _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | ||
914 | // #endif | ||
915 | #endif | ||
916 | } | ||
917 | #ifndef NO_BACKLIGHT_CLOCK | ||
918 | else if ( level == BACKLIGHT_LEVELS ) { | ||
919 | // Turn on PWM control of backlight pin | ||
920 | TCCR1A |= _BV(COM1x1); | ||
921 | // Set the brightness | ||
922 | OCR1x = 0xFFFF; | ||
923 | } | ||
924 | else { | ||
925 | // Turn on PWM control of backlight pin | ||
926 | TCCR1A |= _BV(COM1x1); | ||
927 | // Set the brightness | ||
928 | OCR1x = 0xFFFF >> ((BACKLIGHT_LEVELS - level) * ((BACKLIGHT_LEVELS + 1) / 2)); | ||
929 | } | ||
930 | #endif | ||
931 | |||
932 | #ifdef BACKLIGHT_BREATHING | ||
933 | breathing_intensity_default(); | ||
934 | #endif | ||
935 | } | ||
936 | 885 | ||
937 | uint8_t backlight_tick = 0; | 886 | uint8_t backlight_tick = 0; |
938 | 887 | ||
939 | void backlight_task(void) { | 888 | void backlight_task(void) { |
940 | #ifdef NO_BACKLIGHT_CLOCK | 889 | if ((0xFFFF >> ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) { |
941 | if ((0xFFFF >> ((BACKLIGHT_LEVELS - backlight_config.level) * ((BACKLIGHT_LEVELS + 1) / 2))) & (1 << backlight_tick)) { | ||
942 | #if BACKLIGHT_ON_STATE == 0 | 890 | #if BACKLIGHT_ON_STATE == 0 |
943 | // PORTx &= ~n | 891 | // PORTx &= ~n |
944 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | 892 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); |
@@ -955,232 +903,216 @@ void backlight_task(void) { | |||
955 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); | 903 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); |
956 | #endif | 904 | #endif |
957 | } | 905 | } |
958 | backlight_tick = (backlight_tick + 1) % 16; | 906 | backlight_tick = backlight_tick + 1 % 16; |
959 | #endif | ||
960 | } | 907 | } |
961 | 908 | ||
962 | #ifdef BACKLIGHT_BREATHING | 909 | #ifdef BACKLIGHT_BREATHING |
910 | #error "Backlight breathing only available with hardware PWM. Please disable." | ||
911 | #endif | ||
963 | 912 | ||
964 | #ifdef NO_BACKLIGHT_CLOCK | 913 | #else // pwm through timer |
965 | void breathing_defaults(void) {} | 914 | |
966 | void breathing_intensity_default(void) {} | 915 | #define TIMER_TOP 0xFFFFU |
967 | #else | 916 | |
917 | // See http://jared.geek.nz/2013/feb/linear-led-pwm | ||
918 | static uint16_t cie_lightness(uint16_t v) { | ||
919 | if (v <= 5243) // if below 8% of max | ||
920 | return v / 9; // same as dividing by 900% | ||
921 | else { | ||
922 | uint32_t y = (((uint32_t) v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare | ||
923 | // to get a useful result with integer division, we shift left in the expression above | ||
924 | // and revert what we've done again after squaring. | ||
925 | y = y * y * y >> 8; | ||
926 | if (y > 0xFFFFUL) // prevent overflow | ||
927 | return 0xFFFFU; | ||
928 | else | ||
929 | return (uint16_t) y; | ||
930 | } | ||
931 | } | ||
932 | |||
933 | // range for val is [0..TIMER_TOP]. PWM pin is high while the timer count is below val. | ||
934 | static inline void set_pwm(uint16_t val) { | ||
935 | OCR1x = val; | ||
936 | } | ||
937 | |||
938 | __attribute__ ((weak)) | ||
939 | void backlight_set(uint8_t level) { | ||
940 | if (level > BACKLIGHT_LEVELS) | ||
941 | level = BACKLIGHT_LEVELS; | ||
942 | |||
943 | if (level == 0) { | ||
944 | // Turn off PWM control on backlight pin | ||
945 | TCCR1A &= ~(_BV(COM1x1)); | ||
946 | } else { | ||
947 | // Turn on PWM control of backlight pin | ||
948 | TCCR1A |= _BV(COM1x1); | ||
949 | } | ||
950 | // Set the brightness | ||
951 | set_pwm(cie_lightness(TIMER_TOP * (uint32_t)level / BACKLIGHT_LEVELS)); | ||
952 | } | ||
953 | |||
954 | void backlight_task(void) {} | ||
955 | |||
956 | #ifdef BACKLIGHT_BREATHING | ||
968 | 957 | ||
969 | #define BREATHING_NO_HALT 0 | 958 | #define BREATHING_NO_HALT 0 |
970 | #define BREATHING_HALT_OFF 1 | 959 | #define BREATHING_HALT_OFF 1 |
971 | #define BREATHING_HALT_ON 2 | 960 | #define BREATHING_HALT_ON 2 |
961 | #define BREATHING_STEPS 128 | ||
972 | 962 | ||
973 | static uint8_t breath_intensity; | 963 | static uint8_t breathing_period = BREATHING_PERIOD; |
974 | static uint8_t breath_speed; | 964 | static uint8_t breathing_halt = BREATHING_NO_HALT; |
975 | static uint16_t breathing_index; | 965 | static uint16_t breathing_counter = 0; |
976 | static uint8_t breathing_halt; | ||
977 | 966 | ||
978 | void breathing_enable(void) | 967 | bool is_breathing(void) { |
979 | { | 968 | return !!(TIMSK1 & _BV(TOIE1)); |
980 | if (get_backlight_level() == 0) | 969 | } |
981 | { | ||
982 | breathing_index = 0; | ||
983 | } | ||
984 | else | ||
985 | { | ||
986 | // Set breathing_index to be at the midpoint (brightest point) | ||
987 | breathing_index = 0x20 << breath_speed; | ||
988 | } | ||
989 | 970 | ||
990 | breathing_halt = BREATHING_NO_HALT; | 971 | #define breathing_interrupt_enable() do {TIMSK1 |= _BV(TOIE1);} while (0) |
972 | #define breathing_interrupt_disable() do {TIMSK1 &= ~_BV(TOIE1);} while (0) | ||
973 | #define breathing_min() do {breathing_counter = 0;} while (0) | ||
974 | #define breathing_max() do {breathing_counter = breathing_period * 244 / 2;} while (0) | ||
991 | 975 | ||
992 | // Enable breathing interrupt | 976 | void breathing_enable(void) |
993 | TIMSK1 |= _BV(OCIE1A); | 977 | { |
978 | breathing_counter = 0; | ||
979 | breathing_halt = BREATHING_NO_HALT; | ||
980 | breathing_interrupt_enable(); | ||
994 | } | 981 | } |
995 | 982 | ||
996 | void breathing_pulse(void) | 983 | void breathing_pulse(void) |
997 | { | 984 | { |
998 | if (get_backlight_level() == 0) | 985 | if (get_backlight_level() == 0) |
999 | { | 986 | breathing_min(); |
1000 | breathing_index = 0; | ||
1001 | } | ||
1002 | else | 987 | else |
1003 | { | 988 | breathing_max(); |
1004 | // Set breathing_index to be at the midpoint + 1 (brightest point) | ||
1005 | breathing_index = 0x21 << breath_speed; | ||
1006 | } | ||
1007 | |||
1008 | breathing_halt = BREATHING_HALT_ON; | 989 | breathing_halt = BREATHING_HALT_ON; |
1009 | 990 | breathing_interrupt_enable(); | |
1010 | // Enable breathing interrupt | ||
1011 | TIMSK1 |= _BV(OCIE1A); | ||
1012 | } | 991 | } |
1013 | 992 | ||
1014 | void breathing_disable(void) | 993 | void breathing_disable(void) |
1015 | { | 994 | { |
1016 | // Disable breathing interrupt | 995 | breathing_interrupt_disable(); |
1017 | TIMSK1 &= ~_BV(OCIE1A); | 996 | // Restore backlight level |
1018 | backlight_set(get_backlight_level()); | 997 | backlight_set(get_backlight_level()); |
1019 | } | 998 | } |
1020 | 999 | ||
1021 | void breathing_self_disable(void) | 1000 | void breathing_self_disable(void) |
1022 | { | 1001 | { |
1023 | if (get_backlight_level() == 0) | 1002 | if (get_backlight_level() == 0) |
1024 | { | 1003 | breathing_halt = BREATHING_HALT_OFF; |
1025 | breathing_halt = BREATHING_HALT_OFF; | 1004 | else |
1026 | } | 1005 | breathing_halt = BREATHING_HALT_ON; |
1027 | else | ||
1028 | { | ||
1029 | breathing_halt = BREATHING_HALT_ON; | ||
1030 | } | ||
1031 | |||
1032 | //backlight_set(get_backlight_level()); | ||
1033 | } | 1006 | } |
1034 | 1007 | ||
1035 | void breathing_toggle(void) | 1008 | void breathing_toggle(void) { |
1036 | { | 1009 | if (is_breathing()) |
1037 | if (!is_breathing()) | 1010 | breathing_disable(); |
1038 | { | 1011 | else |
1039 | if (get_backlight_level() == 0) | 1012 | breathing_enable(); |
1040 | { | ||
1041 | breathing_index = 0; | ||
1042 | } | ||
1043 | else | ||
1044 | { | ||
1045 | // Set breathing_index to be at the midpoint + 1 (brightest point) | ||
1046 | breathing_index = 0x21 << breath_speed; | ||
1047 | } | ||
1048 | |||
1049 | breathing_halt = BREATHING_NO_HALT; | ||
1050 | } | ||
1051 | |||
1052 | // Toggle breathing interrupt | ||
1053 | TIMSK1 ^= _BV(OCIE1A); | ||
1054 | |||
1055 | // Restore backlight level | ||
1056 | if (!is_breathing()) | ||
1057 | { | ||
1058 | backlight_set(get_backlight_level()); | ||
1059 | } | ||
1060 | } | 1013 | } |
1061 | 1014 | ||
1062 | bool is_breathing(void) | 1015 | void breathing_period_set(uint8_t value) |
1063 | { | 1016 | { |
1064 | return (TIMSK1 && _BV(OCIE1A)); | 1017 | if (!value) |
1018 | value = 1; | ||
1019 | breathing_period = value; | ||
1065 | } | 1020 | } |
1066 | 1021 | ||
1067 | void breathing_intensity_default(void) | 1022 | void breathing_period_default(void) { |
1068 | { | 1023 | breathing_period_set(BREATHING_PERIOD); |
1069 | //breath_intensity = (uint8_t)((uint16_t)100 * (uint16_t)get_backlight_level() / (uint16_t)BACKLIGHT_LEVELS); | ||
1070 | breath_intensity = ((BACKLIGHT_LEVELS - get_backlight_level()) * ((BACKLIGHT_LEVELS + 1) / 2)); | ||
1071 | } | 1024 | } |
1072 | 1025 | ||
1073 | void breathing_intensity_set(uint8_t value) | 1026 | void breathing_period_inc(void) |
1074 | { | 1027 | { |
1075 | breath_intensity = value; | 1028 | breathing_period_set(breathing_period+1); |
1076 | } | 1029 | } |
1077 | 1030 | ||
1078 | void breathing_speed_default(void) | 1031 | void breathing_period_dec(void) |
1079 | { | 1032 | { |
1080 | breath_speed = 4; | 1033 | breathing_period_set(breathing_period-1); |
1081 | } | 1034 | } |
1082 | 1035 | ||
1083 | void breathing_speed_set(uint8_t value) | 1036 | /* To generate breathing curve in python: |
1084 | { | 1037 | * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)] |
1085 | bool is_breathing_now = is_breathing(); | 1038 | */ |
1086 | uint8_t old_breath_speed = breath_speed; | 1039 | static const uint8_t breathing_table[BREATHING_STEPS] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
1087 | |||
1088 | if (is_breathing_now) | ||
1089 | { | ||
1090 | // Disable breathing interrupt | ||
1091 | TIMSK1 &= ~_BV(OCIE1A); | ||
1092 | } | ||
1093 | |||
1094 | breath_speed = value; | ||
1095 | |||
1096 | if (is_breathing_now) | ||
1097 | { | ||
1098 | // Adjust index to account for new speed | ||
1099 | breathing_index = (( (uint8_t)( (breathing_index) >> old_breath_speed ) ) & 0x3F) << breath_speed; | ||
1100 | |||
1101 | // Enable breathing interrupt | ||
1102 | TIMSK1 |= _BV(OCIE1A); | ||
1103 | } | ||
1104 | |||
1105 | } | ||
1106 | 1040 | ||
1107 | void breathing_speed_inc(uint8_t value) | 1041 | // Use this before the cie_lightness function. |
1108 | { | 1042 | static inline uint16_t scale_backlight(uint16_t v) { |
1109 | if ((uint16_t)(breath_speed - value) > 10 ) | 1043 | return v / BACKLIGHT_LEVELS * get_backlight_level(); |
1110 | { | ||
1111 | breathing_speed_set(0); | ||
1112 | } | ||
1113 | else | ||
1114 | { | ||
1115 | breathing_speed_set(breath_speed - value); | ||
1116 | } | ||
1117 | } | 1044 | } |
1118 | 1045 | ||
1119 | void breathing_speed_dec(uint8_t value) | 1046 | /* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run |
1047 | * about 244 times per second. | ||
1048 | */ | ||
1049 | ISR(TIMER1_OVF_vect) | ||
1120 | { | 1050 | { |
1121 | if ((uint16_t)(breath_speed + value) > 10 ) | 1051 | uint16_t interval = (uint16_t) breathing_period * 244 / BREATHING_STEPS; |
1122 | { | 1052 | // resetting after one period to prevent ugly reset at overflow. |
1123 | breathing_speed_set(10); | 1053 | breathing_counter = (breathing_counter + 1) % (breathing_period * 244); |
1124 | } | 1054 | uint8_t index = breathing_counter / interval % BREATHING_STEPS; |
1125 | else | 1055 | |
1126 | { | 1056 | if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) || |
1127 | breathing_speed_set(breath_speed + value); | 1057 | ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1))) |
1128 | } | 1058 | { |
1129 | } | 1059 | breathing_interrupt_disable(); |
1060 | } | ||
1130 | 1061 | ||
1131 | void breathing_defaults(void) | 1062 | set_pwm(cie_lightness(scale_backlight((uint16_t) pgm_read_byte(&breathing_table[index]) * 0x0101U))); |
1132 | { | ||
1133 | breathing_intensity_default(); | ||
1134 | breathing_speed_default(); | ||
1135 | breathing_halt = BREATHING_NO_HALT; | ||
1136 | } | 1063 | } |
1137 | 1064 | ||
1138 | /* Breathing Sleep LED brighness(PWM On period) table | 1065 | #endif // BACKLIGHT_BREATHING |
1139 | * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle | ||
1140 | * | ||
1141 | * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 | ||
1142 | * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } | ||
1143 | */ | ||
1144 | static const uint8_t breathing_table[64] PROGMEM = { | ||
1145 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, | ||
1146 | 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, | ||
1147 | 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, | ||
1148 | 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
1149 | }; | ||
1150 | 1066 | ||
1151 | ISR(TIMER1_COMPA_vect) | 1067 | __attribute__ ((weak)) |
1068 | void backlight_init_ports(void) | ||
1152 | { | 1069 | { |
1153 | // OCR1x = (pgm_read_byte(&breathing_table[ ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F ] )) * breath_intensity; | 1070 | // Setup backlight pin as output and output to on state. |
1154 | 1071 | // DDRx |= n | |
1155 | 1072 | _SFR_IO8((backlight_pin >> 4) + 1) |= _BV(backlight_pin & 0xF); | |
1156 | uint8_t local_index = ( (uint8_t)( (breathing_index++) >> breath_speed ) ) & 0x3F; | 1073 | #if BACKLIGHT_ON_STATE == 0 |
1157 | 1074 | // PORTx &= ~n | |
1158 | if (((breathing_halt == BREATHING_HALT_ON) && (local_index == 0x20)) || ((breathing_halt == BREATHING_HALT_OFF) && (local_index == 0x3F))) | 1075 | _SFR_IO8((backlight_pin >> 4) + 2) &= ~_BV(backlight_pin & 0xF); |
1159 | { | 1076 | #else |
1160 | // Disable breathing interrupt | 1077 | // PORTx |= n |
1161 | TIMSK1 &= ~_BV(OCIE1A); | 1078 | _SFR_IO8((backlight_pin >> 4) + 2) |= _BV(backlight_pin & 0xF); |
1162 | } | 1079 | #endif |
1163 | 1080 | // I could write a wall of text here to explain... but TL;DW | |
1164 | OCR1x = (uint16_t)(((uint16_t)pgm_read_byte(&breathing_table[local_index]) * 257)) >> breath_intensity; | 1081 | // Go read the ATmega32u4 datasheet. |
1082 | // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on | ||
1083 | |||
1084 | // Pin PB7 = OCR1C (Timer 1, Channel C) | ||
1085 | // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 | ||
1086 | // (i.e. start high, go low when counter matches.) | ||
1087 | // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 | ||
1088 | // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 | ||
1089 | |||
1090 | /* | ||
1091 | 14.8.3: | ||
1092 | "In fast PWM mode, the compare units allow generation of PWM waveforms on the OCnx pins. Setting the COMnx1:0 bits to two will produce a non-inverted PWM [..]." | ||
1093 | "In fast PWM mode the counter is incremented until the counter value matches either one of the fixed values 0x00FF, 0x01FF, or 0x03FF (WGMn3:0 = 5, 6, or 7), the value in ICRn (WGMn3:0 = 14), or the value in OCRnA (WGMn3:0 = 15)." | ||
1094 | */ | ||
1095 | |||
1096 | TCCR1A = _BV(COM1x1) | _BV(WGM11); // = 0b00001010; | ||
1097 | TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; | ||
1098 | // Use full 16-bit resolution. Counter counts to ICR1 before reset to 0. | ||
1099 | ICR1 = TIMER_TOP; | ||
1165 | 1100 | ||
1101 | backlight_init(); | ||
1102 | #ifdef BACKLIGHT_BREATHING | ||
1103 | breathing_enable(); | ||
1104 | #endif | ||
1166 | } | 1105 | } |
1167 | 1106 | ||
1168 | #endif // NO_BACKLIGHT_CLOCK | 1107 | #endif // NO_HARDWARE_PWM |
1169 | #endif // breathing | ||
1170 | 1108 | ||
1171 | #else // backlight | 1109 | #else // backlight |
1172 | 1110 | ||
1173 | __attribute__ ((weak)) | 1111 | __attribute__ ((weak)) |
1174 | void backlight_init_ports(void) | 1112 | void backlight_init_ports(void) {} |
1175 | { | ||
1176 | |||
1177 | } | ||
1178 | 1113 | ||
1179 | __attribute__ ((weak)) | 1114 | __attribute__ ((weak)) |
1180 | void backlight_set(uint8_t level) | 1115 | void backlight_set(uint8_t level) {} |
1181 | { | ||
1182 | |||
1183 | } | ||
1184 | 1116 | ||
1185 | #endif // backlight | 1117 | #endif // backlight |
1186 | 1118 | ||
diff --git a/quantum/quantum.h b/quantum/quantum.h index 056d37292..6ca5ecb5c 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h | |||
@@ -173,12 +173,11 @@ void breathing_self_disable(void); | |||
173 | void breathing_toggle(void); | 173 | void breathing_toggle(void); |
174 | bool is_breathing(void); | 174 | bool is_breathing(void); |
175 | 175 | ||
176 | void breathing_defaults(void); | ||
177 | void breathing_intensity_default(void); | 176 | void breathing_intensity_default(void); |
178 | void breathing_speed_default(void); | 177 | void breathing_period_default(void); |
179 | void breathing_speed_set(uint8_t value); | 178 | void breathing_period_set(uint8_t value); |
180 | void breathing_speed_inc(uint8_t value); | 179 | void breathing_period_inc(void); |
181 | void breathing_speed_dec(uint8_t value); | 180 | void breathing_period_dec(void); |
182 | #endif | 181 | #endif |
183 | 182 | ||
184 | #endif | 183 | #endif |
diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 65bf9e141..1b9a7534c 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h | |||
@@ -380,26 +380,13 @@ enum quantum_keycodes { | |||
380 | #endif // MIDI_ADVANCED | 380 | #endif // MIDI_ADVANCED |
381 | 381 | ||
382 | // Backlight functionality | 382 | // Backlight functionality |
383 | BL_0, | 383 | BL_ON, |
384 | BL_1, | 384 | BL_OFF, |
385 | BL_2, | ||
386 | BL_3, | ||
387 | BL_4, | ||
388 | BL_5, | ||
389 | BL_6, | ||
390 | BL_7, | ||
391 | BL_8, | ||
392 | BL_9, | ||
393 | BL_10, | ||
394 | BL_11, | ||
395 | BL_12, | ||
396 | BL_13, | ||
397 | BL_14, | ||
398 | BL_15, | ||
399 | BL_DEC, | 385 | BL_DEC, |
400 | BL_INC, | 386 | BL_INC, |
401 | BL_TOGG, | 387 | BL_TOGG, |
402 | BL_STEP, | 388 | BL_STEP, |
389 | BL_BRTG, | ||
403 | 390 | ||
404 | // RGB functionality | 391 | // RGB functionality |
405 | RGB_TOG, | 392 | RGB_TOG, |
@@ -579,9 +566,6 @@ enum quantum_keycodes { | |||
579 | #define AG_SWAP MAGIC_SWAP_ALT_GUI | 566 | #define AG_SWAP MAGIC_SWAP_ALT_GUI |
580 | #define AG_NORM MAGIC_UNSWAP_ALT_GUI | 567 | #define AG_NORM MAGIC_UNSWAP_ALT_GUI |
581 | 568 | ||
582 | #define BL_ON BL_9 | ||
583 | #define BL_OFF BL_0 | ||
584 | |||
585 | // GOTO layer - 16 layers max | 569 | // GOTO layer - 16 layers max |
586 | // when: | 570 | // when: |
587 | // ON_PRESS = 1 | 571 | // ON_PRESS = 1 |
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c index b39aa4cbc..dd3a5b3ee 100644 --- a/tmk_core/common/action.c +++ b/tmk_core/common/action.c | |||
@@ -512,8 +512,11 @@ void process_action(keyrecord_t *record, action_t action) | |||
512 | case BACKLIGHT_STEP: | 512 | case BACKLIGHT_STEP: |
513 | backlight_step(); | 513 | backlight_step(); |
514 | break; | 514 | break; |
515 | case BACKLIGHT_LEVEL: | 515 | case BACKLIGHT_ON: |
516 | backlight_level(action.backlight.level); | 516 | backlight_level(BACKLIGHT_LEVELS); |
517 | break; | ||
518 | case BACKLIGHT_OFF: | ||
519 | backlight_level(0); | ||
517 | break; | 520 | break; |
518 | } | 521 | } |
519 | } | 522 | } |
diff --git a/tmk_core/common/action_code.h b/tmk_core/common/action_code.h index b15aaa0eb..05bc84573 100644 --- a/tmk_core/common/action_code.h +++ b/tmk_core/common/action_code.h | |||
@@ -304,7 +304,8 @@ enum backlight_opt { | |||
304 | BACKLIGHT_DECREASE = 1, | 304 | BACKLIGHT_DECREASE = 1, |
305 | BACKLIGHT_TOGGLE = 2, | 305 | BACKLIGHT_TOGGLE = 2, |
306 | BACKLIGHT_STEP = 3, | 306 | BACKLIGHT_STEP = 3, |
307 | BACKLIGHT_LEVEL = 4, | 307 | BACKLIGHT_ON = 4, |
308 | BACKLIGHT_OFF = 5, | ||
308 | }; | 309 | }; |
309 | 310 | ||
310 | /* Macro */ | 311 | /* Macro */ |
@@ -316,7 +317,8 @@ enum backlight_opt { | |||
316 | #define ACTION_BACKLIGHT_DECREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_DECREASE << 8) | 317 | #define ACTION_BACKLIGHT_DECREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_DECREASE << 8) |
317 | #define ACTION_BACKLIGHT_TOGGLE() ACTION(ACT_BACKLIGHT, BACKLIGHT_TOGGLE << 8) | 318 | #define ACTION_BACKLIGHT_TOGGLE() ACTION(ACT_BACKLIGHT, BACKLIGHT_TOGGLE << 8) |
318 | #define ACTION_BACKLIGHT_STEP() ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP << 8) | 319 | #define ACTION_BACKLIGHT_STEP() ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP << 8) |
319 | #define ACTION_BACKLIGHT_LEVEL(level) ACTION(ACT_BACKLIGHT, BACKLIGHT_LEVEL << 8 | (level)) | 320 | #define ACTION_BACKLIGHT_ON() ACTION(ACT_BACKLIGHT, BACKLIGHT_ON << 8) |
321 | #define ACTION_BACKLIGHT_OFF() ACTION(ACT_BACKLIGHT, BACKLIGHT_OFF << 8) | ||
320 | /* Command */ | 322 | /* Command */ |
321 | #define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (id)) | 323 | #define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (id)) |
322 | /* Function */ | 324 | /* Function */ |
diff --git a/tmk_core/common/backlight.c b/tmk_core/common/backlight.c index d03bfe931..4d2491b98 100644 --- a/tmk_core/common/backlight.c +++ b/tmk_core/common/backlight.c | |||
@@ -61,6 +61,8 @@ void backlight_decrease(void) | |||
61 | void backlight_toggle(void) | 61 | void backlight_toggle(void) |
62 | { | 62 | { |
63 | backlight_config.enable ^= 1; | 63 | backlight_config.enable ^= 1; |
64 | if (backlight_config.raw == 1) // enabled but level = 0 | ||
65 | backlight_config.level = 1; | ||
64 | eeconfig_update_backlight(backlight_config.raw); | 66 | eeconfig_update_backlight(backlight_config.raw); |
65 | dprintf("backlight toggle: %u\n", backlight_config.enable); | 67 | dprintf("backlight toggle: %u\n", backlight_config.enable); |
66 | backlight_set(backlight_config.enable ? backlight_config.level : 0); | 68 | backlight_set(backlight_config.enable ? backlight_config.level : 0); |
@@ -81,7 +83,9 @@ void backlight_step(void) | |||
81 | 83 | ||
82 | void backlight_level(uint8_t level) | 84 | void backlight_level(uint8_t level) |
83 | { | 85 | { |
84 | backlight_config.level ^= level; | 86 | if (level > BACKLIGHT_LEVELS) |
87 | level = BACKLIGHT_LEVELS; | ||
88 | backlight_config.level = level; | ||
85 | backlight_config.enable = !!backlight_config.level; | 89 | backlight_config.enable = !!backlight_config.level; |
86 | eeconfig_update_backlight(backlight_config.raw); | 90 | eeconfig_update_backlight(backlight_config.raw); |
87 | backlight_set(backlight_config.level); | 91 | backlight_set(backlight_config.level); |