Features/ws2812 matrix driver (#5418) * WS2812 driver implementation for RGB Matrix * Added driver configuration docs
11 files changed, 177 insertions(+), 13 deletions(-) M common_features.mk M docs/feature_rgb_matrix.md M drivers/avr/ws2812.c M drivers/avr/ws2812.h M keyboards/sol/keymaps/kageurufu/rules.mk M keyboards/sol/rev1/config.h M keyboards/sol/rev1/rev1.c M quantum/rgb_matrix.h M quantum/rgb_matrix_drivers.c M quantum/rgblight.c M users/kageurufu/rules.mk
M common_features.mk => common_features.mk +6 -1
@@ 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
M docs/feature_rgb_matrix.md => docs/feature_rgb_matrix.md +23 -1
@@ 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
M drivers/avr/ws2812.c => drivers/avr/ws2812.c +25 -0
@@ 27,6 27,12 @@ #include <util/delay.h> #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) {
M drivers/avr/ws2812.h => drivers/avr/ws2812.h +4 -1
@@ 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);
M keyboards/sol/keymaps/kageurufu/rules.mk => keyboards/sol/keymaps/kageurufu/rules.mk +4 -3
@@ 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
M keyboards/sol/rev1/config.h => keyboards/sol/rev1/config.h +4 -2
@@ 81,8 81,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #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 <http://www.gnu.org/licenses/>. #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 <http://www.gnu.org/licenses/>. #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
M keyboards/sol/rev1/rev1.c => keyboards/sol/rev1/rev1.c +81 -2
@@ 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(); };
M quantum/rgb_matrix.h => quantum/rgb_matrix.h +4 -2
@@ 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
M quantum/rgb_matrix_drivers.c => quantum/rgb_matrix_drivers.c +21 -0
@@ 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
M quantum/rgblight.c => quantum/rgblight.c +4 -0
@@ 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;
M users/kageurufu/rules.mk => users/kageurufu/rules.mk +1 -1