~ruther/qmk_firmware

17f36a21bfc340e4715c5849e4d0c537820e7cbe — Ryan 1 year, 9 months ago 2acb426
Rework RGBLight driver system (#22529)

M builddefs/common_features.mk => builddefs/common_features.mk +1 -0
@@ 313,6 313,7 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
        OPT_DEFS += -DRGBLIGHT_$(strip $(shell echo $(RGBLIGHT_DRIVER) | tr '[:lower:]' '[:upper:]'))
        SRC += $(QUANTUM_DIR)/color.c
        SRC += $(QUANTUM_DIR)/rgblight/rgblight.c
        SRC += $(QUANTUM_DIR)/rgblight/rgblight_drivers.c
        CIE1931_CURVE := yes
        RGB_KEYCODES_ENABLE := yes
    endif

M drivers/led/apa102.c => drivers/led/apa102.c +0 -5
@@ 71,11 71,6 @@ void apa102_setleds(rgb_led_t *start_led, uint16_t num_leds) {
    apa102_end_frame(num_leds);
}

// Overwrite the default rgblight_call_driver to use apa102 driver
void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds) {
    apa102_setleds(start_led, num_leds);
}

void static apa102_init(void) {
    setPinOutput(APA102_DI_PIN);
    setPinOutput(APA102_CI_PIN);

M keyboards/dp60/keymaps/indicator/indicator.c => keyboards/dp60/keymaps/indicator/indicator.c +7 -5
@@ 14,10 14,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "dp60.h"

#include "rgblight.h"

#include QMK_KEYBOARD_H
#include "ws2812.h"

// caps led
const rgblight_segment_t PROGMEM dp60_capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS(


@@ 72,13 70,17 @@ extern rgblight_config_t rgblight_config;
extern void              rgblight_layers_write(void);
extern void              indicator_write(rgb_led_t *start_led, uint8_t num_leds);

void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
{
    ws2812_setleds(start_led, RGBLED_NUM-RGB_INDICATOR_NUM);

    indicator_write(start_led + (RGBLED_NUM - RGB_INDICATOR_NUM), RGB_INDICATOR_NUM);
}

const rgblight_driver_t rgblight_driver = {
    .setleds = setleds_custom,
};

void led_update_ports(led_t led_state) {
    rgblight_set_layer_state(0, led_state.caps_lock);
    rgblight_set_layer_state(1, led_state.scroll_lock);

M keyboards/dp60/keymaps/indicator/rules.mk => keyboards/dp60/keymaps/indicator/rules.mk +2 -0
@@ 1,4 1,6 @@

RGBLIGHT_ENABLE = yes       	# Use RGB underglow light
RGBLIGHT_DRIVER = custom
WS2812_DRIVER_REQUIRED = yes

SRC += indicator.c led_driver.c

M keyboards/ergodox_ez/led_i2c.c => keyboards/ergodox_ez/led_i2c.c +5 -1
@@ 21,8 21,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
#ifdef RGBLIGHT_ENABLE

#    include "ergodox_ez.h"
#    include "ws2812.h"

void rgblight_call_driver(rgb_led_t *led, uint8_t led_num) {
void setleds_custom(rgb_led_t *led, uint16_t led_num) {
    i2c_init();
    i2c_start(0x84, ERGODOX_EZ_I2C_TIMEOUT);
    int i = 0;


@@ 51,5 52,8 @@ void rgblight_call_driver(rgb_led_t *led, uint8_t led_num) {
    ws2812_setleds(led, led_num);
}

const rgblight_driver_t rgblight_driver = {
    .setleds = setleds_custom,
};

#endif  // RGBLIGHT_ENABLE

M keyboards/ergodox_ez/shine/info.json => keyboards/ergodox_ez/shine/info.json +3 -0
@@ 2,5 2,8 @@
    "keyboard_name": "ErgoDox EZ Shine",
    "usb": {
        "pid": "0x4975"
    },
    "rgblight": {
        "driver": "custom"
    }
}

M keyboards/ergodox_ez/shine/rules.mk => keyboards/ergodox_ez/shine/rules.mk +1 -0
@@ 1,1 1,2 @@
RGBLIGHT_ENABLE = yes
WS2812_DRIVER_REQUIRED = yes

M keyboards/matrix/abelx/abelx.c => keyboards/matrix/abelx/abelx.c +6 -1
@@ 57,6 57,7 @@ void housekeeping_task_kb(void) {

#ifdef RGBLIGHT_ENABLE
#include "rgblight.h"
#include "ws2812.h"
#include "i2c_master.h"

const aw9523b_led g_aw9523b_leds[AW9523B_RGB_NUM] = {


@@ 66,7 67,7 @@ const aw9523b_led g_aw9523b_leds[AW9523B_RGB_NUM] = {
    {AW9523B_P07_PWM, AW9523B_P06_PWM, AW9523B_P05_PWM},
};

void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
{
    uint8_t num = num_leds < AW9523B_RGB_NUM ? num_leds : AW9523B_RGB_NUM;



@@ 77,6 78,10 @@ void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
    }
}

const rgblight_driver_t rgblight_driver = {
    .setleds = setleds_custom,
};

#endif

static uint16_t caps_lock_pin = DEF_PIN(TCA6424_PORT2, 3);

M keyboards/matrix/abelx/info.json => keyboards/matrix/abelx/info.json +1 -0
@@ 10,6 10,7 @@
  },
  "rgblight": {
    "led_count": 9,
    "driver": "custom",
    "animations": {
      "breathing": true,
      "rainbow_mood": true,

M keyboards/matrix/abelx/rules.mk => keyboards/matrix/abelx/rules.mk +1 -0
@@ 46,3 46,4 @@ CUSTOM_MATRIX = lite
# project specific files
SRC += matrix.c tca6424.c aw9523b.c
I2C_DRIVER_REQUIRED = yes
WS2812_DRIVER_REQUIRED = yes

M keyboards/matrix/m20add/info.json => keyboards/matrix/m20add/info.json +1 -0
@@ 10,6 10,7 @@
  },
  "rgblight": {
    "led_count": 20,
    "driver": "custom",
    "animations": {
      "breathing": true,
      "rainbow_mood": true,

M keyboards/matrix/m20add/rgb_ring.c => keyboards/matrix/m20add/rgb_ring.c +5 -1
@@ 357,7 357,7 @@ static void custom_effects(void)
    effect_funcs[rgb_ring.effect]();
}

void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
{
    if (rgb_ring.state != RING_STATE_QMK) {
        return;


@@ 368,6 368,10 @@ void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
    }
}

const rgblight_driver_t rgblight_driver = {
    .setleds = setleds_custom,
};


void rgb_ring_init(void)
{

M keyboards/matrix/noah/noah.c => keyboards/matrix/noah/noah.c +12 -15
@@ 22,45 22,42 @@ extern rgblight_config_t rgblight_config;
#endif
rgb_led_t noah_leds[RGBLED_NUM];
static bool noah_led_mode = false;
void rgblight_set(void) {
void setleds_custom(rgb_led_t *ledarray, uint16_t num_leds) {
    memset(&noah_leds[0], 0, sizeof(noah_leds));
    if (!rgblight_config.enable) {
        for (uint8_t i = 0; i < RGBLED_NUM; i++) {
            led[i].r = 0;
            led[i].g = 0;
            led[i].b = 0;
            ledarray[i].r = 0;
            ledarray[i].g = 0;
            ledarray[i].b = 0;
        }
    }
    if (noah_led_mode) {
      led_t led_state = host_keyboard_led_state();
      if (led_state.caps_lock) {
        noah_leds[0] = led[0];
        noah_leds[0] = ledarray[0];
      }
      if (led_state.scroll_lock) {
        noah_leds[1] = led[1];
        noah_leds[1] = ledarray[1];
      }
      if (led_state.num_lock) {
        noah_leds[2] = led[2];
        noah_leds[2] = ledarray[2];
      }
      for (int32_t i = 0; i < 4; i++) {
        if(layer_state_is(i+1)) {
          noah_leds[i + 3] = led[i + 3];
          noah_leds[i + 3] = ledarray[i + 3];
        }
      }
    } else {
      memcpy(&noah_leds[0], &led[0], sizeof(noah_leds));
      memcpy(&noah_leds[0], &ledarray[0], sizeof(noah_leds));
    }

  ws2812_setleds(noah_leds, RGBLED_NUM);
}
#endif

void matrix_scan_kb(void) {
#ifdef RGBLIGHT_ENABLE
    rgblight_task();
const rgblight_driver_t rgblight_driver = {
    .setleds = setleds_custom,
};
#endif
    matrix_scan_user();
}

#ifdef RGB_MATRIX_ENABLE
const is31fl3731_led_t PROGMEM g_is31fl3731_leds[RGB_MATRIX_LED_COUNT] = {

M keyboards/neson_design/700e/700e.c => keyboards/neson_design/700e/700e.c +6 -1
@@ 20,6 20,7 @@
#include "quantum.h"
#include "i2c_master.h"
#include "drivers/led/issi/is31fl3731.h"
#include "ws2812.h"

enum {
    SELF_TESTING,


@@ 336,7 337,7 @@ void housekeeping_task_kb(void)
    housekeeping_task_user();
}

void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
{
    if (rgb_state.state != NORMAL) return;



@@ 353,6 354,10 @@ void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
    ws2812_setleds(leds, 4);
}

const rgblight_driver_t rgblight_driver = {
    .setleds = setleds_custom,
};

bool led_update_kb(led_t led_state)
{
    bool res = led_update_user(led_state);

M keyboards/neson_design/700e/info.json => keyboards/neson_design/700e/info.json +1 -0
@@ 20,6 20,7 @@
        "saturation_steps": 8,
        "brightness_steps": 8,
        "led_count": 68,
        "driver": "custom",
        "animations": {
            "breathing": true,
            "rainbow_mood": true,

M keyboards/neson_design/700e/rules.mk => keyboards/neson_design/700e/rules.mk +1 -0
@@ 12,4 12,5 @@ RGBLIGHT_ENABLE = yes		# Enable keyboard RGB underglow
NO_USB_STARTUP_CHECK = yes

QUANTUM_LIB_SRC += drivers/led/issi/is31fl3731.c
WS2812_DRIVER_REQUIRED = yes
I2C_DRIVER_REQUIRED = yes

M keyboards/neson_design/n6/info.json => keyboards/neson_design/n6/info.json +1 -0
@@ 23,6 23,7 @@
        "saturation_steps": 8,
        "brightness_steps": 8,
        "led_count": 65,
        "driver": "custom",
        "max_brightness": 192,
        "animations": {
            "breathing": true,

M keyboards/neson_design/n6/n6.c => keyboards/neson_design/n6/n6.c +6 -1
@@ 20,6 20,7 @@
#include "quantum.h"
#include "i2c_master.h"
#include "drivers/led/issi/is31fl3731.h"
#include "ws2812.h"

enum {
    SELF_TESTING,


@@ 338,7 339,7 @@ void housekeeping_task_kb(void)
    housekeeping_task_user();
}

void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
{
    if (rgb_state.state != NORMAL) return;



@@ 348,6 349,10 @@ void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
    ws2812_setleds(start_led+IS31FL3731_LED_COUNT, 1);
}

const rgblight_driver_t rgblight_driver = {
    .setleds = setleds_custom,
};

bool led_update_kb(led_t led_state)
{
    bool res = led_update_user(led_state);

M keyboards/neson_design/n6/rules.mk => keyboards/neson_design/n6/rules.mk +1 -0
@@ 11,4 11,5 @@ BACKLIGHT_ENABLE = no       # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = yes		# Enable keyboard RGB underglow

QUANTUM_LIB_SRC += drivers/led/issi/is31fl3731.c
WS2812_DRIVER_REQUIRED = yes
I2C_DRIVER_REQUIRED = yes

M keyboards/neson_design/nico/info.json => keyboards/neson_design/nico/info.json +2 -1
@@ 25,7 25,8 @@
        "pin": "B0"
    },
    "rgblight": {
        "led_count": 5
        "led_count": 5,
        "driver": "custom"
    },
    "url": "",
    "usb": {

M keyboards/neson_design/nico/nico.c => keyboards/neson_design/nico/nico.c +5 -1
@@ 18,6 18,7 @@
 */

#include "quantum.h"
#include "ws2812.h"
#ifdef RGBLIGHT_ENABLE

static bool alert = false;


@@ 66,7 67,7 @@ void housekeeping_task_kb(void)
    housekeeping_task_user();
}

void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
void setleds_custom(rgb_led_t *start_led, uint16_t num_leds)
{
    start_led[2].r = start_led[0].r;
    start_led[2].g = start_led[0].g;


@@ 82,4 83,7 @@ void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds)
    ws2812_setleds(start_led, RGBLED_NUM);
}

const rgblight_driver_t rgblight_driver = {
    .setleds = setleds_custom,
};
#endif
\ No newline at end of file

M keyboards/neson_design/nico/rules.mk => keyboards/neson_design/nico/rules.mk +1 -1
@@ 1,1 1,1 @@
# This file intentionally left blank
WS2812_DRIVER_REQUIRED = yes

M keyboards/v60_type_r/info.json => keyboards/v60_type_r/info.json +0 -16
@@ 18,22 18,6 @@
    "pin": "F7",
    "on_state": 0
  },
  "rgblight": {
    "driver": "custom",
    "led_count": 1,
    "animations": {
      "breathing": true,
      "rainbow_mood": true,
      "rainbow_swirl": true,
      "snake": true,
      "knight": true,
      "christmas": true,
      "static_gradient": true,
      "rgb_test": true,
      "alternating": true,
      "twinkle": true
    }
  },
  "processor": "atmega32u4",
  "bootloader": "atmel-dfu",
  "community_layouts": ["60_ansi", "60_iso"],

M keyboards/v60_type_r/rules.mk => keyboards/v60_type_r/rules.mk +1 -1
@@ 8,7 8,7 @@ CONSOLE_ENABLE = no         # Console for debug
COMMAND_ENABLE = yes        # Commands for debug and configuration
NKRO_ENABLE = no            # Enable N-Key Rollover
BACKLIGHT_ENABLE = yes      # Enable keyboard backlight functionality
RGBLIGHT_ENABLE = yes       # Enable the RGB Underglow
RGBLIGHT_ENABLE = no        # Enable the RGB Underglow
AUDIO_ENABLE = no           # Audio output

LTO_ENABLE = yes

M keyboards/v60_type_r/v60_type_r.c => keyboards/v60_type_r/v60_type_r.c +0 -14
@@ 131,20 131,6 @@ void set_rgb_pin_off(uint8_t pin) {
	PORTF |= _BV(pin);
}

void rgblight_set(void) {
	  // xprintf("Setting RGB underglow\n");
    if (!rgblight_config.enable) {
          led[0].r = 0;
          led[0].g = 0;
          led[0].b = 0;
          set_rgb_pin_off(RGB_RED_PIN);
          set_rgb_pin_off(RGB_GREEN_PIN);
          set_rgb_pin_off(RGB_BLUE_PIN);
    }

   //  //xprintf("Red: %u, Green: %u, Blue: %u\n", led[0].r, led[0].g, led[0].b);
}

ISR(TIMER3_COMPA_vect)
{
    static uint8_t pwm = 0;

M keyboards/work_louder/loop/info.json => keyboards/work_louder/loop/info.json +1 -0
@@ 30,6 30,7 @@
        "pin": "F1"
    },
    "rgblight": {
        "driver": "custom",
        "max_brightness": 120,
        "sleep": true,
        "animations": {

M keyboards/work_louder/micro/info.json => keyboards/work_louder/micro/info.json +1 -0
@@ 21,6 21,7 @@
    },
    "processor": "atmega32u4",
    "rgblight": {
        "driver": "custom",
        "animations": {
            "alternating": false,
            "breathing": true,

M keyboards/work_louder/nano/info.json => keyboards/work_louder/nano/info.json +1 -0
@@ 27,6 27,7 @@
    },
    "rgblight": {
        "led_count": 6,
        "driver": "custom",
        "max_brightness": 120,
        "sleep": true,
        "animations": {

M keyboards/work_louder/numpad/info.json => keyboards/work_louder/numpad/info.json +1 -0
@@ 50,6 50,7 @@
        ]
    },
    "rgblight": {
        "driver": "custom",
        "animations": {
            "breathing": true,
            "knight": true,

M keyboards/work_louder/rgb_functions.c => keyboards/work_louder/rgb_functions.c +3 -3
@@ 24,9 24,9 @@

#include "ws2812_bitbang.c"

void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds) {
    ws2812_setleds(start_led, num_leds);
}
const rgblight_driver_t rgblight_driver = {
    .setleds = ws2812_setleds,
};
#endif

#ifdef RGB_MATRIX_ENABLE

M keyboards/work_louder/work_board/info.json => keyboards/work_louder/work_board/info.json +1 -0
@@ 25,6 25,7 @@
      "pin": "D1"
    },
    "rgblight": {
      "driver": "custom",
      "max_brightness": 120,
      "sleep": true,
      "animations": {

M quantum/rgblight/rgblight.c => quantum/rgblight/rgblight.c +13 -20
@@ 900,12 900,6 @@ void rgblight_wakeup(void) {

#endif

__attribute__((weak)) void rgblight_call_driver(rgb_led_t *start_led, uint8_t num_leds) {
    ws2812_setleds(start_led, num_leds);
}

#ifndef RGBLIGHT_CUSTOM

void rgblight_set(void) {
    rgb_led_t *start_led;
    uint8_t    num_leds = rgblight_ranges.clipping_num_leds;


@@ 915,42 909,41 @@ void rgblight_set(void) {
            led[i].r = 0;
            led[i].g = 0;
            led[i].b = 0;
#    ifdef RGBW
#ifdef RGBW
            led[i].w = 0;
#    endif
#endif
        }
    }

#    ifdef RGBLIGHT_LAYERS
#ifdef RGBLIGHT_LAYERS
    if (rgblight_layers != NULL
#        if !defined(RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF)
#    if !defined(RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF)
        && rgblight_config.enable
#        elif defined(RGBLIGHT_SLEEP)
#    elif defined(RGBLIGHT_SLEEP)
        && !is_suspended
#        endif
#    endif
    ) {
        rgblight_layers_write();
    }
#    endif
#endif

#    ifdef RGBLIGHT_LED_MAP
#ifdef RGBLIGHT_LED_MAP
    rgb_led_t led0[RGBLED_NUM];
    for (uint8_t i = 0; i < RGBLED_NUM; i++) {
        led0[i] = led[pgm_read_byte(&led_map[i])];
    }
    start_led = led0 + rgblight_ranges.clipping_start_pos;
#    else
#else
    start_led = led + rgblight_ranges.clipping_start_pos;
#    endif
#endif

#    ifdef RGBW
#ifdef RGBW
    for (uint8_t i = 0; i < num_leds; i++) {
        convert_rgb_to_rgbw(&start_led[i]);
    }
#    endif
    rgblight_call_driver(start_led, num_leds);
}
#endif
    rgblight_driver.setleds(start_led, num_leds);
}

#ifdef RGBLIGHT_SPLIT
/* for split keyboard master side */

M quantum/rgblight/rgblight.h => quantum/rgblight/rgblight.h +1 -0
@@ 160,6 160,7 @@ enum RGBLIGHT_EFFECT_MODE {

#include <stdint.h>
#include <stdbool.h>
#include "rgblight_drivers.h"
#include "progmem.h"
#include "eeconfig.h"
#include "ws2812.h"

A quantum/rgblight/rgblight_drivers.c => quantum/rgblight/rgblight_drivers.c +20 -0
@@ 0,0 1,20 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later

#include "rgblight_drivers.h"

#if defined(RGBLIGHT_WS2812)
#    include "ws2812.h"

const rgblight_driver_t rgblight_driver = {
    .setleds = ws2812_setleds,
};

#elif defined(RGBLIGHT_APA102)
#    include "apa102.h"

const rgblight_driver_t rgblight_driver = {
    .setleds = apa102_setleds,
};

#endif

A quantum/rgblight/rgblight_drivers.h => quantum/rgblight/rgblight_drivers.h +13 -0
@@ 0,0 1,13 @@
// Copyright 2023 QMK
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <stdint.h>
#include "color.h"

typedef struct {
    void (*setleds)(rgb_led_t *ledarray, uint16_t number_of_leds);
} rgblight_driver_t;

extern const rgblight_driver_t rgblight_driver;