~ruther/qmk_firmware

6c7450dad7c3651e0aae7ebaeb6c3cf15bde5112 — Matthes W 4 years ago c14fa1e
Add function to allow repeated blinking of one layer (#12237)

* Implement function rgblight_blink_layer_repeat to allow repeated blinking of one layer at a time

* Update doc

* Rework rgblight blinking according to requested change

* optimize storage
3 files changed, 43 insertions(+), 12 deletions(-)

M docs/feature_rgblight.md
M quantum/rgblight.c
M quantum/rgblight.h
M docs/feature_rgblight.md => docs/feature_rgblight.md +12 -0
@@ 310,6 310,18 @@ void post_process_record_user(uint16_t keycode, keyrecord_t *record) {
}
```

You can also use `rgblight_blink_layer_repeat` to specify the amount of times the layer is supposed to blink. Using the layers from above,
```c
void post_process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case DEBUG:
            rgblight_blink_layer_repeat(debug_enable ? 0 : 1, 200, 3);
            break;
    }
}
```
would turn the layer 0 (or 1) on and off again three times when `DEBUG` is pressed.

### Overriding RGB Lighting on/off status

Normally lighting layers are not shown when RGB Lighting is disabled (e.g. with `RGB_TOG` keycode). If you would like lighting layers to work even when the RGB Lighting is otherwise off, add `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF` to your `config.h`.

M quantum/rgblight.c => quantum/rgblight.c +30 -12
@@ 722,23 722,41 @@ static void rgblight_layers_write(void) {
}

#    ifdef RGBLIGHT_LAYER_BLINK
rgblight_layer_mask_t _blinked_layer_mask = 0;
static uint16_t       _blink_timer;
rgblight_layer_mask_t _blinking_layer_mask = 0;
static uint16_t       _repeat_timer;
static uint8_t        _times_remaining;
static uint16_t       _dur;

void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms) {
    rgblight_blink_layer_repeat(layer, duration_ms, 1);
}

void rgblight_blink_layer_repeat(uint8_t layer, uint16_t duration_ms, uint8_t times) {
    _times_remaining = times * 2;
    _dur = duration_ms;

    rgblight_set_layer_state(layer, true);
    _blinked_layer_mask |= (rgblight_layer_mask_t)1 << layer;
    _blink_timer = sync_timer_read() + duration_ms;
    _times_remaining--;
    _blinking_layer_mask |= (rgblight_layer_mask_t)1 << layer;
    _repeat_timer = sync_timer_read() + duration_ms;
}

void rgblight_unblink_layers(void) {
    if (_blinked_layer_mask != 0 && timer_expired(sync_timer_read(), _blink_timer)) {
void rgblight_blink_layer_repeat_helper(void) {
    if (_blinking_layer_mask != 0 && timer_expired(sync_timer_read(), _repeat_timer)) {
        for (uint8_t layer = 0; layer < RGBLIGHT_MAX_LAYERS; layer++) {
            if ((_blinked_layer_mask & (rgblight_layer_mask_t)1 << layer) != 0) {
                rgblight_set_layer_state(layer, false);
            if ((_blinking_layer_mask & (rgblight_layer_mask_t)1 << layer) != 0 && _times_remaining > 0) {
                if (_times_remaining % 2 == 1) {
                    rgblight_set_layer_state(layer, false);
                } else {
                    rgblight_set_layer_state(layer, true);
                }
                _times_remaining--;
                _repeat_timer = sync_timer_read() + _dur;
            }
        }
        _blinked_layer_mask = 0;
        if (_times_remaining <= 0) {
            _blinking_layer_mask = 0;
        }
    }
}
#    endif


@@ 755,8 773,8 @@ void rgblight_suspend(void) {

#    ifdef RGBLIGHT_LAYER_BLINK
        // make sure any layer blinks don't come back after suspend
        rgblight_status.enabled_layer_mask &= ~_blinked_layer_mask;
        _blinked_layer_mask = 0;
        rgblight_status.enabled_layer_mask &= ~_blinking_layer_mask;
        _blinking_layer_mask = 0;
#    endif

        rgblight_disable_noeeprom();


@@ 1030,7 1048,7 @@ void rgblight_task(void) {
    }

#    ifdef RGBLIGHT_LAYER_BLINK
    rgblight_unblink_layers();
    rgblight_blink_layer_repeat_helper();
#    endif
}


M quantum/rgblight.h => quantum/rgblight.h +1 -0
@@ 222,6 222,7 @@ 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);
void rgblight_blink_layer_repeat(uint8_t layer, uint16_t duration_ms, uint8_t times);
#        endif

#    endif