From 5fcd744ddba591829a129560992b2e43fb615d4d Mon Sep 17 00:00:00 2001 From: XScorpion2 Date: Sun, 14 Apr 2019 20:50:35 -0400 Subject: [PATCH] Features/ws2812 matrix driver (#5418) * WS2812 driver implementation for RGB Matrix * Added driver configuration docs --- common_features.mk | 7 +- docs/feature_rgb_matrix.md | 24 ++++++- drivers/avr/ws2812.c | 25 +++++++ drivers/avr/ws2812.h | 5 +- keyboards/sol/keymaps/kageurufu/rules.mk | 7 +- keyboards/sol/rev1/config.h | 6 +- keyboards/sol/rev1/rev1.c | 83 +++++++++++++++++++++++- quantum/rgb_matrix.h | 6 +- quantum/rgb_matrix_drivers.c | 21 ++++++ quantum/rgblight.c | 4 ++ users/kageurufu/rules.mk | 2 +- 11 files changed, 177 insertions(+), 13 deletions(-) diff --git a/common_features.mk b/common_features.mk index c3b6fa9168..bd1685869d 100644 --- a/common_features.mk +++ b/common_features.mk @@ -114,7 +114,7 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) endif endif -VALID_MATRIX_TYPES := yes IS31FL3731 IS31FL3733 IS31FL3737 custom +VALID_MATRIX_TYPES := yes IS31FL3731 IS31FL3733 IS31FL3737 WS2812 custom LED_MATRIX_ENABLE ?= no ifneq ($(strip $(LED_MATRIX_ENABLE)), no) @@ -172,6 +172,11 @@ ifeq ($(strip $(RGB_MATRIX_ENABLE)), IS31FL3737) SRC += i2c_master.c endif +ifeq ($(strip $(RGB_MATRIX_ENABLE)), WS2812) + OPT_DEFS += -DWS2812 + SRC += ws2812.c +endif + ifeq ($(strip $(TAP_DANCE_ENABLE)), yes) OPT_DEFS += -DTAP_DANCE_ENABLE SRC += $(QUANTUM_DIR)/process_keycode/process_tap_dance.c diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md index 36d9d01136..e744ecc492 100644 --- a/docs/feature_rgb_matrix.md +++ b/docs/feature_rgb_matrix.md @@ -5,7 +5,7 @@ This feature allows you to use RGB LED matrices driven by external drivers. It h If you want to use single color LED's you should use the [LED Matrix Subsystem](feature_led_matrix.md) instead. ## Driver configuration - +--- ### IS31FL3731 There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`: @@ -52,6 +52,7 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0` or `1` right now). +--- ### IS31FL3733/IS31FL3737 !> For the IS31FL3737, replace all instances of `IS31FL3733` below with `IS31FL3737`. @@ -102,6 +103,27 @@ const is31_led g_is31_leds[DRIVER_LED_TOTAL] = { Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](http://www.issi.com/WW/pdf/31FL3733.pdf) and the header file `drivers/issi/is31fl3733.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0` right now). +--- + +### WS2812 (AVR only) + +There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{a,b,c} addressable LED strand. To enable it, add this to your `rules.mk`: + +```C +RGB_MATRIX_ENABLE = WS2812 +``` + +Configure the hardware via your `config.h`: + +```C +// The pin connected to the data pin of the LEDs +#define RGB_DI_PIN D7 +// The number of LEDs connected +#define DRIVER_LED_TOTAL 70 +``` + +--- + From this point forward the configuration is the same for all the drivers. ```C diff --git a/drivers/avr/ws2812.c b/drivers/avr/ws2812.c index 5bd837ec75..b3ed4fd0b0 100644 --- a/drivers/avr/ws2812.c +++ b/drivers/avr/ws2812.c @@ -27,6 +27,12 @@ #include #include "debug.h" +#if !defined(LED_ARRAY) && defined(RGB_MATRIX_ENABLE) +// LED color buffer +LED_TYPE led[DRIVER_LED_TOTAL]; + #define LED_ARRAY led +#endif + #ifdef RGBW_BB_TWI // Port for the I2C @@ -141,6 +147,25 @@ unsigned char I2C_Write(unsigned char c) #endif +#ifdef RGB_MATRIX_ENABLE +// Set an led in the buffer to a color +void inline ws2812_setled(int i, uint8_t r, uint8_t g, uint8_t b) +{ + led[i].r = r; + led[i].g = g; + led[i].b = b; +} + +void ws2812_setled_all (uint8_t r, uint8_t g, uint8_t b) +{ + for (int i = 0; i < RGBLED_NUM; i++) { + led[i].r = r; + led[i].g = g; + led[i].b = b; + } +} +#endif + // Setleds for standard RGB void inline ws2812_setleds(LED_TYPE *ledarray, uint16_t leds) { diff --git a/drivers/avr/ws2812.h b/drivers/avr/ws2812.h index 1f9299ffb5..ecb1dc4d18 100644 --- a/drivers/avr/ws2812.h +++ b/drivers/avr/ws2812.h @@ -30,7 +30,6 @@ #include "rgblight_types.h" - /* User Interface * * Input: @@ -43,6 +42,10 @@ * - Send out the LED data * - Wait 50�s to reset the LEDs */ +#ifdef RGB_MATRIX_ENABLE +void ws2812_setled (int index, uint8_t r, uint8_t g, uint8_t b); +void ws2812_setled_all (uint8_t r, uint8_t g, uint8_t b); +#endif void ws2812_setleds (LED_TYPE *ledarray, uint16_t number_of_leds); void ws2812_setleds_pin (LED_TYPE *ledarray, uint16_t number_of_leds,uint8_t pinmask); diff --git a/keyboards/sol/keymaps/kageurufu/rules.mk b/keyboards/sol/keymaps/kageurufu/rules.mk index d098168fd5..bb502be00d 100644 --- a/keyboards/sol/keymaps/kageurufu/rules.mk +++ b/keyboards/sol/keymaps/kageurufu/rules.mk @@ -4,14 +4,15 @@ # BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration(+1000) MOUSEKEY_ENABLE = no # Mouse keys(+4700) + EXTRAKEY_ENABLE = yes # Audio control and System control(+450) CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration NKRO_ENABLE = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -RGBLIGHT_ENABLE = yes # Enable global lighting effects. Do not enable with RGB Matrix -LED_ANIMATIONS = yes # LED animations +RGBLIGHT_ENABLE = no # Enable global lighting effects. Do not enable with RGB Matrix +RGBLIGHT_ANIMATIONS = no # LED animations LED_MIRRORED = no # Mirror LEDs across halves (enable DIP 1 on slave, and DIP 2 and 3 on master) -RGB_MATRIX_ENABLE = no # Enable per-key coordinate based RGB effects. Do not enable with RGBlight (+8500) +RGB_MATRIX_ENABLE = WS2812 # Enable per-key coordinate based RGB effects. Do not enable with RGBlight (+8500) RGB_MATRIX_KEYPRESSES = no # Enable reactive per-key effects. Can be very laggy (+1500) RGBLIGHT_FULL_POWER = no # Allow maximum RGB brightness. Otherwise, limited to a safe level for a normal USB-A port UNICODE_ENABLE = no # Unicode diff --git a/keyboards/sol/rev1/config.h b/keyboards/sol/rev1/config.h index bfdadf9f6c..1ef373f963 100644 --- a/keyboards/sol/rev1/config.h +++ b/keyboards/sol/rev1/config.h @@ -81,8 +81,7 @@ along with this program. If not, see . #define ws2812_PORTREG PORTD #define ws2812_DDRREG DDRD -#define DRIVER_COUNT 2 -#define DRIVER_LED_TOTAL 70 +#define DRIVER_COUNT 1 // #define RGB_MATRIX_KEYPRESSES #define BACKLIGHT_PIN B7 #define BACKLIGHT_LEVELS 5 @@ -92,6 +91,7 @@ along with this program. If not, see . #else #define RGBLED_NUM 70 #endif +#define DRIVER_LED_TOTAL RGBLED_NUM #define RGBLIGHT_RAINBOW_SWIRL_RANGE 1950 @@ -112,6 +112,8 @@ along with this program. If not, see . #define RGBLIGHT_ANIMATIONS +#define LED_HITS_TO_REMEMBER 5 + #if defined(RGBLIGHT_ENABLE) && !defined(IOS_DEVICE_ENABLE) // USB_MAX_POWER_CONSUMPTION value for Helix keyboard // 120 RGBoff, OLEDoff diff --git a/keyboards/sol/rev1/rev1.c b/keyboards/sol/rev1/rev1.c index 01ab577d45..9d869a4af4 100644 --- a/keyboards/sol/rev1/rev1.c +++ b/keyboards/sol/rev1/rev1.c @@ -1,6 +1,5 @@ #include "sol.h" - #ifdef SSD1306OLED void led_set_kb(uint8_t usb_led) { // put your keyboard LED indicator (ex: Caps Lock LED) toggling code here @@ -8,8 +7,88 @@ void led_set_kb(uint8_t usb_led) { } #endif -void matrix_init_kb(void) { +#ifdef RGB_MATRIX_ENABLE + const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = { + // Left Hand Mapped Left to Right + { { 0 | (0 << 4) }, { 0, 0 }, 1}, + { { 0 | (1 << 4) }, { 22, 0 }, 0}, + { { 0 | (2 << 4) }, { 37, 0 }, 0}, + { { 0 | (3 << 4) }, { 37, 0 }, 0}, + { { 0 | (4 << 4) }, { 67, 0 }, 0}, + { { 0 | (5 << 4) }, { 82, 0 }, 0}, + { { 0 | (6 << 4) }, { 104, 0 }, 1}, + { { 1 | (0 << 4) }, { 0, 16 }, 1}, + { { 1 | (1 << 4) }, { 22, 16 }, 0}, + { { 1 | (2 << 4) }, { 37, 16 }, 0}, + { { 1 | (3 << 4) }, { 37, 16 }, 0}, + { { 1 | (4 << 4) }, { 67, 16 }, 0}, + { { 1 | (5 << 4) }, { 82, 16 }, 0}, + { { 1 | (6 << 4) }, { 104, 16 }, 1}, + { { 2 | (0 << 4) }, { 0, 32 }, 1}, + { { 2 | (1 << 4) }, { 22, 32 }, 0}, + { { 2 | (2 << 4) }, { 37, 32 }, 0}, + { { 2 | (3 << 4) }, { 37, 32 }, 0}, + { { 2 | (4 << 4) }, { 67, 32 }, 0}, + { { 2 | (5 << 4) }, { 82, 32 }, 0}, + { { 2 | (6 << 4) }, { 104, 32 }, 1}, + { { 3 | (0 << 4) }, { 0, 48 }, 1}, + { { 3 | (1 << 4) }, { 22, 48 }, 0}, + { { 3 | (2 << 4) }, { 37, 48 }, 0}, + { { 3 | (3 << 4) }, { 37, 48 }, 0}, + { { 3 | (4 << 4) }, { 67, 48 }, 0}, + { { 3 | (5 << 4) }, { 82, 48 }, 0}, + { { 3 | (6 << 4) }, { 104, 48 }, 1}, + { { 4 | (0 << 4) }, { 0, 64 }, 1}, + { { 4 | (1 << 4) }, { 22, 64 }, 1}, + { { 4 | (2 << 4) }, { 37, 64 }, 1}, + { { 4 | (3 << 4) }, { 37, 64 }, 1}, + { { 4 | (4 << 4) }, { 67, 64 }, 1}, + // These two control the 4 LEDs in the thumb cluster + // Top keys are { 4 | (5 << 4) & { 4 | (6 << 4) + { { 5 | (5 << 4) }, { 89, 45 }, 1}, + { { 5 | (6 << 4) }, { 97, 55 }, 1}, + // Left Hand Mapped Right to Left + { { 6 | (0 << 4) }, { 224, 0 }, 1}, + { { 6 | (1 << 4) }, { 202, 0 }, 0}, + { { 6 | (2 << 4) }, { 187, 0 }, 0}, + { { 6 | (3 << 4) }, { 172, 0 }, 0}, + { { 6 | (4 << 4) }, { 157, 0 }, 0}, + { { 6 | (5 << 4) }, { 142, 0 }, 0}, + { { 6 | (6 << 4) }, { 120, 0 }, 1}, + { { 7 | (0 << 4) }, { 224, 16 }, 1}, + { { 7 | (1 << 4) }, { 202, 16 }, 0}, + { { 7 | (2 << 4) }, { 187, 16 }, 0}, + { { 7 | (3 << 4) }, { 172, 16 }, 0}, + { { 7 | (4 << 4) }, { 157, 16 }, 0}, + { { 7 | (5 << 4) }, { 142, 16 }, 0}, + { { 7 | (6 << 4) }, { 120, 16 }, 1}, + { { 8 | (0 << 4) }, { 224, 32 }, 1}, + { { 8 | (1 << 4) }, { 202, 32 }, 0}, + { { 8 | (2 << 4) }, { 187, 32 }, 0}, + { { 8 | (3 << 4) }, { 172, 32 }, 0}, + { { 8 | (4 << 4) }, { 157, 32 }, 0}, + { { 8 | (5 << 4) }, { 142, 32 }, 0}, + { { 8 | (6 << 4) }, { 120, 32 }, 1}, + { { 9 | (0 << 4) }, { 224, 48 }, 1}, + { { 9 | (1 << 4) }, { 202, 48 }, 0}, + { { 9 | (2 << 4) }, { 187, 48 }, 0}, + { { 9 | (3 << 4) }, { 172, 48 }, 0}, + { { 9 | (4 << 4) }, { 157, 48 }, 0}, + { { 9 | (5 << 4) }, { 142, 48 }, 0}, + { { 9 | (6 << 4) }, { 120, 48 }, 1}, + { { 10 | (0 << 4) }, { 224, 64 }, 1}, + { { 10 | (1 << 4) }, { 202, 64 }, 1}, + { { 10 | (2 << 4) }, { 187, 64 }, 1}, + { { 10 | (3 << 4) }, { 172, 64 }, 1}, + { { 10 | (4 << 4) }, { 157, 64 }, 1}, + // These two control the 4 LEDs in the thumb cluster + // Top keys are { 10 | (5 << 4) & { 10 | (6 << 4) + { { 11 | (5 << 4) }, { 135, 45 }, 1}, + { { 11 | (6 << 4) }, { 127, 55 }, 1} + }; +#endif +void matrix_init_kb(void) { matrix_init_user(); }; diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h index 0e193dcb2f..0a11f26920 100644 --- a/quantum/rgb_matrix.h +++ b/quantum/rgb_matrix.h @@ -28,9 +28,11 @@ #ifdef IS31FL3731 #include "is31fl3731.h" #elif defined (IS31FL3733) - #include "is31fl3733.h" + #include "is31fl3733.h" #elif defined (IS31FL3737) - #include "is31fl3737.h" + #include "is31fl3737.h" +#elif defined (WS2812) + #include "ws2812.h" #endif #ifndef RGB_MATRIX_LED_FLUSH_LIMIT diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c index 3b7d58483a..3814dd61fc 100644 --- a/quantum/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix_drivers.c @@ -97,4 +97,25 @@ const rgb_matrix_driver_t rgb_matrix_driver = { }; #endif +#elif defined(WS2812) + +extern LED_TYPE led[RGBLED_NUM]; + + static void flush( void ) + { + // Assumes use of RGB_DI_PIN + ws2812_setleds(led, RGBLED_NUM); + } + + static void init( void ) + { + + } + + const rgb_matrix_driver_t rgb_matrix_driver = { + .init = init, + .flush = flush, + .set_color = ws2812_setled, + .set_color_all = ws2812_setled_all, + }; #endif diff --git a/quantum/rgblight.c b/quantum/rgblight.c index 08515564bc..e2410424e4 100644 --- a/quantum/rgblight.c +++ b/quantum/rgblight.c @@ -63,7 +63,11 @@ const uint16_t RGBLED_GRADIENT_RANGES[] PROGMEM = {360, 240, 180, 120, 90}; rgblight_config_t rgblight_config; bool is_rgblight_initialized = false; +#ifndef LED_ARRAY LED_TYPE led[RGBLED_NUM]; + #define LED_ARRAY led +#endif + bool rgblight_timer_enabled = false; static uint8_t clipping_start_pos = 0; diff --git a/users/kageurufu/rules.mk b/users/kageurufu/rules.mk index 1bd16e2626..df9ae559a6 100644 --- a/users/kageurufu/rules.mk +++ b/users/kageurufu/rules.mk @@ -11,5 +11,5 @@ MOUSEKEY_ENABLE = no EXTRAKEY_ENABLE = yes COMMAND_ENABLE = yes CONSOLE_ENABLE = yes -RGBLIGHT_ENABLE = yes +RGBLIGHT_ENABLE = no RGBLIGHT_ANIMATIONS = yes