]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Features/ws2812 matrix driver (#5418)
authorXScorpion2 <rcalt2vt@gmail.com>
Mon, 15 Apr 2019 00:50:35 +0000 (20:50 -0400)
committerMechMerlin <30334081+mechmerlin@users.noreply.github.com>
Mon, 15 Apr 2019 00:50:35 +0000 (17:50 -0700)
* WS2812 driver implementation for RGB Matrix

* Added driver configuration docs

common_features.mk
docs/feature_rgb_matrix.md
drivers/avr/ws2812.c
drivers/avr/ws2812.h
keyboards/sol/keymaps/kageurufu/rules.mk
keyboards/sol/rev1/config.h
keyboards/sol/rev1/rev1.c
quantum/rgb_matrix.h
quantum/rgb_matrix_drivers.c
quantum/rgblight.c
users/kageurufu/rules.mk

index c3b6fa9168452ad381012a4b88955139568c93f8..bd1685869d0f9df3588ded77656fbbe5aad8b3da 100644 (file)
@@ -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
index 36d9d0113626d1e34af907fd38950f783946b4f7..e744ecc492029db181d8cdac971d5102c61a41e3 100644 (file)
@@ -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
index 5bd837ec7542959a4b5c51491bea2cc49c1810dc..b3ed4fd0b0ae07b1b3eb7b27970d633ddd910590 100644 (file)
 #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)
 {
index 1f9299ffb53905881119f3605f49c3e5deba8cf9..ecb1dc4d18c8e8569a2f9866fc6acfe1cd71dffb 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "rgblight_types.h"
 
-
 /* User Interface
  *
  * Input:
  *         - 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);
index d098168fd5ec627aa91c2f58dd6d1505a83697b7..bb502be00dcdf5e0724e331fa36e1f69dcc24401 100644 (file)
@@ -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
index bfdadf9f6c694b6c7dd838cbde03d30da39443f7..1ef373f96313455dd7d928a5041b458d03e428ed 100644 (file)
@@ -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
index 01ab577d4577f5656346bd751886484e047411e8..9d869a4af42e811a863b86af6e83e4ccd7d85c58 100644 (file)
@@ -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();
 };
 
index 0e193dcb2f91ac688cd2d3158617b7c18be07785..0a11f269205d20505caf61ef89eecc755ba9c9a3 100644 (file)
 #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
index 3b7d58483ab32d727fffbd21166122a89294fa24..3814dd61fc966c6472aa49e6910437b122f8c1fe 100644 (file)
@@ -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
index 08515564bc3049343336c803c32ff8605ab6ba19..e2410424e4bb169e574a0627dba658f9b1d6fc4b 100644 (file)
@@ -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;
index 1bd16e2626c6025babeae327cf4d7a0e6752ecf1..df9ae559a645920215ea4ddfe8fa89c689cd3e82 100644 (file)
@@ -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