Skip to content

Commit

Permalink
Add ability to blink lighting layer for a specified duration (#8760)
Browse files Browse the repository at this point in the history
* Implement momentarily blink of lighting layers

* Refactor spidey3 userspace to use rgb layer blink

* Remove un-necessary line from example in documentation

* Revert "Refactor spidey3 userspace to use rgb layer blink"

This reverts commit 831649b.

* Adds a missing bit of documentation about lighting layer blink

* Update docs/feature_rgblight.md per suggestions

Co-authored-by: James Young <[email protected]>

* Update docs/feature_rgblight.md per suggestions

Co-authored-by: James Young <[email protected]>

* Update docs/feature_rgblight.md per suggestions

Co-authored-by: James Young <[email protected]>

* cformat, as suggested

Co-authored-by: James Young <[email protected]>
  • Loading branch information
spidey3 and noroadsleft authored May 9, 2020
1 parent 94fc32f commit e0f5480
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 3 deletions.
4 changes: 3 additions & 1 deletion docs/config_options.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@ If you define these options you will enable the associated feature, which may in
* `#define RGBLIGHT_ANIMATIONS`
* run RGB animations
* `#define RGBLIGHT_LAYERS`
* Lets you define [lighting layers](feature_rgblight.md) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
* Lets you define [lighting layers](feature_rgblight.md?id=lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
* `#define RGBLIGHT_LAYER_BLINK`
* Adds ability to [blink](feature_rgblight.md?id=lighting-layer-blink) a lighting layer for a specified number of milliseconds (e.g. to acknowledge an action).
* `#define RGBLED_NUM 12`
* number of LEDs
* `#define RGBLIGHT_SPLIT`
Expand Down
43 changes: 41 additions & 2 deletions docs/feature_rgblight.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64};
By including `#define RGBLIGHT_LAYERS` in your `config.h` file you can enable lighting layers. These make
it easy to use your underglow LEDs as status indicators to show which keyboard layer is currently active, or the state of caps lock, all without disrupting any animations. [Here's a video](https://youtu.be/uLGE1epbmdY) showing an example of what you can do.
### Defining Lighting Layers :id=defining-lighting-layers
To define a layer, we modify `keymap.c` to list out LED ranges and the colors we want to overlay on them using an array of `rgblight_segment_t` using the `RGBLIGHT_LAYER_SEGMENTS` macro. We can define multiple layers and enable/disable them independently:
```c
Expand Down Expand Up @@ -211,8 +213,12 @@ void keyboard_post_init_user(void) {
rgblight_layers = my_rgb_layers;
}
```
Note: For split keyboards with two controllers, both sides need to be flashed when updating the contents of rgblight_layers.
Finally, we enable and disable the lighting layers whenever the state of the keyboard changes:
### Enabling and disabling lighting layers :id=enabling-lighting-layers
Everything above just configured the definition of each lighting layer.
We can now enable and disable the lighting layers whenever the state of the keyboard changes:
```c
layer_state_t layer_state_set_user(layer_state_t state) {
Expand All @@ -228,7 +234,40 @@ bool led_update_user(led_t led_state) {
}
```

Note: For split keyboards with two controllers, both sides need to be flashed when updating the contents of rgblight_layers.
### Lighting layer blink :id=lighting-layer-blink

By including `#define RGBLIGHT_LAYER_BLINK` in your `config.h` file you can turn a lighting
layer on for a specified duration. Once the specified number of milliseconds has elapsed
the layer will be turned off. This is useful, e.g., if you want to acknowledge some
action (e.g. toggling some setting):

```c
const rgblight_segment_t PROGMEM _yes_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_GREEN} );
const rgblight_segment_t PROGMEM _no_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_RED} );

const rgblight_segment_t* const PROGMEM _rgb_layers[] =
RGBLIGHT_LAYERS_LIST( _yes_layer, _no_layer );

void keyboard_post_init_user(void) {
rgblight_layers = _rgb_layers;
}

// Note we user post_process_record_user because we want the state
// after the flag has been flipped...
void post_process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case DEBUG:
rgblight_blink_layer(debug_enable ? 0 : 1, 500);
break;

case NK_TOGG:
case NK_ON:
case NK_OFF:
rgblight_blink_layer(keymap_config.nkro ? 0 : 1, 500);
break;
}
}
```
## Functions
Expand Down
29 changes: 29 additions & 0 deletions quantum/rgblight.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,31 @@ static void rgblight_layers_write(void) {
}
}
}

# ifdef RGBLIGHT_LAYER_BLINK
uint8_t _blinked_layer_mask = 0;
uint16_t _blink_duration = 0;
static uint16_t _blink_timer;

void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms) {
rgblight_set_layer_state(layer, true);
_blinked_layer_mask |= 1 << layer;
_blink_timer = timer_read();
_blink_duration = duration_ms;
}

void rgblight_unblink_layers(void) {
if (_blinked_layer_mask != 0 && timer_elapsed(_blink_timer) > _blink_duration) {
for (uint8_t layer = 0; layer < RGBLIGHT_MAX_LAYERS; layer++) {
if ((_blinked_layer_mask & 1 << layer) != 0) {
rgblight_set_layer_state(layer, false);
}
}
_blinked_layer_mask = 0;
}
}
# endif

#endif

__attribute__((weak)) void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { ws2812_setleds(start_led, num_leds); }
Expand Down Expand Up @@ -909,6 +934,10 @@ void rgblight_task(void) {
# endif
}
}

# ifdef RGBLIGHT_LAYER_BLINK
rgblight_unblink_layers();
# endif
}

#endif /* RGBLIGHT_USE_TIMER */
Expand Down
6 changes: 6 additions & 0 deletions quantum/rgblight.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ bool rgblight_get_layer_state(uint8_t layer);

// Point this to an array of rgblight_segment_t arrays in keyboard_post_init_user to use rgblight layers
extern const rgblight_segment_t *const *rgblight_layers;

# ifdef RGBLIGHT_LAYER_BLINK
# define RGBLIGHT_USE_TIMER
void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms);
# endif

# endif

extern LED_TYPE led[RGBLED_NUM];
Expand Down

0 comments on commit e0f5480

Please sign in to comment.