mirror of
https://github.com/qmk/qmk_firmware
synced 2024-11-18 09:55:48 +00:00
Add support for RGB LEDs wired directly to each half's controller (#5392)
* Add support for wiring RGB LEDs for both halves directly to their respective controllers RGB LEDs for each half don't need to be chained together across the TRRS cable with this * Add split RGB LED support for serial * Update config/rules for bakingpy layout * Un-nest ifdefs for hand detection * Read RGB config state from memory instead of EEPROM for serial updates * Reuse existing LED pointer instead of creating new one
This commit is contained in:
parent
23086808a7
commit
f077204fae
10 changed files with 76 additions and 38 deletions
|
@ -171,11 +171,15 @@ If you define these options you will enable the associated feature, which may in
|
||||||
## RGB Light Configuration
|
## RGB Light Configuration
|
||||||
|
|
||||||
* `#define RGB_DI_PIN D7`
|
* `#define RGB_DI_PIN D7`
|
||||||
* pin the DI on the ws2812 is hooked-up to
|
* pin the DI on the WS2812 is hooked-up to
|
||||||
* `#define RGBLIGHT_ANIMATIONS`
|
* `#define RGBLIGHT_ANIMATIONS`
|
||||||
* run RGB animations
|
* run RGB animations
|
||||||
* `#define RGBLED_NUM 15`
|
* `#define RGBLED_NUM 12`
|
||||||
* number of LEDs
|
* number of LEDs
|
||||||
|
* `#define RGBLED_SPLIT { 6, 6 }`
|
||||||
|
* number of LEDs connected that are directly wired to `RGB_DI_PIN` on each half of a split keyboard
|
||||||
|
* First value indicates number of LEDs for left half, second value is for the right half
|
||||||
|
* Needed if both halves of the board have RGB LEDs wired directly to the RGB output pin on the controllers instead of passing the output of the left half to the input of the right half
|
||||||
* `#define RGBLIGHT_HUE_STEP 12`
|
* `#define RGBLIGHT_HUE_STEP 12`
|
||||||
* units to step when in/decreasing hue
|
* units to step when in/decreasing hue
|
||||||
* `#define RGBLIGHT_SAT_STEP 25`
|
* `#define RGBLIGHT_SAT_STEP 25`
|
||||||
|
@ -236,6 +240,9 @@ There are a few different ways to set handedness for split keyboards (listed in
|
||||||
* `#define MATRIX_COL_PINS_RIGHT { <col pins> }`
|
* `#define MATRIX_COL_PINS_RIGHT { <col pins> }`
|
||||||
* If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns.
|
* If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns.
|
||||||
|
|
||||||
|
* `#define RGBLED_SPLIT { 6, 6 }`
|
||||||
|
* See [RGB Light Configuration](#rgb-light-configuration)
|
||||||
|
|
||||||
* `#define SELECT_SOFT_SERIAL_SPEED <speed>` (default speed is 1)
|
* `#define SELECT_SOFT_SERIAL_SPEED <speed>` (default speed is 1)
|
||||||
* Sets the protocol speed when using serial communication
|
* Sets the protocol speed when using serial communication
|
||||||
* Speeds:
|
* Speeds:
|
||||||
|
|
|
@ -23,10 +23,11 @@ RGBLIGHT_ENABLE = yes
|
||||||
|
|
||||||
At minimum you must define the data pin your LED strip is connected to, and the number of LEDs in the strip, in your `config.h`. If your keyboard has onboard RGB LEDs, and you are simply creating a keymap, you usually won't need to modify these.
|
At minimum you must define the data pin your LED strip is connected to, and the number of LEDs in the strip, in your `config.h`. If your keyboard has onboard RGB LEDs, and you are simply creating a keymap, you usually won't need to modify these.
|
||||||
|
|
||||||
|Define |Description |
|
|Define |Description |
|
||||||
|------------|---------------------------------------------|
|
|---------------|---------------------------------------------------------------------------------------------------------|
|
||||||
|`RGB_DI_PIN`|The pin connected to the data pin of the LEDs|
|
|`RGB_DI_PIN` |The pin connected to the data pin of the LEDs |
|
||||||
|`RGBLED_NUM`|The number of LEDs connected |
|
|`RGBLED_NUM` |The number of LEDs connected |
|
||||||
|
|`RGBLED_SPLIT` |(Optional) For split keyboards, the number of LEDs connected on each half directly wired to `RGB_DI_PIN` |
|
||||||
|
|
||||||
Then you should be able to use the keycodes below to change the RGB lighting to your liking.
|
Then you should be able to use the keycodes below to change the RGB lighting to your liking.
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
/* ws2812 RGB LED */
|
/* ws2812 RGB LED */
|
||||||
#define RGB_DI_PIN F7
|
#define RGB_DI_PIN F7
|
||||||
#define RGBLED_NUM 12 // Number of LEDs
|
#define RGBLED_NUM 12 // Number of LEDs
|
||||||
|
#define RGBLED_SPLIT { 6, 6 }
|
||||||
|
|
||||||
#define DYNAMIC_KEYMAP_LAYER_COUNT 4
|
#define DYNAMIC_KEYMAP_LAYER_COUNT 4
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#define RGB_DI_PIN B4
|
#define RGB_DI_PIN B4
|
||||||
#define RGBLIGHT_ANIMATIONS
|
#define RGBLIGHT_ANIMATIONS
|
||||||
#define RGBLED_NUM 12
|
#define RGBLED_NUM 12
|
||||||
|
#define RGBLED_SPLIT { 6, 6 }
|
||||||
|
|
||||||
/* Backlight LEDs */
|
/* Backlight LEDs */
|
||||||
#define BACKLIGHT_PIN B5
|
#define BACKLIGHT_PIN B5
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#undef RGBLED_NUM
|
#undef RGBLED_NUM
|
||||||
#define RGBLIGHT_ANIMATIONS
|
#define RGBLIGHT_ANIMATIONS
|
||||||
#define RGBLED_NUM 12
|
#define RGBLED_NUM 12
|
||||||
|
#define RGBLED_SPLIT { 6, 6 }
|
||||||
#define RGBLIGHT_HUE_STEP 8
|
#define RGBLIGHT_HUE_STEP 8
|
||||||
#define RGBLIGHT_SAT_STEP 8
|
#define RGBLIGHT_SAT_STEP 8
|
||||||
#define RGBLIGHT_VAL_STEP 8
|
#define RGBLIGHT_VAL_STEP 8
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
# Enable RGB if not a Planck
|
ifneq ($(LAYOUTS_HAS_RGB), no)
|
||||||
ifeq ($(LAYOUTS_HAS_RGB),yes)
|
|
||||||
RGBLIGHT_ENABLE = yes
|
RGBLIGHT_ENABLE = yes
|
||||||
endif
|
endif
|
||||||
AUDIO_ENABLE = no
|
AUDIO_ENABLE = no
|
||||||
ifeq ($(strip $(KEYBOARD)), zlant)
|
ifeq ($(strip $(KEYBOARD)), zlant)
|
||||||
BACKLIGHT_ENABLE = no
|
BACKLIGHT_ENABLE = no
|
||||||
else ifeq ($(strip $(KEYBOARD)), 40percentclub/4x4)
|
else ifeq ($(strip $(KEYBOARD)), 40percentclub/4x4)
|
||||||
BACKLIGHT_ENABLE = no
|
BACKLIGHT_ENABLE = no
|
||||||
|
else ifneq (, $(findstring lets_split, $(KEYBOARD)))
|
||||||
|
BACKLIGHT_ENABLE = no
|
||||||
else
|
else
|
||||||
BACKLIGHT_ENABLE = yes
|
BACKLIGHT_ENABLE = yes
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -66,6 +66,15 @@ bool is_rgblight_initialized = false;
|
||||||
LED_TYPE led[RGBLED_NUM];
|
LED_TYPE led[RGBLED_NUM];
|
||||||
bool rgblight_timer_enabled = false;
|
bool rgblight_timer_enabled = false;
|
||||||
|
|
||||||
|
static uint8_t clipping_start_pos = 0;
|
||||||
|
static uint8_t clipping_num_leds = RGBLED_NUM;
|
||||||
|
|
||||||
|
void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) {
|
||||||
|
clipping_start_pos = start_pos;
|
||||||
|
clipping_num_leds = num_leds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
|
void sethsv(uint16_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) {
|
||||||
uint8_t r = 0, g = 0, b = 0, base, color;
|
uint8_t r = 0, g = 0, b = 0, base, color;
|
||||||
|
|
||||||
|
@ -621,7 +630,7 @@ void rgblight_sethsv_at(uint16_t hue, uint8_t sat, uint8_t val, uint8_t index) {
|
||||||
|| defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT)
|
|| defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT)
|
||||||
|
|
||||||
static uint8_t get_interval_time(const uint8_t* default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) {
|
static uint8_t get_interval_time(const uint8_t* default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) {
|
||||||
return
|
return
|
||||||
#ifdef VELOCIKEY_ENABLE
|
#ifdef VELOCIKEY_ENABLE
|
||||||
velocikey_enabled() ? velocikey_match_speed(velocikey_min, velocikey_max) :
|
velocikey_enabled() ? velocikey_match_speed(velocikey_min, velocikey_max) :
|
||||||
#endif
|
#endif
|
||||||
|
@ -668,21 +677,20 @@ void rgblight_sethsv_slave(uint16_t hue, uint8_t sat, uint8_t val) {
|
||||||
|
|
||||||
#ifndef RGBLIGHT_CUSTOM_DRIVER
|
#ifndef RGBLIGHT_CUSTOM_DRIVER
|
||||||
void rgblight_set(void) {
|
void rgblight_set(void) {
|
||||||
|
LED_TYPE *start_led = led + clipping_start_pos;
|
||||||
|
uint16_t num_leds = clipping_num_leds;
|
||||||
if (rgblight_config.enable) {
|
if (rgblight_config.enable) {
|
||||||
LED_TYPE *ledp;
|
|
||||||
#ifdef RGBLIGHT_LED_MAP
|
#ifdef RGBLIGHT_LED_MAP
|
||||||
LED_TYPE led0[RGBLED_NUM];
|
LED_TYPE led0[RGBLED_NUM];
|
||||||
for(uint8_t i = 0; i < RGBLED_NUM; i++) {
|
for(uint8_t i = 0; i < RGBLED_NUM; i++) {
|
||||||
led0[i] = led[pgm_read_byte(&led_map[i])];
|
led0[i] = led[pgm_read_byte(&led_map[i])];
|
||||||
}
|
}
|
||||||
ledp = led0;
|
start_led = led0 + clipping_start_pos;
|
||||||
#else
|
|
||||||
ledp = led;
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef RGBW
|
#ifdef RGBW
|
||||||
ws2812_setleds_rgbw(ledp, RGBLED_NUM);
|
ws2812_setleds_rgbw(start_led, num_leds);
|
||||||
#else
|
#else
|
||||||
ws2812_setleds(ledp, RGBLED_NUM);
|
ws2812_setleds(start_led, num_leds);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
for (uint8_t i = 0; i < RGBLED_NUM; i++) {
|
for (uint8_t i = 0; i < RGBLED_NUM; i++) {
|
||||||
|
@ -691,9 +699,9 @@ void rgblight_set(void) {
|
||||||
led[i].b = 0;
|
led[i].b = 0;
|
||||||
}
|
}
|
||||||
#ifdef RGBW
|
#ifdef RGBW
|
||||||
ws2812_setleds_rgbw(led, RGBLED_NUM);
|
ws2812_setleds_rgbw(start_led, num_leds);
|
||||||
#else
|
#else
|
||||||
ws2812_setleds(led, RGBLED_NUM);
|
ws2812_setleds(start_led, num_leds);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -813,7 +821,7 @@ void rgblight_effect_breathing(uint8_t interval) {
|
||||||
float val;
|
float val;
|
||||||
|
|
||||||
uint8_t interval_time = get_interval_time(&RGBLED_BREATHING_INTERVALS[interval], 1, 100);
|
uint8_t interval_time = get_interval_time(&RGBLED_BREATHING_INTERVALS[interval], 1, 100);
|
||||||
|
|
||||||
if (timer_elapsed(last_timer) < interval_time) {
|
if (timer_elapsed(last_timer) < interval_time) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,6 +197,7 @@ void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b);
|
||||||
void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b);
|
void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b);
|
||||||
void rgblight_sethsv_master(uint16_t hue, uint8_t sat, uint8_t val);
|
void rgblight_sethsv_master(uint16_t hue, uint8_t sat, uint8_t val);
|
||||||
void rgblight_sethsv_slave(uint16_t hue, uint8_t sat, uint8_t val);
|
void rgblight_sethsv_slave(uint16_t hue, uint8_t sat, uint8_t val);
|
||||||
|
void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds);
|
||||||
|
|
||||||
uint32_t eeconfig_read_rgblight(void);
|
uint32_t eeconfig_read_rgblight(void);
|
||||||
void eeconfig_update_rgblight(uint32_t val);
|
void eeconfig_update_rgblight(uint32_t val);
|
||||||
|
|
|
@ -11,25 +11,25 @@
|
||||||
# include "eeconfig.h"
|
# include "eeconfig.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
|
||||||
|
#include "rgblight.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
volatile bool isLeftHand = true;
|
volatile bool isLeftHand = true;
|
||||||
|
|
||||||
__attribute__((weak))
|
__attribute__((weak))
|
||||||
bool is_keyboard_left(void) {
|
bool is_keyboard_left(void) {
|
||||||
#ifdef SPLIT_HAND_PIN
|
#if defined(SPLIT_HAND_PIN)
|
||||||
// Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
|
// Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
|
||||||
setPinInput(SPLIT_HAND_PIN);
|
setPinInput(SPLIT_HAND_PIN);
|
||||||
return readPin(SPLIT_HAND_PIN);
|
return readPin(SPLIT_HAND_PIN);
|
||||||
#else
|
#elif defined(EE_HANDS)
|
||||||
#ifdef EE_HANDS
|
return eeprom_read_byte(EECONFIG_HANDEDNESS);
|
||||||
return eeprom_read_byte(EECONFIG_HANDEDNESS);
|
#elif defined(MASTER_RIGHT)
|
||||||
#else
|
return !is_keyboard_master();
|
||||||
#ifdef MASTER_RIGHT
|
|
||||||
return !is_keyboard_master();
|
|
||||||
#else
|
|
||||||
return is_keyboard_master();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return is_keyboard_master();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_keyboard_master(void)
|
bool is_keyboard_master(void)
|
||||||
|
@ -71,6 +71,16 @@ void matrix_setup(void)
|
||||||
{
|
{
|
||||||
isLeftHand = is_keyboard_left();
|
isLeftHand = is_keyboard_left();
|
||||||
|
|
||||||
|
#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
|
||||||
|
uint8_t num_rgb_leds_split[2] = RGBLED_SPLIT;
|
||||||
|
if (isLeftHand) {
|
||||||
|
rgblight_set_clipping_range(0, num_rgb_leds_split[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rgblight_set_clipping_range(num_rgb_leds_split[0], num_rgb_leds_split[1]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (is_keyboard_master())
|
if (is_keyboard_master())
|
||||||
{
|
{
|
||||||
keyboard_master_setup();
|
keyboard_master_setup();
|
||||||
|
|
|
@ -92,12 +92,13 @@ typedef struct _Serial_m2s_buffer_t {
|
||||||
# ifdef BACKLIGHT_ENABLE
|
# ifdef BACKLIGHT_ENABLE
|
||||||
uint8_t backlight_level;
|
uint8_t backlight_level;
|
||||||
# endif
|
# endif
|
||||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
# if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
|
||||||
rgblight_config_t rgblight_config; // not yet use
|
rgblight_config_t rgblight_config; // not yet use
|
||||||
//
|
//
|
||||||
// When MCUs on both sides drive their respective RGB LED chains,
|
// When MCUs on both sides drive their respective RGB LED chains,
|
||||||
// it is necessary to synchronize, so it is necessary to communicate RGB
|
// it is necessary to synchronize, so it is necessary to communicate RGB
|
||||||
// information. In that case, define the RGBLIGHT_SPLIT macro.
|
// information. In that case, define RGBLED_SPLIT with info on the number
|
||||||
|
// of LEDs on each half.
|
||||||
//
|
//
|
||||||
// Otherwise, if the master side MCU drives both sides RGB LED chains,
|
// Otherwise, if the master side MCU drives both sides RGB LED chains,
|
||||||
// there is no need to communicate.
|
// there is no need to communicate.
|
||||||
|
@ -132,15 +133,20 @@ bool transport_master(matrix_row_t matrix[]) {
|
||||||
matrix[i] = serial_s2m_buffer.smatrix[i];
|
matrix[i] = serial_s2m_buffer.smatrix[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
|
||||||
// Code to send RGB over serial goes here (not implemented yet)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef BACKLIGHT_ENABLE
|
# ifdef BACKLIGHT_ENABLE
|
||||||
// Write backlight level for slave to read
|
// Write backlight level for slave to read
|
||||||
serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
|
serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
|
||||||
|
static rgblight_config_t prev_rgb = {~0};
|
||||||
|
uint32_t rgb = rgblight_read_dword();
|
||||||
|
if (rgb != prev_rgb.raw) {
|
||||||
|
serial_m2s_buffer.rgblight_config.raw = rgb;
|
||||||
|
prev_rgb.raw = rgb;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,8 +158,9 @@ void transport_slave(matrix_row_t matrix[]) {
|
||||||
# ifdef BACKLIGHT_ENABLE
|
# ifdef BACKLIGHT_ENABLE
|
||||||
backlight_set(serial_m2s_buffer.backlight_level);
|
backlight_set(serial_m2s_buffer.backlight_level);
|
||||||
# endif
|
# endif
|
||||||
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
|
# if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
|
||||||
// Add serial implementation for RGB here
|
// Update RGB config with the new data
|
||||||
|
rgblight_update_dword(serial_m2s_buffer.rgblight_config.raw);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue