~ruther/qmk_firmware

5fcd744ddba591829a129560992b2e43fb615d4d — XScorpion2 6 years ago d7ba190
Features/ws2812 matrix driver (#5418)

* WS2812 driver implementation for RGB Matrix

* Added driver configuration docs
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
@@ 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