Skip to content
Permalink
Browse files

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
  • Loading branch information...
nooges authored and drashna committed Mar 24, 2019
1 parent 2308680 commit f077204fae729e66f8dfa16db82263ff2ff84d59
@@ -171,11 +171,15 @@ If you define these options you will enable the associated feature, which may in
## RGB Light Configuration

* `#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`
* run RGB animations
* `#define RGBLED_NUM 15`
* `#define RGBLED_NUM 12`
* 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`
* units to step when in/decreasing hue
* `#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> }`
* 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)
* Sets the protocol speed when using serial communication
* 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.

|Define |Description |
|------------|---------------------------------------------|
|`RGB_DI_PIN`|The pin connected to the data pin of the LEDs|
|`RGBLED_NUM`|The number of LEDs connected |
|Define |Description |
|---------------|---------------------------------------------------------------------------------------------------------|
|`RGB_DI_PIN` |The pin connected to the data pin of the LEDs |
|`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.

@@ -71,6 +71,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* ws2812 RGB LED */
#define RGB_DI_PIN F7
#define RGBLED_NUM 12 // Number of LEDs
#define RGBLED_SPLIT { 6, 6 }

#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 RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 12
#define RGBLED_SPLIT { 6, 6 }

/* Backlight LEDs */
#define BACKLIGHT_PIN B5
@@ -10,6 +10,7 @@
#undef RGBLED_NUM
#define RGBLIGHT_ANIMATIONS
#define RGBLED_NUM 12
#define RGBLED_SPLIT { 6, 6 }
#define RGBLIGHT_HUE_STEP 8
#define RGBLIGHT_SAT_STEP 8
#define RGBLIGHT_VAL_STEP 8
@@ -1,12 +1,13 @@
# Enable RGB if not a Planck
ifeq ($(LAYOUTS_HAS_RGB),yes)
ifneq ($(LAYOUTS_HAS_RGB), no)
RGBLIGHT_ENABLE = yes
endif
AUDIO_ENABLE = no
ifeq ($(strip $(KEYBOARD)), zlant)
BACKLIGHT_ENABLE = no
else ifeq ($(strip $(KEYBOARD)), 40percentclub/4x4)
BACKLIGHT_ENABLE = no
BACKLIGHT_ENABLE = no
else ifneq (, $(findstring lets_split, $(KEYBOARD)))
BACKLIGHT_ENABLE = no
else
BACKLIGHT_ENABLE = yes
endif
@@ -66,6 +66,15 @@ bool is_rgblight_initialized = false;
LED_TYPE led[RGBLED_NUM];
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) {
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)

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
velocikey_enabled() ? velocikey_match_speed(velocikey_min, velocikey_max) :
#endif
@@ -668,21 +677,20 @@ void rgblight_sethsv_slave(uint16_t hue, uint8_t sat, uint8_t val) {

#ifndef RGBLIGHT_CUSTOM_DRIVER
void rgblight_set(void) {
LED_TYPE *start_led = led + clipping_start_pos;
uint16_t num_leds = clipping_num_leds;
if (rgblight_config.enable) {
LED_TYPE *ledp;
#ifdef RGBLIGHT_LED_MAP
LED_TYPE led0[RGBLED_NUM];
for(uint8_t i = 0; i < RGBLED_NUM; i++) {
led0[i] = led[pgm_read_byte(&led_map[i])];
}
ledp = led0;
#else
ledp = led;
start_led = led0 + clipping_start_pos;
#endif
#ifdef RGBW
ws2812_setleds_rgbw(ledp, RGBLED_NUM);
ws2812_setleds_rgbw(start_led, num_leds);
#else
ws2812_setleds(ledp, RGBLED_NUM);
ws2812_setleds(start_led, num_leds);
#endif
} else {
for (uint8_t i = 0; i < RGBLED_NUM; i++) {
@@ -691,9 +699,9 @@ void rgblight_set(void) {
led[i].b = 0;
}
#ifdef RGBW
ws2812_setleds_rgbw(led, RGBLED_NUM);
ws2812_setleds_rgbw(start_led, num_leds);
#else
ws2812_setleds(led, RGBLED_NUM);
ws2812_setleds(start_led, num_leds);
#endif
}
}
@@ -813,7 +821,7 @@ void rgblight_effect_breathing(uint8_t interval) {
float val;

uint8_t interval_time = get_interval_time(&RGBLED_BREATHING_INTERVALS[interval], 1, 100);

if (timer_elapsed(last_timer) < interval_time) {
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_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_set_clipping_range(uint8_t start_pos, uint8_t num_leds);

uint32_t eeconfig_read_rgblight(void);
void eeconfig_update_rgblight(uint32_t val);
@@ -11,25 +11,25 @@
# include "eeconfig.h"
#endif

#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
#include "rgblight.h"
#endif

volatile bool isLeftHand = true;

__attribute__((weak))
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
setPinInput(SPLIT_HAND_PIN);
return readPin(SPLIT_HAND_PIN);
#else
#ifdef EE_HANDS
return eeprom_read_byte(EECONFIG_HANDEDNESS);
#else
#ifdef MASTER_RIGHT
return !is_keyboard_master();
#else
return is_keyboard_master();
#endif
#endif
#elif defined(EE_HANDS)
return eeprom_read_byte(EECONFIG_HANDEDNESS);
#elif defined(MASTER_RIGHT)
return !is_keyboard_master();
#endif

return is_keyboard_master();
}

bool is_keyboard_master(void)
@@ -71,6 +71,16 @@ void matrix_setup(void)
{
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())
{
keyboard_master_setup();
@@ -92,12 +92,13 @@ typedef struct _Serial_m2s_buffer_t {
# ifdef BACKLIGHT_ENABLE
uint8_t backlight_level;
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
# if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
rgblight_config_t rgblight_config; // not yet use
//
// When MCUs on both sides drive their respective RGB LED chains,
// 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,
// there is no need to communicate.
@@ -132,15 +133,20 @@ bool transport_master(matrix_row_t matrix[]) {
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
// Write backlight level for slave to read
serial_m2s_buffer.backlight_level = backlight_config.enable ? backlight_config.level : 0;
# 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;
}

@@ -152,8 +158,9 @@ void transport_slave(matrix_row_t matrix[]) {
# ifdef BACKLIGHT_ENABLE
backlight_set(serial_m2s_buffer.backlight_level);
# endif
# if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT)
// Add serial implementation for RGB here
# if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
// Update RGB config with the new data
rgblight_update_dword(serial_m2s_buffer.rgblight_config.raw);
# endif
}

0 comments on commit f077204

Please sign in to comment.
You can’t perform that action at this time.