diff --git a/docs/feature_rgblight.md b/docs/feature_rgblight.md index 8e8d6b81c3..292176548f 100644 --- a/docs/feature_rgblight.md +++ b/docs/feature_rgblight.md @@ -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`. diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 119d3eab21..e4c4d555e5 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -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_set_layer_state(layer, true); - _blinked_layer_mask |= (rgblight_layer_mask_t)1 << layer; - _blink_timer = sync_timer_read() + duration_ms; + rgblight_blink_layer_repeat(layer, duration_ms, 1); } -void rgblight_unblink_layers(void) { - if (_blinked_layer_mask != 0 && timer_expired(sync_timer_read(), _blink_timer)) { +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); + _times_remaining--; + _blinking_layer_mask |= (rgblight_layer_mask_t)1 << layer; + _repeat_timer = sync_timer_read() + duration_ms; +} + +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 } diff --git a/quantum/rgblight.h b/quantum/rgblight.h index 6fb3ab9380..bec2c66955 100644 --- a/quantum/rgblight.h +++ b/quantum/rgblight.h @@ -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