WS2812 API rework (#24364)
* Begin WS2812 API rework * Move RGBW conversion, clean up color.h, fix RGBW for AVR bitbang * Formatting & update PS2AVRGB I2C driver (untested) * Tested ARM bitbang RGB+RGBW * Tested ARM SPI RGB - RGBW not working * Tested ARM PWM RGB+RGBW * Tested RP2040 PIO driver RGB+RGBW * Update RGBLight * Formatting * Fix BM60HSRGB rev2 * Fix oddforge/vea * Fix 1k and XD002 RGBLite * Fix model_m/mschwingen * Fix handwired/promethium * Rename `WS2812_LED_TOTAL` for BM60HSRGB * Fix work_louder boards * Fix dawn60 * Fix rgbkb/pan * Fix neson_design/700e and n6 * Fix ergodox_ez/shine * ergodox_ez/shine: invert indices for left half * Fix matrix/abelx * Fix matrix/m20add * Remove custom rgblight driver for matrix/noah - should be done with lighting layers * Fix LED indexes for RGBLight split * Rename `convert_rgb_to_rgbw()` to `ws2812_rgb_to_rgbw()` * Update WS2812 API docs * `ergodox_ez/shine`: simplify LED index calculation * LED/RGB Matrix: Add weak function for LED index resolution * Bandaid fix for RGB Matrix splits not using WS2812 * `steelseries/prime_plus`: redo custom RGBLight driver * Update keyboards/steelseries/prime_plus/rgblight_custom.c Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com> --------- Co-authored-by: Dasky <32983009+daskygit@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									43e82ed5c7
								
							
						
					
					
						commit
						208ebf54a9
					
				
					 61 changed files with 649 additions and 672 deletions
				
			
		|  | @ -932,7 +932,7 @@ ifeq ($(strip $(WS2812_DRIVER_REQUIRED)), yes) | |||
| 
 | ||||
|     OPT_DEFS += -DWS2812_$(strip $(shell echo $(WS2812_DRIVER) | tr '[:lower:]' '[:upper:]')) | ||||
| 
 | ||||
|     SRC += ws2812_$(strip $(WS2812_DRIVER)).c | ||||
|     SRC += ws2812.c ws2812_$(strip $(WS2812_DRIVER)).c | ||||
| 
 | ||||
|     ifeq ($(strip $(PLATFORM)), CHIBIOS) | ||||
|         ifeq ($(strip $(WS2812_DRIVER)), pwm) | ||||
|  |  | |||
|  | @ -241,13 +241,44 @@ Using a complementary timer output (`TIMx_CHyN`) is possible only for advanced-c | |||
| 
 | ||||
| ## API {#api} | ||||
| 
 | ||||
| ### `void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds)` {#api-ws2812-setleds} | ||||
| ### `void ws2812_init(void)` {#api-ws2812-init} | ||||
| 
 | ||||
| Send RGB data to the WS2812 LED chain. | ||||
| Initialize the LED driver. This function should be called first. | ||||
| 
 | ||||
| #### Arguments {#api-ws2812-setleds-arguments} | ||||
| --- | ||||
| 
 | ||||
|  - `rgb_led_t *ledarray`   | ||||
|    A pointer to the LED array. | ||||
|  - `uint16_t number_of_leds`   | ||||
|    The length of the LED array. | ||||
| ### `void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color} | ||||
| 
 | ||||
| Set the color of a single LED. This function does not immediately update the LEDs; call `ws2812_flush()` after you are finished. | ||||
| 
 | ||||
| #### Arguments {#api-ws2812-set-color-arguments} | ||||
| 
 | ||||
|  - `int index`   | ||||
|    The LED index in the WS2812 chain. | ||||
|  - `uint8_t red`   | ||||
|    The red value to set. | ||||
|  - `uint8_t green`   | ||||
|    The green value to set. | ||||
|  - `uint8_t blue`   | ||||
|    The blue value to set. | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| ### `void ws812_set_color_all(uint8_t red, uint8_t green, uint8_t blue)` {#api-ws2812-set-color-all} | ||||
| 
 | ||||
| Set the color of all LEDs. | ||||
| 
 | ||||
| #### Arguments {#api-ws2812-set-color-all-arguments} | ||||
| 
 | ||||
|  - `uint8_t red`   | ||||
|    The red value to set. | ||||
|  - `uint8_t green`   | ||||
|    The green value to set. | ||||
|  - `uint8_t blue`   | ||||
|    The blue value to set. | ||||
| 
 | ||||
| --- | ||||
| 
 | ||||
| ### `void ws2812_flush(void)` {#api-ws2812-flush} | ||||
| 
 | ||||
| Flush the PWM values to the LED chain. | ||||
|  |  | |||
							
								
								
									
										15
									
								
								drivers/ws2812.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								drivers/ws2812.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | |||
| // Copyright 2024 QMK
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include "ws2812.h" | ||||
| 
 | ||||
| #if defined(WS2812_RGBW) | ||||
| void ws2812_rgb_to_rgbw(ws2812_led_t *led) { | ||||
|     // Determine lowest value in all three colors, put that into
 | ||||
|     // the white channel and then shift all colors by that amount
 | ||||
|     led->w = MIN(led->r, MIN(led->g, led->b)); | ||||
|     led->r -= led->w; | ||||
|     led->g -= led->w; | ||||
|     led->b -= led->w; | ||||
| } | ||||
| #endif | ||||
|  | @ -15,7 +15,7 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "quantum/color.h" | ||||
| #include "util.h" | ||||
| 
 | ||||
| /*
 | ||||
|  * The WS2812 datasheets define T1H 900ns, T0H 350ns, T1L 350ns, T0L 900ns. Hence, by default, these | ||||
|  | @ -62,17 +62,36 @@ | |||
| #    define WS2812_LED_COUNT RGB_MATRIX_LED_COUNT | ||||
| #endif | ||||
| 
 | ||||
| void ws2812_init(void); | ||||
| #define WS2812_BYTE_ORDER_RGB 0 | ||||
| #define WS2812_BYTE_ORDER_GRB 1 | ||||
| #define WS2812_BYTE_ORDER_BGR 2 | ||||
| 
 | ||||
| /* User Interface
 | ||||
|  * | ||||
|  * Input: | ||||
|  *         ledarray:           An array of GRB data describing the LED colors | ||||
|  *         number_of_leds:     The number of LEDs to write | ||||
|  * | ||||
|  * The functions will perform the following actions: | ||||
|  *         - Set the data-out pin as output | ||||
|  *         - Send out the LED data | ||||
|  *         - Wait 50us to reset the LEDs | ||||
|  */ | ||||
| void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds); | ||||
| #ifndef WS2812_BYTE_ORDER | ||||
| #    define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB | ||||
| #endif | ||||
| 
 | ||||
| typedef struct PACKED ws2812_led_t { | ||||
| #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) | ||||
|     uint8_t g; | ||||
|     uint8_t r; | ||||
|     uint8_t b; | ||||
| #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB) | ||||
|     uint8_t r; | ||||
|     uint8_t g; | ||||
|     uint8_t b; | ||||
| #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) | ||||
|     uint8_t b; | ||||
|     uint8_t g; | ||||
|     uint8_t r; | ||||
| #endif | ||||
| #ifdef WS2812_RGBW | ||||
|     uint8_t w; | ||||
| #endif | ||||
| } ws2812_led_t; | ||||
| 
 | ||||
| void ws2812_init(void); | ||||
| void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | ||||
| void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | ||||
| void ws2812_flush(void); | ||||
| 
 | ||||
| void ws2812_rgb_to_rgbw(ws2812_led_t *led); | ||||
|  |  | |||
|  | @ -32,3 +32,5 @@ | |||
| #define USB_INTR_ENABLE_BIT PCIE | ||||
| #define USB_INTR_PENDING_BIT PCIF | ||||
| #define USB_INTR_VECTOR SIG_PIN_CHANGE | ||||
| 
 | ||||
| #define WS2812_LED_COUNT 1 | ||||
|  |  | |||
|  | @ -11,8 +11,8 @@ static inline void rgblite_init(void) { | |||
| } | ||||
| 
 | ||||
| static inline void rgblite_setrgb(RGB rgb) { | ||||
|     rgb_led_t leds[RGBLIGHT_LED_COUNT] = {{.r = rgb.r, .g = rgb.g, .b = rgb.b}}; | ||||
|     ws2812_setleds(leds, RGBLIGHT_LED_COUNT); | ||||
|     ws2812_set_color_all(rgb.r, rgb.g, rgb.b); | ||||
|     ws2812_flush(); | ||||
| } | ||||
| 
 | ||||
| static void rgblite_increase_hue(void) { | ||||
|  |  | |||
|  | @ -33,8 +33,10 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| 
 | ||||
| #ifdef ERGODOX_LED_30 | ||||
| // If using 30 LEDs, then define that many
 | ||||
| #    define WS2812_LED_COUNT 30 | ||||
| #    define RGBLIGHT_LED_COUNT 30  // Number of LEDs
 | ||||
| #else | ||||
| // If not, then only define 15
 | ||||
| #    define WS2812_LED_COUNT 15 | ||||
| #    define RGBLIGHT_LED_COUNT 15  // Number of LEDs
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -21,47 +21,55 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #include "ergodox_ez.h" | ||||
| #include "ws2812.h" | ||||
| 
 | ||||
| void setleds_custom(rgb_led_t *led, uint16_t led_num) { | ||||
|     uint16_t length = 0; | ||||
|     int i = 0; | ||||
|     int j = 0; | ||||
| #    ifdef WS2812_RGBW | ||||
|     int bytes_per_led = 4; | ||||
| #    else | ||||
|     int bytes_per_led = 3; | ||||
| #    endif | ||||
| #    if defined(ERGODOX_LED_30) | ||||
|     // prevent right-half code from trying to bitbang all 30
 | ||||
|     // so with 30 LEDs, we count from 29 to 15 here, and the
 | ||||
|     // other half does 0 to 14.
 | ||||
|     uint8_t half_led_num = RGBLIGHT_LED_COUNT / 2; | ||||
|     length = half_led_num * bytes_per_led; | ||||
|     uint8_t data[length]; | ||||
|     for (i = half_led_num + half_led_num - 1; i >= half_led_num; --i) | ||||
| #    elif defined(ERGODOX_LED_15_MIRROR) | ||||
|     length = led_num * bytes_per_led; | ||||
|     uint8_t data[length]; | ||||
|     for (i = 0; i < led_num; ++i) | ||||
| #    else  // ERGDOX_LED_15 non-mirrored
 | ||||
|     length = led_num * bytes_per_led; | ||||
|     uint8_t data[length]; | ||||
|     for (i = led_num - 1; i >= 0; --i) | ||||
| #    endif | ||||
|     { | ||||
|         uint8_t *data_byte = (uint8_t *)(led + i); | ||||
|         data[j++] = data_byte[0]; | ||||
|         data[j++] = data_byte[1]; | ||||
|         data[j++] = data_byte[2]; | ||||
| #ifdef WS2812_RGBW | ||||
|         data[j++] = data_byte[3]; | ||||
| #endif | ||||
|     } | ||||
|     i2c_transmit(0x84, data, sizeof(data), ERGODOX_EZ_I2C_TIMEOUT); | ||||
| #define WS2812_I2C_ADDRESS_LEFT 0x84 | ||||
| 
 | ||||
|     ws2812_setleds(led, led_num); | ||||
| #if defined(ERGODOX_LED_30) | ||||
| #    define WS2812_LED_COUNT_LEFT (RGBLIGHT_LED_COUNT / 2) | ||||
| ws2812_led_t ws2812_leds_left[WS2812_LED_COUNT_LEFT]; | ||||
| #else | ||||
| #    define WS2812_LED_COUNT_LEFT RGBLIGHT_LED_COUNT | ||||
| ws2812_led_t ws2812_leds_left[WS2812_LED_COUNT_LEFT]; | ||||
| #endif | ||||
| 
 | ||||
| void set_color_left(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     ws2812_leds_left[index].r = red; | ||||
|     ws2812_leds_left[index].g = green; | ||||
|     ws2812_leds_left[index].b = blue; | ||||
| #if defined(WS2812_RGBW) | ||||
|     ws2812_rgb_to_rgbw(&ws2812_leds_left[index]); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
| #if defined(ERGODOX_LED_30) | ||||
|     if (index < WS2812_LED_COUNT_LEFT) { | ||||
|         ws2812_set_color(index, red, green, blue); | ||||
|     } else { | ||||
|         set_color_left(RGBLIGHT_LED_COUNT - index - 1, red, green, blue); | ||||
|     } | ||||
| #elif defined(ERGODOX_LED_15_MIRROR) | ||||
|     ws2812_set_color(index, red, green, blue); | ||||
|     set_color_left(index, red, green, blue); | ||||
| #else | ||||
|     ws2812_set_color(index, red, green, blue); | ||||
|     set_color_left(WS2812_LED_COUNT_LEFT - index - 1, red, green, blue); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) { | ||||
|         set_color_custom(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void flush_custom(void) { | ||||
|     i2c_transmit(WS2812_I2C_ADDRESS_LEFT, (uint8_t *)ws2812_leds_left, sizeof(ws2812_leds_left), ERGODOX_EZ_I2C_TIMEOUT); | ||||
|     ws2812_flush(); | ||||
| } | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .init    = ws2812_init, | ||||
|     .setleds = setleds_custom, | ||||
|     .init          = ws2812_init, | ||||
|     .set_color     = set_color_custom, | ||||
|     .set_color_all = set_color_all_custom, | ||||
|     .flush         = flush_custom, | ||||
| }; | ||||
|  |  | |||
|  | @ -155,6 +155,7 @@ enum led_sequence { | |||
| }; | ||||
| 
 | ||||
| #    define RGBSPS_NUM LED_TOTAL | ||||
| #    define WS2812_LED_COUNT RGBSPS_NUM | ||||
| #endif | ||||
| 
 | ||||
| /* PS/2 mouse */ | ||||
|  |  | |||
|  | @ -2,8 +2,6 @@ | |||
| #include "ws2812.h" | ||||
| #include "rgbsps.h" | ||||
| 
 | ||||
| rgb_led_t led[RGBSPS_NUM]; | ||||
| 
 | ||||
| void keyboard_pre_init_kb(void) { | ||||
|   ws2812_init(); | ||||
| 
 | ||||
|  | @ -11,9 +9,7 @@ void keyboard_pre_init_kb(void) { | |||
| } | ||||
| 
 | ||||
| void rgbsps_set(uint8_t index, uint8_t r, uint8_t g, uint8_t b) { | ||||
|   led[index].r = r; | ||||
|   led[index].g = g; | ||||
|   led[index].b = b; | ||||
|   ws2812_set_color(index, r, g, b); | ||||
| } | ||||
| 
 | ||||
| void rgbsps_setall(uint8_t r, uint8_t g, uint8_t b) { | ||||
|  | @ -27,7 +23,7 @@ void rgbsps_turnoff(void) { | |||
| } | ||||
| 
 | ||||
| void rgbsps_send(void) { | ||||
|   ws2812_setleds(led, RGBSPS_NUM); | ||||
|   ws2812_flush(); | ||||
| } | ||||
| 
 | ||||
| void rgbsps_sethsv(uint8_t index, uint16_t hue, uint8_t sat, uint8_t val) { | ||||
|  |  | |||
|  | @ -65,6 +65,7 @@ | |||
| # define MODELM_LED_SCROLLOCK MODELM_LED3 | ||||
| # define MODELM_LED_NUMLOCK   MODELM_LED1 | ||||
| #elif defined(KEYBOARD_ibm_model_m_mschwingen_led_ws2812) | ||||
| # define WS2812_LED_COUNT 3 | ||||
| #else | ||||
| # error one of MODELM_LEDS_FFC, MODELM_LEDS_WIRED or MODELM_LEDS_WS2812 must be set! | ||||
| #endif | ||||
|  |  | |||
|  | @ -39,27 +39,10 @@ static uint8_t  isRecording = 0; | |||
| #    if RGBLIGHT_LED_COUNT < 3 | ||||
| #        error we need at least 3 RGB LEDs! | ||||
| #    endif | ||||
| static rgb_led_t led[RGBLIGHT_LED_COUNT] = {{255, 255, 255}, {255, 255, 255}, {255, 255, 255}}; | ||||
| 
 | ||||
| #    define BRIGHT 32 | ||||
| #    define DIM 6 | ||||
| 
 | ||||
| static const rgb_led_t black = {.r = 0, .g = 0, .b = 0}; | ||||
| 
 | ||||
| static const __attribute__((unused)) rgb_led_t green  = {.r = 0, .g = BRIGHT, .b = 0}; | ||||
| static const __attribute__((unused)) rgb_led_t lgreen = {.r = 0, .g = DIM, .b = 0}; | ||||
| 
 | ||||
| static const __attribute__((unused)) rgb_led_t red  = {.r = BRIGHT, .g = 0, .b = 0}; | ||||
| static const __attribute__((unused)) rgb_led_t lred = {.r = DIM, .g = 0, .b = 0}; | ||||
| 
 | ||||
| static const __attribute__((unused)) rgb_led_t blue  = {.r = 0, .g = 0, .b = BRIGHT}; | ||||
| static const __attribute__((unused)) rgb_led_t lblue = {.r = 0, .g = 0, .b = DIM}; | ||||
| 
 | ||||
| static const __attribute__((unused)) rgb_led_t turq  = {.r = 0, .g = BRIGHT, .b = BRIGHT}; | ||||
| static const __attribute__((unused)) rgb_led_t lturq = {.r = 0, .g = DIM, .b = DIM}; | ||||
| 
 | ||||
| static const __attribute__((unused)) rgb_led_t white = {.r = BRIGHT, .g = BRIGHT, .b = BRIGHT}; | ||||
| 
 | ||||
| static led_t   led_state; | ||||
| static uint8_t layer; | ||||
| static uint8_t default_layer; | ||||
|  | @ -81,17 +64,15 @@ void sleep_led_enable(void) { | |||
|     suspend_active = true; | ||||
|     gpio_write_pin_low(MODELM_STATUS_LED); | ||||
| #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812 | ||||
|     led[0] = black; | ||||
|     led[1] = black; | ||||
|     led[2] = black; | ||||
|     ws2812_setleds(led, RGBLIGHT_LED_COUNT); | ||||
|     ws2812_set_color_all(0, 0, 0); | ||||
|     ws2812_flush(); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void keyboard_pre_init_kb(void) { | ||||
| #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812 | ||||
|     ws2812_init(); | ||||
|     ws2812_setleds(led, RGBLIGHT_LED_COUNT); | ||||
|     ws2812_flush(); | ||||
| #else | ||||
|     /* Set status LEDs pins to output and Low (on) */ | ||||
|     gpio_set_pin_output(MODELM_LED_CAPSLOCK); | ||||
|  | @ -121,35 +102,59 @@ void keyboard_pre_init_kb(void) { | |||
| #ifdef KEYBOARD_ibm_model_m_mschwingen_led_ws2812 | ||||
| static void led_update_rgb(void) { | ||||
|     if (isRecording && blink_state) { | ||||
|         led[0] = white; | ||||
|         ws2812_set_color(0, BRIGHT, BRIGHT, BRIGHT); | ||||
|     } else { | ||||
|         switch (default_layer) { | ||||
|             case 0: | ||||
|                 led[0] = led_state.num_lock ? blue : lblue; | ||||
|                 if (led_state.num_lock) { | ||||
|                     ws2812_set_color(0, 0, 0, BRIGHT); | ||||
|                 } else { | ||||
|                     ws2812_set_color(0, 0, 0, DIM); | ||||
|                 } | ||||
|                 break; | ||||
|             case 1: | ||||
|                 led[0] = led_state.num_lock ? green : black; | ||||
|                 if (led_state.num_lock) { | ||||
|                     ws2812_set_color(0, 0, BRIGHT, 0); | ||||
|                 } else { | ||||
|                     ws2812_set_color(0, 0, 0, 0); | ||||
|                 } | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     led[1] = led_state.caps_lock ? green : black; | ||||
|     if (led_state.caps_lock) { | ||||
|         ws2812_set_color(1, 0, BRIGHT, 0); | ||||
|     } else { | ||||
|         ws2812_set_color(1, 0, 0, 0); | ||||
|     } | ||||
| 
 | ||||
|     switch (layer) { | ||||
|         case 0: | ||||
|         case 1: | ||||
|         default: | ||||
|             led[2] = led_state.scroll_lock ? green : black; | ||||
|             if (led_state.scroll_lock) { | ||||
|                 ws2812_set_color(2, 0, BRIGHT, 0); | ||||
|             } else { | ||||
|                 ws2812_set_color(2, 0, 0, 0); | ||||
|             } | ||||
|             break; | ||||
|         case 2: | ||||
|             led[2] = led_state.scroll_lock ? red : lred; | ||||
|             if (led_state.scroll_lock) { | ||||
|                 ws2812_set_color(2, BRIGHT, 0, 0); | ||||
|             } else { | ||||
|                 ws2812_set_color(2, DIM, 0, 0); | ||||
|             } | ||||
|             break; | ||||
|         case 3: | ||||
|             led[2] = led_state.scroll_lock ? turq : lturq; | ||||
|             if (led_state.scroll_lock) { | ||||
|                 ws2812_set_color(2, 0, BRIGHT, BRIGHT); | ||||
|             } else { | ||||
|                 ws2812_set_color(2, 0, DIM, DIM); | ||||
|             } | ||||
|             break; | ||||
|     } | ||||
|     if (!suspend_active) { | ||||
| 	ws2812_setleds(led, RGBLIGHT_LED_COUNT); | ||||
|         ws2812_flush(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -209,6 +209,10 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = { | |||
| //                                                                       71           70           69
 | ||||
|                                                                     { 0, C3_7 }, { 0, C2_7 }, { 0, C1_7 }, | ||||
| }; | ||||
| 
 | ||||
| int led_matrix_led_index(int index) { | ||||
|     return index; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #ifdef ST7565_ENABLE | ||||
|  |  | |||
|  | @ -125,4 +125,8 @@ const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT] = { | |||
|     {0, CB7_CA1,  CB9_CA1,  CB8_CA1},  // Down
 | ||||
|     {0, CB7_CA7,  CB9_CA7,  CB8_CA7},  // Right
 | ||||
| }; | ||||
| 
 | ||||
| int rgb_matrix_led_index(int index) { | ||||
|     return index; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -126,4 +126,8 @@ const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT] = { | |||
|     {0, CB7_CA1,  CB9_CA1,  CB8_CA1},  // Down
 | ||||
|     {0, CB7_CA7,  CB9_CA7,  CB8_CA7},  // Right
 | ||||
| }; | ||||
| 
 | ||||
| int rgb_matrix_led_index(int index) { | ||||
|     return index; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -25,9 +25,9 @@ | |||
| // Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
 | ||||
| // don't use those LEDs in RGB Matrix in that case.
 | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
| #    define WS2812_LED_TOTAL 0 | ||||
| #    define WS2812_LED_COUNT 0 | ||||
| #else | ||||
| #    define WS2812_LED_TOTAL 6 | ||||
| #    define WS2812_LED_COUNT 6 | ||||
| #endif | ||||
| 
 | ||||
| #define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_TOTAL) | ||||
| #define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_COUNT) | ||||
|  |  | |||
|  | @ -110,7 +110,7 @@ led_config_t g_led_config = { | |||
|     {  18,  48 }, {  30,  48 }, {  45,  48 }, {  60,  48 }, {  75,  48 }, {  90,  48 }, { 105,  48 }, { 120,  48 }, { 135,  48 }, { 150,  48 }, { 165,  48 }, { 191,  48 }, { 210,  48 }, | ||||
|     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
 | ||||
|     {   3,  64 }, {  22,  64 }, {  33,  64 }, { 101,  64 }, { 135,  64 }, { 153,  64 }, { 195,  64 }, { 210,  64 }, { 225,  64 } | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|         ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40} | ||||
| #    endif | ||||
| }, { | ||||
|  | @ -124,7 +124,7 @@ led_config_t g_led_config = { | |||
|     1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, | ||||
|     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
 | ||||
|     1, 1, 1, 4, 1, 1, 1, 1, 1 | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|         ,2, 2, 2, 2, 2, 2 | ||||
| #    endif | ||||
|     } | ||||
|  | @ -147,10 +147,6 @@ bool rgb_matrix_indicators_kb(void) { | |||
| // Custom RGB Matrix driver that combines IS31FL3733 and WS2812
 | ||||
| // ==========================================================================
 | ||||
| 
 | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
| rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL]; | ||||
| #    endif | ||||
| 
 | ||||
| static void rgb_matrix_driver_init(void) { | ||||
|     i2c_init(); | ||||
|     is31fl3733_init(0); | ||||
|  | @ -164,31 +160,25 @@ static void rgb_matrix_driver_init(void) { | |||
| 
 | ||||
| static void rgb_matrix_driver_flush(void) { | ||||
|     is31fl3733_update_pwm_buffers(0); | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
|     ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL); | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|     ws2812_flush(); | ||||
| #    endif | ||||
| } | ||||
| 
 | ||||
| static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index < IS31FL3733_LED_COUNT) { | ||||
|         is31fl3733_set_color(index, red, green, blue); | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|     } else { | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].r = red; | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].g = green; | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].b = blue; | ||||
|         ws2812_set_color(index - IS31FL3733_LED_COUNT, red, green, blue); | ||||
| #    endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     is31fl3733_set_color_all(red, green, blue); | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
|     for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { | ||||
|         rgb_matrix_ws2812_array[i].r = red; | ||||
|         rgb_matrix_ws2812_array[i].g = green; | ||||
|         rgb_matrix_ws2812_array[i].b = blue; | ||||
|     } | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|         ws2812_set_color_all(red, green, blue); | ||||
| #    endif | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,9 +23,9 @@ | |||
| // Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
 | ||||
| // don't use those LEDs in RGB Matrix in that case.
 | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
| #    define WS2812_LED_TOTAL 0 | ||||
| #    define WS2812_LED_COUNT 0 | ||||
| #else | ||||
| #    define WS2812_LED_TOTAL 6 | ||||
| #    define WS2812_LED_COUNT 6 | ||||
| #endif | ||||
| 
 | ||||
| #define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_TOTAL) | ||||
| #define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_COUNT) | ||||
|  |  | |||
|  | @ -112,7 +112,7 @@ led_config_t g_led_config = { { | |||
|     {   3,  48 }, {  22,  48 }, {  33,  48 }, {  48,  48 }, {  63,  48 }, {  78,  48 }, {  93,  48 }, { 108,  48 }, { 123,  48 }, { 138,  48 }, { 153,  48 }, { 168,  48 }, { 194,  48 }, { 213,  48 }, | ||||
|     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
 | ||||
|     {   3,  64 }, {  22,  64 }, {  33,  64 }, { 101,  64 }, { 135,  64 }, { 153,  64 }, { 195,  64 }, { 210,  64 }, { 225,  64 } | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|         ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40} | ||||
| #    endif | ||||
| }, { | ||||
|  | @ -126,7 +126,7 @@ led_config_t g_led_config = { { | |||
|     1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, | ||||
|     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
 | ||||
|     1, 1, 1, 4, 1, 1, 1, 1, 1 | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|         ,2, 2, 2, 2, 2, 2 | ||||
| #    endif | ||||
| } }; | ||||
|  | @ -147,10 +147,6 @@ bool rgb_matrix_indicators_kb(void) { | |||
| // Custom RGB Matrix driver that combines IS31FL3733 and WS2812
 | ||||
| // ==========================================================================
 | ||||
| 
 | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
| rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL]; | ||||
| #    endif | ||||
| 
 | ||||
| static void rgb_matrix_driver_init(void) { | ||||
|     i2c_init(); | ||||
|     is31fl3733_init(0); | ||||
|  | @ -164,31 +160,25 @@ static void rgb_matrix_driver_init(void) { | |||
| 
 | ||||
| static void rgb_matrix_driver_flush(void) { | ||||
|     is31fl3733_update_pwm_buffers(0); | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
|     ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL); | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|     ws2812_flush(); | ||||
| #    endif | ||||
| } | ||||
| 
 | ||||
| static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index < IS31FL3733_LED_COUNT) { | ||||
|         is31fl3733_set_color(index, red, green, blue); | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|     } else { | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].r = red; | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].g = green; | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].b = blue; | ||||
|         ws2812_set_color(index - IS31FL3733_LED_COUNT, red, green, blue); | ||||
| #    endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     is31fl3733_set_color_all(red, green, blue); | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
|     for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { | ||||
|         rgb_matrix_ws2812_array[i].r = red; | ||||
|         rgb_matrix_ws2812_array[i].g = green; | ||||
|         rgb_matrix_ws2812_array[i].b = blue; | ||||
|     } | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|     ws2812_set_color_all(red, green, blue); | ||||
| #    endif | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,9 +21,9 @@ | |||
| // Underglow LEDs are WS2812, but someone might want to use RGBLIGHT for them;
 | ||||
| // don't use those LEDs in RGB Matrix in that case.
 | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
| #    define WS2812_LED_TOTAL 0 | ||||
| #    define WS2812_LED_COUNT 0 | ||||
| #else | ||||
| #    define WS2812_LED_TOTAL 6 | ||||
| #    define WS2812_LED_COUNT 6 | ||||
| #endif | ||||
| 
 | ||||
| #define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_TOTAL) | ||||
| #define RGB_MATRIX_LED_COUNT (IS31FL3733_LED_COUNT + WS2812_LED_COUNT) | ||||
|  |  | |||
|  | @ -107,7 +107,7 @@ led_config_t g_led_config = { | |||
|     {  18,  48 }, {  30,  48 }, {  45,  48 }, {  60,  48 }, {  75,  48 }, {  90,  48 }, { 105,  48 }, { 120,  48 }, { 135,  48 }, { 150,  48 }, { 165,  48 }, { 191,  48 }, | ||||
|     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
 | ||||
|     {   3,  64 }, {  22,  64 }, {  33,  64 }, { 101,  64 }, { 135,  64 }, { 153,  64 }, { 210,  64 }, { 225,  64 } | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|         ,{ 28, 40}, { 62, 40}, { 96, 40}, {130, 40}, {164, 40}, {198, 40} | ||||
| #    endif | ||||
| }, { | ||||
|  | @ -121,7 +121,7 @@ led_config_t g_led_config = { | |||
|     1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, | ||||
|     // Ctrl, GUI, Alt, Space, RAlt, FN, Left, Down, Right
 | ||||
|     1, 1, 1, 4, 1, 1, 1, 1 | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|         ,2, 2, 2, 2, 2, 2 | ||||
| #    endif | ||||
|     } | ||||
|  | @ -143,10 +143,6 @@ bool rgb_matrix_indicators_kb(void) { | |||
| // Custom RGB Matrix driver that combines IS31FL3733 and WS2812
 | ||||
| // ==========================================================================
 | ||||
| 
 | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
| rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL]; | ||||
| #    endif | ||||
| 
 | ||||
| static void rgb_matrix_driver_init(void) { | ||||
|     i2c_init(); | ||||
|     is31fl3733_init(0); | ||||
|  | @ -160,31 +156,25 @@ static void rgb_matrix_driver_init(void) { | |||
| 
 | ||||
| static void rgb_matrix_driver_flush(void) { | ||||
|     is31fl3733_update_pwm_buffers(0); | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
|     ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL); | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|     ws2812_flush(); | ||||
| #    endif | ||||
| } | ||||
| 
 | ||||
| static void rgb_matrix_driver_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index < IS31FL3733_LED_COUNT) { | ||||
|         is31fl3733_set_color(index, red, green, blue); | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|     } else { | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].r = red; | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].g = green; | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3733_LED_COUNT].b = blue; | ||||
|         ws2812_set_color(index - IS31FL3733_LED_COUNT, red, green, blue); | ||||
| #    endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void rgb_matrix_driver_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     is31fl3733_set_color_all(red, green, blue); | ||||
| #    if WS2812_LED_TOTAL > 0 | ||||
|     for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { | ||||
|         rgb_matrix_ws2812_array[i].r = red; | ||||
|         rgb_matrix_ws2812_array[i].g = green; | ||||
|         rgb_matrix_ws2812_array[i].b = blue; | ||||
|     } | ||||
| #    if WS2812_LED_COUNT > 0 | ||||
|     ws2812_set_color_all(red, green, blue); | ||||
| #    endif | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -41,20 +41,6 @@ uint8_t read_pin(uint16_t pin) | |||
|     return (data & (1<<GET_PIN(pin))) ? 1 : 0; | ||||
| } | ||||
| 
 | ||||
| void matrix_init_kb(void) { | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
|     aw9523b_init(AW9523B_ADDR); | ||||
| #endif | ||||
|     matrix_init_user(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void housekeeping_task_kb(void) { | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
|     aw9523b_update_pwm_buffers(AW9523B_ADDR); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
| #include "rgblight.h" | ||||
| #include "ws2812.h" | ||||
|  | @ -67,20 +53,35 @@ const aw9523b_led g_aw9523b_leds[AW9523B_RGB_NUM] = { | |||
|     {AW9523B_P07_PWM, AW9523B_P06_PWM, AW9523B_P05_PWM}, | ||||
| }; | ||||
| 
 | ||||
| void setleds_custom(rgb_led_t *start_led, uint16_t num_leds) | ||||
| { | ||||
|     uint8_t num = num_leds < AW9523B_RGB_NUM ? num_leds : AW9523B_RGB_NUM; | ||||
| void init_custom(void) { | ||||
|     aw9523b_init(AW9523B_ADDR); | ||||
|     ws2812_init(); | ||||
| } | ||||
| 
 | ||||
|     ws2812_setleds(start_led, num); | ||||
| 
 | ||||
|     for (int i = 0; i < num; i++) { | ||||
|         aw9523b_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b); | ||||
| void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index < AW9523B_RGB_NUM) { | ||||
|         aw9523b_set_color(index, red, green, blue); | ||||
|     } else { | ||||
|         ws2812_set_color(index - AW9523B_RGB_NUM, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) { | ||||
|         set_color_custom(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void flush_custom(void) { | ||||
|     aw9523b_update_pwm_buffers(AW9523B_ADDR); | ||||
|     ws2812_flush(); | ||||
| } | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .init    = ws2812_init, | ||||
|     .setleds = setleds_custom, | ||||
|     .init          = init_custom, | ||||
|     .set_color     = set_color_custom, | ||||
|     .set_color_all = set_color_all_custom, | ||||
|     .flush         = flush_custom, | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -89,5 +89,6 @@ | |||
| #define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2 | ||||
| 
 | ||||
| #define AW9523B_RGB_NUM 4 | ||||
| #define WS2812_LED_COUNT 5 | ||||
| 
 | ||||
| #define EARLY_INIT_PERFORM_BOOTLOADER_JUMP FALSE | ||||
|  |  | |||
|  | @ -27,13 +27,6 @@ uint8_t read_pin(uint16_t pin) | |||
|     return (data & (1<<GET_PIN(pin))) ? 1 : 0; | ||||
| } | ||||
| 
 | ||||
| void matrix_init_kb(void) { | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
|     rgb_ring_init(); | ||||
| #endif | ||||
|     matrix_init_user(); | ||||
| } | ||||
| 
 | ||||
| void housekeeping_task_kb(void) { | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
|     rgb_ring_task(); | ||||
|  |  | |||
|  | @ -361,27 +361,22 @@ static void custom_effects(void) | |||
|     effect_funcs[rgb_ring.effect](); | ||||
| } | ||||
| 
 | ||||
| void setleds_custom(rgb_led_t *start_led, uint16_t num_leds) | ||||
| { | ||||
| void flush_custom(void) { | ||||
|     if (rgb_ring.state != RING_STATE_QMK) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     for (uint8_t i = 0; i < num_leds; i++) { | ||||
|         is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b); | ||||
|     } | ||||
|     is31fl3731_flush(); | ||||
| } | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .setleds = setleds_custom, | ||||
|     .init          = is31fl3731_init_drivers, | ||||
|     .set_color     = is31fl3731_set_color, | ||||
|     .set_color_all = is31fl3731_set_color_all, | ||||
|     .flush         = flush_custom, | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| void rgb_ring_init(void) | ||||
| { | ||||
|     is31fl3731_init_drivers(); | ||||
| } | ||||
| 
 | ||||
| void rgb_ring_task(void) | ||||
| { | ||||
|     switch (rgb_ring.state) { | ||||
|  | @ -397,8 +392,6 @@ void rgb_ring_task(void) | |||
|         default: | ||||
|             break; | ||||
|     }; | ||||
| 
 | ||||
|     is31fl3731_flush(); | ||||
| } | ||||
| 
 | ||||
| bool process_record_kb(uint16_t keycode, keyrecord_t *record) | ||||
|  |  | |||
|  | @ -19,5 +19,4 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| void rgb_ring_init(void); | ||||
| void rgb_ring_task(void); | ||||
|  |  | |||
|  | @ -10,7 +10,7 @@ | |||
|     "no_startup_check": true | ||||
|   }, | ||||
|   "rgblight": { | ||||
|     "driver": "custom", | ||||
|     "driver": "ws2812", | ||||
|     "led_count": 7, | ||||
|     "animations": { | ||||
|       "breathing": true, | ||||
|  |  | |||
|  | @ -9,57 +9,6 @@ void bootloader_jump(void) { | |||
|     NVIC_SystemReset(); | ||||
| } | ||||
| 
 | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
| #include <string.h> | ||||
| #include "rgblight.h" | ||||
| #include "ws2812.h" | ||||
| extern rgblight_config_t rgblight_config; | ||||
| 
 | ||||
| // led 0 for caps lock, led 1 for scroll lock, led 3 for num lock
 | ||||
| // led 4 for layer 1, led 5 for layer 2, led 6 for layer 3, led 7 for layer 4
 | ||||
| #if RGBLIGHT_LED_COUNT < 7 | ||||
| #error "MUST set the RGBLIGHT_LED_COUNT bigger than 7" | ||||
| #endif | ||||
| rgb_led_t noah_leds[RGBLIGHT_LED_COUNT]; | ||||
| static bool noah_led_mode = false; | ||||
| void setleds_custom(rgb_led_t *ledarray, uint16_t num_leds) { | ||||
|     memset(&noah_leds[0], 0, sizeof(noah_leds)); | ||||
|     if (!rgblight_config.enable) { | ||||
|         for (uint8_t i = 0; i < RGBLIGHT_LED_COUNT; i++) { | ||||
|             ledarray[i].r = 0; | ||||
|             ledarray[i].g = 0; | ||||
|             ledarray[i].b = 0; | ||||
|         } | ||||
|     } | ||||
|     if (noah_led_mode) { | ||||
|       led_t led_state = host_keyboard_led_state(); | ||||
|       if (led_state.caps_lock) { | ||||
|         noah_leds[0] = ledarray[0]; | ||||
|       } | ||||
|       if (led_state.scroll_lock) { | ||||
|         noah_leds[1] = ledarray[1]; | ||||
|       } | ||||
|       if (led_state.num_lock) { | ||||
|         noah_leds[2] = ledarray[2]; | ||||
|       } | ||||
|       for (int32_t i = 0; i < 4; i++) { | ||||
|         if(layer_state_is(i+1)) { | ||||
|           noah_leds[i + 3] = ledarray[i + 3]; | ||||
|         } | ||||
|       } | ||||
|     } else { | ||||
|       memcpy(&noah_leds[0], &ledarray[0], sizeof(noah_leds)); | ||||
|     } | ||||
| 
 | ||||
|   ws2812_setleds(noah_leds, RGBLIGHT_LED_COUNT); | ||||
| } | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .init    = ws2812_init, | ||||
|     .setleds = setleds_custom, | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef RGB_MATRIX_ENABLE | ||||
| const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = { | ||||
| /* Refer to IS31 manual for these locations
 | ||||
|  | @ -150,11 +99,6 @@ const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = { | |||
| bool process_record_kb(uint16_t keycode, keyrecord_t *record) { | ||||
|   if (record->event.pressed) { | ||||
|     switch(keycode) { | ||||
|     #ifdef RGBLIGHT_ENABLE | ||||
|         case KC_F24: // switch the led mode on or off
 | ||||
|         noah_led_mode = !noah_led_mode; | ||||
|         return false; | ||||
| 
 | ||||
|     #ifdef RGB_MATRIX_ENABLE | ||||
|         case KC_F13: // toggle rgb matrix
 | ||||
|         rgb_matrix_toggle(); | ||||
|  | @ -162,7 +106,6 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { | |||
|         case KC_F14: | ||||
|         rgb_matrix_step(); | ||||
|         return false; | ||||
|     #endif | ||||
|     #endif | ||||
|         default: | ||||
|         break; | ||||
|  |  | |||
|  | @ -18,9 +18,11 @@ | |||
|  */ | ||||
| 
 | ||||
| #include "quantum.h" | ||||
| #include "i2c_master.h" | ||||
| #include "drivers/led/issi/is31fl3731.h" | ||||
| #include "ws2812.h" | ||||
| 
 | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
| #    include "i2c_master.h" | ||||
| #    include "drivers/led/issi/is31fl3731.h" | ||||
| #    include "ws2812.h" | ||||
| 
 | ||||
| enum { | ||||
|     SELF_TESTING, | ||||
|  | @ -67,7 +69,6 @@ enum { | |||
| #endif | ||||
| #define ST_RIGHT_END        (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1) | ||||
| 
 | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
| 
 | ||||
| typedef struct { | ||||
|     uint8_t state; | ||||
|  | @ -295,7 +296,6 @@ void matrix_init_kb(void) | |||
|     gpio_set_pin_output(LED_CAPS_LOCK_PIN); | ||||
|     gpio_write_pin_low(LED_CAPS_LOCK_PIN); | ||||
| 
 | ||||
|     is31fl3731_init_drivers(); | ||||
| 
 | ||||
|     update_ticks(); | ||||
|     matrix_init_user(); | ||||
|  | @ -313,17 +313,10 @@ void housekeeping_task_kb(void) | |||
|     } else if (rgb_state.state == CAPS_ALERT) { | ||||
|         if (rgb_state.alert) { | ||||
|             is31fl3731_set_color_all(ALERM_LED_R, ALERM_LED_G, ALERM_LED_B); | ||||
|             rgb_led_t leds[4]; | ||||
|             for (int i = 0; i < 4; i++) { | ||||
|                 leds[i].r = ALERM_LED_G; | ||||
|                 leds[i].g = ALERM_LED_R; | ||||
|                 leds[i].b = ALERM_LED_B; | ||||
|             } | ||||
|             ws2812_setleds(leds, 4); | ||||
|             ws2812_set_color_all(ALERM_LED_G, ALERM_LED_R, ALERM_LED_B); | ||||
|         } else { | ||||
|             is31fl3731_set_color_all(0, 0, 0); | ||||
|             rgb_led_t leds[4] = {0}; | ||||
|             ws2812_setleds(leds, 4); | ||||
|             ws2812_set_color_all(0, 0, 0); | ||||
|         } | ||||
| 
 | ||||
|         if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) { | ||||
|  | @ -333,28 +326,40 @@ void housekeeping_task_kb(void) | |||
|     } | ||||
| 
 | ||||
|     is31fl3731_flush(); | ||||
|     ws2812_flush(); | ||||
| } | ||||
| 
 | ||||
| void setleds_custom(rgb_led_t *start_led, uint16_t num_leds) | ||||
| { | ||||
| void init_custom(void) { | ||||
|     is31fl3731_init_drivers(); | ||||
|     ws2812_init(); | ||||
| } | ||||
| 
 | ||||
| void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index < IS31FL3731_LED_COUNT) { | ||||
|         is31fl3731_set_color(index, red, green, blue); | ||||
|     } else if (index < IS31FL3731_LED_COUNT + WS2812_LED_COUNT) { | ||||
|         ws2812_set_color(index - IS31FL3731_LED_COUNT, green, red, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) { | ||||
|         set_color_custom(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void flush_custom(void) { | ||||
|     if (rgb_state.state != NORMAL) return; | ||||
| 
 | ||||
|     for (uint8_t i = 0; i < IS31FL3731_LED_COUNT; i++) { | ||||
|         is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b); | ||||
|     } | ||||
|     rgb_led_t leds[4]; | ||||
|     for (int i = 0; i < 4; i++) { | ||||
|         leds[i].r = start_led[IS31FL3731_LED_COUNT+i].g; | ||||
|         leds[i].g = start_led[IS31FL3731_LED_COUNT+i].r; | ||||
|         leds[i].b = start_led[IS31FL3731_LED_COUNT+i].b; | ||||
|     } | ||||
|     //ws2812_setleds(start_led+IS31FL3731_LED_COUNT, 4);
 | ||||
|     ws2812_setleds(leds, 4); | ||||
|     is31fl3731_flush(); | ||||
|     ws2812_flush(); | ||||
| } | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .init    = ws2812_init, | ||||
|     .setleds = setleds_custom, | ||||
|     .init          = init_custom, | ||||
|     .set_color     = set_color_custom, | ||||
|     .set_color_all = set_color_all_custom, | ||||
|     .flush         = flush_custom, | ||||
| }; | ||||
| 
 | ||||
| bool led_update_kb(led_t led_state) | ||||
|  |  | |||
|  | @ -21,5 +21,6 @@ | |||
| #define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND | ||||
| #define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC | ||||
| #define IS31FL3731_LED_COUNT 64 | ||||
| #define WS2812_LED_COUNT 4 | ||||
| 
 | ||||
| #define USB_SUSPEND_WAKEUP_DELAY 1000 | ||||
|  |  | |||
|  | @ -21,3 +21,4 @@ | |||
| #define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND | ||||
| #define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_VCC | ||||
| #define IS31FL3731_LED_COUNT 64 | ||||
| #define WS2812_LED_COUNT 1 | ||||
|  |  | |||
|  | @ -18,9 +18,11 @@ | |||
|  */ | ||||
| 
 | ||||
| #include "quantum.h" | ||||
| #include "i2c_master.h" | ||||
| #include "drivers/led/issi/is31fl3731.h" | ||||
| #include "ws2812.h" | ||||
| 
 | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
| #    include "i2c_master.h" | ||||
| #    include "drivers/led/issi/is31fl3731.h" | ||||
| #    include "ws2812.h" | ||||
| 
 | ||||
| enum { | ||||
|     SELF_TESTING, | ||||
|  | @ -67,7 +69,6 @@ enum { | |||
| #endif | ||||
| #define ST_RIGHT_END        (ST_RIGHT_BEGIN+ST_RIGHT_SIZE-1) | ||||
| 
 | ||||
| #ifdef RGBLIGHT_ENABLE | ||||
| extern rgblight_config_t rgblight_config; | ||||
| 
 | ||||
| typedef struct { | ||||
|  | @ -299,8 +300,6 @@ void matrix_init_kb(void) | |||
|     gpio_set_pin_output(LED_CAPS_LOCK_PIN); | ||||
|     gpio_write_pin_low(LED_CAPS_LOCK_PIN); | ||||
| 
 | ||||
|     is31fl3731_init_drivers(); | ||||
| 
 | ||||
|     update_ticks(); | ||||
|     matrix_init_user(); | ||||
| } | ||||
|  | @ -310,22 +309,12 @@ void housekeeping_task_kb(void) | |||
|     if (rgb_state.state == SELF_TESTING) { | ||||
|         self_testing(); | ||||
|     } else if (rgb_state.state == CAPS_ALERT) { | ||||
|         //gold 0xFF, 0xD9, 0x00
 | ||||
|         rgb_led_t led = { | ||||
|             .r = 0xFF, | ||||
|             //.g = 0xD9,
 | ||||
|             .g = 0xA5, | ||||
|             .b = 0x00, | ||||
|         }; | ||||
|         if (rgb_state.alert) { | ||||
|             is31fl3731_set_color_all(led.r, led.g, led.b); | ||||
|             ws2812_setleds(&led, 1); | ||||
|             is31fl3731_set_color_all(0xFF, 0xA5, 0x00); | ||||
|             ws2812_set_color_all(0xFF, 0xA5, 0x00); | ||||
|         } else { | ||||
|             led.r = 0; | ||||
|             led.g = 0; | ||||
|             led.b = 0; | ||||
|             is31fl3731_set_color_all(0, 0, 0); | ||||
|             ws2812_setleds(&led, 1); | ||||
|             ws2812_set_color_all(0, 0, 0); | ||||
|         } | ||||
| 
 | ||||
|         if (timer_elapsed(rgb_state.ticks) > ALERT_INTERVAL) { | ||||
|  | @ -337,19 +326,37 @@ void housekeeping_task_kb(void) | |||
|     is31fl3731_flush(); | ||||
| } | ||||
| 
 | ||||
| void setleds_custom(rgb_led_t *start_led, uint16_t num_leds) | ||||
| { | ||||
| void init_custom(void) { | ||||
|     is31fl3731_init_drivers(); | ||||
|     ws2812_init(); | ||||
| } | ||||
| 
 | ||||
| void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index < IS31FL3731_LED_COUNT) { | ||||
|         is31fl3731_set_color(index, red, green, blue); | ||||
|     } else if (index < IS31FL3731_LED_COUNT + WS2812_LED_COUNT) { | ||||
|         ws2812_set_color(index - IS31FL3731_LED_COUNT, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) { | ||||
|         set_color_custom(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void flush_custom(void) { | ||||
|     if (rgb_state.state != NORMAL) return; | ||||
| 
 | ||||
|     for (uint8_t i = 0; i < IS31FL3731_LED_COUNT; i++) { | ||||
|         is31fl3731_set_color(i, start_led[i].r, start_led[i].g, start_led[i].b); | ||||
|     } | ||||
|     ws2812_setleds(start_led+IS31FL3731_LED_COUNT, 1); | ||||
|     is31fl3731_flush(); | ||||
|     ws2812_flush(); | ||||
| } | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .init    = ws2812_init, | ||||
|     .setleds = setleds_custom, | ||||
|     .init          = init_custom, | ||||
|     .set_color     = set_color_custom, | ||||
|     .set_color_all = set_color_all_custom, | ||||
|     .flush         = flush_custom, | ||||
| }; | ||||
| 
 | ||||
| bool led_update_kb(led_t led_state) | ||||
|  |  | |||
|  | @ -17,12 +17,25 @@ | |||
| #    define WS2812_I2C_TIMEOUT 100 | ||||
| #endif | ||||
| 
 | ||||
| ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; | ||||
| 
 | ||||
| void ws2812_init(void) { | ||||
|     i2c_init(); | ||||
| } | ||||
| 
 | ||||
| // Setleds for standard RGB
 | ||||
| void ws2812_setleds(rgb_led_t *ledarray, uint16_t leds) { | ||||
|     i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ledarray, sizeof(rgb_led_t) * (leds >> 1), WS2812_I2C_TIMEOUT); | ||||
|     i2c_transmit(WS2812_I2C_ADDRESS_RIGHT, (uint8_t *)ledarray+(sizeof(rgb_led_t) * (leds >> 1)), sizeof(rgb_led_t) * (leds - (leds >> 1)), WS2812_I2C_TIMEOUT); | ||||
| void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     ws2812_leds[index].r = red; | ||||
|     ws2812_leds[index].g = green; | ||||
|     ws2812_leds[index].b = blue; | ||||
| } | ||||
| 
 | ||||
| void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         ws2812_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ws2812_flush(void) { | ||||
|     i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ws2812_leds, sizeof(ws2812_led_t) * (WS2812_LED_COUNT >> 1), WS2812_I2C_TIMEOUT); | ||||
|     i2c_transmit(WS2812_I2C_ADDRESS_RIGHT, (uint8_t *)ws2812_leds + (sizeof(ws2812_led_t) * (WS2812_LED_COUNT >> 1)), sizeof(ws2812_led_t) * (WS2812_LED_COUNT - (WS2812_LED_COUNT >> 1)), WS2812_I2C_TIMEOUT); | ||||
| } | ||||
|  |  | |||
|  | @ -125,4 +125,7 @@ const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT] = { | |||
| {0, SW7_CS7, SW8_CS7, SW9_CS7} | ||||
| }; | ||||
| 
 | ||||
| int rgb_matrix_led_index(int index) { | ||||
|     return index; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -17,3 +17,4 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #pragma once | ||||
| 
 | ||||
| #define RGB_MATRIX_LED_COUNT 64 | ||||
| #define WS2812_LED_COUNT 64 | ||||
|  |  | |||
|  | @ -21,43 +21,23 @@ | |||
| #    if defined(KEYBOARD_rgbkb_pan_rev1) | ||||
| #        include "ws2812.h" | ||||
| 
 | ||||
| // LED color buffer
 | ||||
| rgb_led_t rgb_matrix_ws2812_array[RGB_MATRIX_LED_COUNT]; | ||||
| 
 | ||||
| static void flush(void) { | ||||
|     ws2812_setleds(rgb_matrix_ws2812_array, RGB_MATRIX_LED_COUNT); | ||||
| } | ||||
| 
 | ||||
| // Set an led in the buffer to a color
 | ||||
| static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) { | ||||
| #        if defined(RGB_ENCODERS) || defined(STAGGERED_RGB_ENCODERS) | ||||
|     if (i == 0 || i == 1) {  // if encoder LEDs, change LEDs
 | ||||
|         rgb_matrix_ws2812_array[i].r = g; | ||||
|         rgb_matrix_ws2812_array[i].g = b; | ||||
|         rgb_matrix_ws2812_array[i].b = r; | ||||
|         ws2812_set_color(i, g, b, r); | ||||
|     } else | ||||
| #        endif | ||||
|     { | ||||
|         rgb_matrix_ws2812_array[i].r = r; | ||||
|         rgb_matrix_ws2812_array[i].g = g; | ||||
|         rgb_matrix_ws2812_array[i].b = b; | ||||
|     } | ||||
| #        ifdef WS2812_RGBW | ||||
|     convert_rgb_to_rgbw(&rgb_matrix_ws2812_array[i]); | ||||
| #        endif | ||||
| } | ||||
| 
 | ||||
| static void setled_all(uint8_t r, uint8_t g, uint8_t b) { | ||||
|     for (int i = 0; i < ARRAY_SIZE(rgb_matrix_ws2812_array); i++) { | ||||
|         setled(i, r, g, b); | ||||
|         ws2812_set_color(i, r, g, b); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const rgb_matrix_driver_t rgb_matrix_driver = { | ||||
|     .init          = ws2812_init, | ||||
|     .flush         = flush, | ||||
|     .flush         = ws2812_flush, | ||||
|     .set_color     = setled, | ||||
|     .set_color_all = setled_all, | ||||
|     .set_color_all = ws2812_set_color_all, | ||||
| }; | ||||
| #    endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,35 +1,20 @@ | |||
| // Copyright 2024 Dasky (@daskygit)
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include "quantum.h" | ||||
| #include <hal.h> | ||||
| #include "chibios_config.h" | ||||
| #include "gpio.h" | ||||
| #include "color.h" | ||||
| #include "rgblight_drivers.h" | ||||
| 
 | ||||
| static PWMConfig pwmCFG = { | ||||
|     .frequency = 0xFFFF, | ||||
|     .period    = 256, | ||||
| }; | ||||
| 
 | ||||
| void prime_setleds(rgb_led_t *start_led, uint16_t num_leds) { | ||||
|     if (start_led[0].r == 0) { | ||||
|         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1); | ||||
|     } else { | ||||
|         uint32_t duty = ((uint32_t)0xFFFF * start_led[0].r) / 0xFF; | ||||
|         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty)); | ||||
|     } | ||||
|     if (start_led[0].g == 0) { | ||||
|         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1); | ||||
|     } else { | ||||
|         uint32_t duty = ((uint32_t)0xFFFF * start_led[0].g) / 0xFF; | ||||
|         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty)); | ||||
|     } | ||||
|     if (start_led[0].b == 0) { | ||||
|         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1); | ||||
|     } else { | ||||
|         uint32_t duty = ((uint32_t)0xFFFF * start_led[0].b) / 0xFF; | ||||
|         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty)); | ||||
|     } | ||||
| } | ||||
| rgb_led_t prime_leds[RGBLIGHT_LED_COUNT]; | ||||
| 
 | ||||
| void prime_initleds(void) { | ||||
| void init_custom(void) { | ||||
|     palSetPadMode(PAL_PORT(RGB_RED_PIN), PAL_PAD(RGB_RED_PIN), PAL_MODE_ALTERNATE_PUSHPULL); | ||||
|     palSetPadMode(PAL_PORT(RGB_GREEN_PIN), PAL_PAD(RGB_GREEN_PIN), PAL_MODE_ALTERNATE_PUSHPULL); | ||||
|     palSetPadMode(PAL_PORT(RGB_BLUE_PIN), PAL_PAD(RGB_BLUE_PIN), PAL_MODE_ALTERNATE_PUSHPULL); | ||||
|  | @ -39,7 +24,42 @@ void prime_initleds(void) { | |||
|     pwmStart(&RGB_PWM_DRIVER, &pwmCFG); | ||||
| } | ||||
| 
 | ||||
| void set_color_custom(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     prime_leds[index].r = red; | ||||
|     prime_leds[index].g = green; | ||||
|     prime_leds[index].b = blue; | ||||
| } | ||||
| 
 | ||||
| void set_color_all_custom(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < RGBLIGHT_LED_COUNT; i++) { | ||||
|         set_color_custom(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void flush_custom(void) { | ||||
|     if (prime_leds[0].r == 0) { | ||||
|         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1); | ||||
|     } else { | ||||
|         uint32_t duty = ((uint32_t)0xFFFF * prime_leds[0].r) / 0xFF; | ||||
|         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty)); | ||||
|     } | ||||
|     if (prime_leds[0].g == 0) { | ||||
|         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1); | ||||
|     } else { | ||||
|         uint32_t duty = ((uint32_t)0xFFFF * prime_leds[0].g) / 0xFF; | ||||
|         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty)); | ||||
|     } | ||||
|     if (prime_leds[0].b == 0) { | ||||
|         pwmDisableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1); | ||||
|     } else { | ||||
|         uint32_t duty = ((uint32_t)0xFFFF * prime_leds[0].b) / 0xFF; | ||||
|         pwmEnableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .init    = prime_initleds, | ||||
|     .setleds = prime_setleds, | ||||
|     .init          = init_custom, | ||||
|     .set_color     = set_color_custom, | ||||
|     .set_color_all = set_color_all_custom, | ||||
|     .flush         = flush_custom, | ||||
| }; | ||||
|  |  | |||
|  | @ -60,7 +60,6 @@ | |||
| 
 | ||||
| #if defined(RGB_BACKLIGHT_DAWN60) | ||||
| #include "ws2812.h" | ||||
| rgb_led_t g_ws2812_leds[WS2812_LED_TOTAL]; | ||||
| #endif | ||||
| 
 | ||||
| #include "progmem.h" | ||||
|  | @ -1011,6 +1010,9 @@ void backlight_update_pwm_buffers(void) | |||
|         driver = 0; | ||||
|     } | ||||
| #else | ||||
| #if defined(RGB_BACKLIGHT_DAWN60) | ||||
|     ws2812_flush(); | ||||
| #endif | ||||
|     is31fl3731_update_pwm_buffers( 0 ); | ||||
|     is31fl3731_update_pwm_buffers( 1 ); | ||||
|     is31fl3731_update_led_control_registers( 0 ); | ||||
|  | @ -1037,10 +1039,7 @@ void backlight_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) | |||
|     if( index < IS31FL3731_LED_COUNT ) { | ||||
|         is31fl3731_set_color( index, red, green, blue ); | ||||
|     } else { | ||||
|         g_ws2812_leds[index - IS31FL3731_LED_COUNT].r = red; | ||||
|         g_ws2812_leds[index - IS31FL3731_LED_COUNT].g = green; | ||||
|         g_ws2812_leds[index - IS31FL3731_LED_COUNT].b = blue; | ||||
|         ws2812_setleds(g_ws2812_leds, WS2812_LED_TOTAL); | ||||
|         ws2812_set_color( index - IS31FL3731_LED_COUNT, red, green, blue ); | ||||
|     } | ||||
| #else | ||||
|     is31fl3731_set_color( index, red, green, blue ); | ||||
|  | @ -1075,12 +1074,7 @@ void backlight_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) | |||
|     } | ||||
| #elif defined(RGB_BACKLIGHT_DAWN60) | ||||
|     is31fl3731_set_color_all( red, green, blue ); | ||||
|     for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { | ||||
|         g_ws2812_leds[i].r = red; | ||||
|         g_ws2812_leds[i].g = green; | ||||
|         g_ws2812_leds[i].b = blue; | ||||
|     } | ||||
|     ws2812_setleds(g_ws2812_leds, WS2812_LED_TOTAL); | ||||
|     ws2812_set_color_all( red, green, blue ); | ||||
| #else | ||||
|     is31fl3731_set_color_all( red, green, blue ); | ||||
| #endif | ||||
|  | @ -1325,7 +1319,7 @@ void backlight_effect_alphas_mods(void) | |||
|         } | ||||
|     } | ||||
| #if defined(RGB_BACKLIGHT_DAWN60) | ||||
|     for (int i = 0; i < WS2812_LED_TOTAL; i++) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         if ((RGB_UNDERGLOW_ALPHA_TOP_START <= i && i <= RGB_UNDERGLOW_ALPHA_TOP_END) || | ||||
|             (RGB_UNDERGLOW_ALPHA_BOT_START <= i && i <= RGB_UNDERGLOW_ALPHA_BOT_END)) { | ||||
|             backlight_set_color(i + IS31FL3731_LED_COUNT, rgb1.r, rgb1.g, rgb1.b); | ||||
|  |  | |||
|  | @ -26,13 +26,17 @@ | |||
| #define WS2812_DI_PIN RGBLIGHT_DI_PIN | ||||
| 
 | ||||
| #define ws2812_init ws2812_rgb_init | ||||
| #define ws2812_setleds ws2812_rgb_setleds | ||||
| #define ws2812_set_color ws2812_rgb_set_color | ||||
| #define ws2812_set_color_all ws2812_rgb_set_color_all | ||||
| #define ws2812_flush ws2812_rgb_flush | ||||
| 
 | ||||
| #include "ws2812_bitbang.c" | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .init    = ws2812_init, | ||||
|     .setleds = ws2812_setleds, | ||||
|     .init          = ws2812_init, | ||||
|     .set_color     = ws2812_set_color, | ||||
|     .set_color_all = ws2812_set_color_all, | ||||
|     .flush         = ws2812_flush, | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -42,7 +42,7 @@ | |||
| #define RGB_BACKLIGHT_DAWN60 | ||||
| 
 | ||||
| //RGB Underglow defines
 | ||||
| #define WS2812_LED_TOTAL 20 | ||||
| #define WS2812_LED_COUNT 20 | ||||
| 
 | ||||
| #define RGB_UNDERGLOW_ALPHA_TOP_START 0 | ||||
| #define RGB_UNDERGLOW_ALPHA_TOP_END   6    | ||||
|  |  | |||
|  | @ -16,14 +16,14 @@ | |||
| #pragma once | ||||
| 
 | ||||
| //RGB Underglow defines
 | ||||
| #define WS2812_LED_TOTAL 20 | ||||
| #define WS2812_LED_COUNT 20 | ||||
| 
 | ||||
| //RGB Matrix defines
 | ||||
| #define IS31FL3731_I2C_ADDRESS_1 IS31FL3731_I2C_ADDRESS_GND | ||||
| #define IS31FL3731_I2C_ADDRESS_2 IS31FL3731_I2C_ADDRESS_SDA | ||||
| #define IS31FL3731_LED_COUNT 64 | ||||
| 
 | ||||
| #define RGB_MATRIX_LED_COUNT (IS31FL3731_LED_COUNT + WS2812_LED_TOTAL) | ||||
| #define RGB_MATRIX_LED_COUNT (IS31FL3731_LED_COUNT + WS2812_LED_COUNT) | ||||
| 
 | ||||
| // enable/disable LEDs based on layout
 | ||||
| // switch between split backspace (1) or normal backspace(0)
 | ||||
|  |  | |||
|  | @ -23,8 +23,6 @@ | |||
| #include "ws2812.h" | ||||
| 
 | ||||
| #ifdef RGB_MATRIX_ENABLE | ||||
| rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_TOTAL]; | ||||
| 
 | ||||
| const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT] = { | ||||
| /* Refer to IS31 manual for these locations
 | ||||
|  *   driver | ||||
|  | @ -161,26 +159,20 @@ static void init(void) { | |||
| static void flush(void) { | ||||
|     is31fl3731_update_pwm_buffers(0); | ||||
|     is31fl3731_update_pwm_buffers(1); | ||||
|     ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_TOTAL); | ||||
|     ws2812_flush(); | ||||
| } | ||||
| 
 | ||||
| static void set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     if (index < IS31FL3731_LED_COUNT) { | ||||
|         is31fl3731_set_color(index, red, green, blue); | ||||
|     } else { | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3731_LED_COUNT].r = red; | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3731_LED_COUNT].g = green; | ||||
|         rgb_matrix_ws2812_array[index - IS31FL3731_LED_COUNT].b = blue; | ||||
|         ws2812_set_color(index - IS31FL3731_LED_COUNT, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     is31fl3731_set_color_all( red, green, blue ); | ||||
|     for (uint8_t i = 0; i < WS2812_LED_TOTAL; i++) { | ||||
|         rgb_matrix_ws2812_array[i].r = red; | ||||
|         rgb_matrix_ws2812_array[i].g = green; | ||||
|         rgb_matrix_ws2812_array[i].b = blue; | ||||
|     } | ||||
|     ws2812_set_color_all( red, green, blue ); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										3
									
								
								keyboards/xiudi/xd002/keymaps/rgb_lite/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								keyboards/xiudi/xd002/keymaps/rgb_lite/config.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #define WS2812_LED_COUNT 2 | ||||
|  | @ -7,9 +7,9 @@ static inline void rgblite_init(void) { | |||
|     ws2812_init(); | ||||
| } | ||||
| 
 | ||||
| static inline void rgblite_setrgb(uint8_t _r, uint8_t _g, uint8_t _b) { | ||||
|     rgb_led_t leds[RGBLIGHT_LED_COUNT] = {{.r = _r, .g = _g, .b = _b}, {.r = _r, .g = _g, .b = _b}}; | ||||
|     ws2812_setleds(leds, RGBLIGHT_LED_COUNT); | ||||
| static inline void rgblite_setrgb(uint8_t r, uint8_t g, uint8_t b) { | ||||
|     ws2812_set_color_all(r, g, b); | ||||
|     ws2812_flush(); | ||||
| } | ||||
| 
 | ||||
| static void rgblite_increase_hue(void) { | ||||
|  |  | |||
|  | @ -28,28 +28,6 @@ | |||
| 
 | ||||
| #define pinmask(pin) (_BV((pin)&0xF)) | ||||
| 
 | ||||
| /*
 | ||||
|  * Forward declare internal functions | ||||
|  * | ||||
|  * The functions take a byte-array and send to the data output as WS2812 bitstream. | ||||
|  * The length is the number of bytes to send - three per LED. | ||||
|  */ | ||||
| 
 | ||||
| static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t masklo, uint8_t maskhi); | ||||
| 
 | ||||
| void ws2812_init(void) { | ||||
|     DDRx_ADDRESS(WS2812_DI_PIN) |= pinmask(WS2812_DI_PIN); | ||||
| } | ||||
| 
 | ||||
| void ws2812_setleds(rgb_led_t *ledarray, uint16_t number_of_leds) { | ||||
|     uint8_t masklo = ~(pinmask(WS2812_DI_PIN)) & PORTx_ADDRESS(WS2812_DI_PIN); | ||||
|     uint8_t maskhi = pinmask(WS2812_DI_PIN) | PORTx_ADDRESS(WS2812_DI_PIN); | ||||
| 
 | ||||
|     ws2812_sendarray_mask((uint8_t *)ledarray, number_of_leds * sizeof(rgb_led_t), masklo, maskhi); | ||||
| 
 | ||||
|     _delay_us(WS2812_TRST_US); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|   This routine writes an array of bytes with RGB values to the Dataout pin | ||||
|   using the fast 800kHz clockless WS2811/2812 protocol. | ||||
|  | @ -172,3 +150,33 @@ static inline void ws2812_sendarray_mask(uint8_t *data, uint16_t datlen, uint8_t | |||
| 
 | ||||
|     SREG = sreg_prev; | ||||
| } | ||||
| 
 | ||||
| ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; | ||||
| 
 | ||||
| void ws2812_init(void) { | ||||
|     DDRx_ADDRESS(WS2812_DI_PIN) |= pinmask(WS2812_DI_PIN); | ||||
| } | ||||
| 
 | ||||
| void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     ws2812_leds[index].r = red; | ||||
|     ws2812_leds[index].g = green; | ||||
|     ws2812_leds[index].b = blue; | ||||
| #if defined(WS2812_RGBW) | ||||
|     ws2812_rgb_to_rgbw(&ws2812_leds[index]); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         ws2812_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ws2812_flush(void) { | ||||
|     uint8_t masklo = ~(pinmask(WS2812_DI_PIN)) & PORTx_ADDRESS(WS2812_DI_PIN); | ||||
|     uint8_t maskhi = pinmask(WS2812_DI_PIN) | PORTx_ADDRESS(WS2812_DI_PIN); | ||||
| 
 | ||||
|     ws2812_sendarray_mask((uint8_t *)ws2812_leds, WS2812_LED_COUNT * sizeof(ws2812_led_t), masklo, maskhi); | ||||
| 
 | ||||
|     _delay_us(WS2812_TRST_US); | ||||
| } | ||||
|  |  | |||
|  | @ -1,3 +1,6 @@ | |||
| // Copyright 2024 QMK
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include "ws2812.h" | ||||
| #include "i2c_master.h" | ||||
| 
 | ||||
|  | @ -13,11 +16,24 @@ | |||
| #    define WS2812_I2C_TIMEOUT 100 | ||||
| #endif | ||||
| 
 | ||||
| ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; | ||||
| 
 | ||||
| void ws2812_init(void) { | ||||
|     i2c_init(); | ||||
| } | ||||
| 
 | ||||
| // Setleds for standard RGB
 | ||||
| void ws2812_setleds(rgb_led_t *ledarray, uint16_t leds) { | ||||
|     i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ledarray, sizeof(rgb_led_t) * leds, WS2812_I2C_TIMEOUT); | ||||
| void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     ws2812_leds[index].r = red; | ||||
|     ws2812_leds[index].g = green; | ||||
|     ws2812_leds[index].b = blue; | ||||
| } | ||||
| 
 | ||||
| void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         ws2812_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ws2812_flush(void) { | ||||
|     i2c_transmit(WS2812_I2C_ADDRESS, (uint8_t *)ws2812_leds, WS2812_LED_COUNT * sizeof(ws2812_led_t), WS2812_I2C_TIMEOUT); | ||||
| } | ||||
|  |  | |||
|  | @ -266,19 +266,36 @@ static inline void sync_ws2812_transfer(void) { | |||
|     busy_wait_until(LAST_TRANSFER); | ||||
| } | ||||
| 
 | ||||
| void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) { | ||||
| ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; | ||||
| 
 | ||||
| void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     ws2812_leds[index].r = red; | ||||
|     ws2812_leds[index].g = green; | ||||
|     ws2812_leds[index].b = blue; | ||||
| #if defined(WS2812_RGBW) | ||||
|     ws2812_rgb_to_rgbw(&ws2812_leds[index]); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         ws2812_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ws2812_flush(void) { | ||||
|     sync_ws2812_transfer(); | ||||
| 
 | ||||
|     for (int i = 0; i < leds; i++) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
| #if defined(WS2812_RGBW) | ||||
|         WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, ledarray[i].w); | ||||
|         WS2812_BUFFER[i] = rgbw8888_to_u32(ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b, ws2812_leds[i].w); | ||||
| #else | ||||
|         WS2812_BUFFER[i] = rgbw8888_to_u32(ledarray[i].r, ledarray[i].g, ledarray[i].b, 0); | ||||
|         WS2812_BUFFER[i] = rgbw8888_to_u32(ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b, 0); | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|     dmaChannelSetSourceX(dma_channel, (uint32_t)WS2812_BUFFER); | ||||
|     dmaChannelSetCounterX(dma_channel, leds); | ||||
|     dmaChannelSetCounterX(dma_channel, WS2812_LED_COUNT); | ||||
|     dmaChannelSetModeX(dma_channel, RP_DMA_MODE_WS2812); | ||||
|     dmaChannelEnableX(dma_channel); | ||||
| } | ||||
|  |  | |||
|  | @ -76,33 +76,49 @@ void sendByte(uint8_t byte) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; | ||||
| 
 | ||||
| void ws2812_init(void) { | ||||
|     palSetLineMode(WS2812_DI_PIN, WS2812_OUTPUT_MODE); | ||||
| } | ||||
| 
 | ||||
| // Setleds for standard RGB
 | ||||
| void ws2812_setleds(rgb_led_t *ledarray, uint16_t leds) { | ||||
| void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     ws2812_leds[index].r = red; | ||||
|     ws2812_leds[index].g = green; | ||||
|     ws2812_leds[index].b = blue; | ||||
| #if defined(WS2812_RGBW) | ||||
|     ws2812_rgb_to_rgbw(&ws2812_leds[index]); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         ws2812_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ws2812_flush(void) { | ||||
|     // this code is very time dependent, so we need to disable interrupts
 | ||||
|     chSysLock(); | ||||
| 
 | ||||
|     for (uint8_t i = 0; i < leds; i++) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         // WS2812 protocol dictates grb order
 | ||||
| #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) | ||||
|         sendByte(ledarray[i].g); | ||||
|         sendByte(ledarray[i].r); | ||||
|         sendByte(ledarray[i].b); | ||||
|         sendByte(ws2812_leds[i].g); | ||||
|         sendByte(ws2812_leds[i].r); | ||||
|         sendByte(ws2812_leds[i].b); | ||||
| #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB) | ||||
|         sendByte(ledarray[i].r); | ||||
|         sendByte(ledarray[i].g); | ||||
|         sendByte(ledarray[i].b); | ||||
|         sendByte(ws2812_leds[i].r); | ||||
|         sendByte(ws2812_leds[i].g); | ||||
|         sendByte(ws2812_leds[i].b); | ||||
| #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) | ||||
|         sendByte(ledarray[i].b); | ||||
|         sendByte(ledarray[i].g); | ||||
|         sendByte(ledarray[i].r); | ||||
|         sendByte(ws2812_leds[i].b); | ||||
|         sendByte(ws2812_leds[i].g); | ||||
|         sendByte(ws2812_leds[i].r); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WS2812_RGBW | ||||
|         sendByte(ledarray[i].w); | ||||
|         sendByte(ws2812_leds[i].w); | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -387,13 +387,29 @@ void ws2812_write_led_rgbw(uint16_t led_number, uint8_t r, uint8_t g, uint8_t b, | |||
|     } | ||||
| } | ||||
| 
 | ||||
| // Setleds for standard RGB
 | ||||
| void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) { | ||||
|     for (uint16_t i = 0; i < leds; i++) { | ||||
| #ifdef WS2812_RGBW | ||||
|         ws2812_write_led_rgbw(i, ledarray[i].r, ledarray[i].g, ledarray[i].b, ledarray[i].w); | ||||
| ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; | ||||
| 
 | ||||
| void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     ws2812_leds[index].r = red; | ||||
|     ws2812_leds[index].g = green; | ||||
|     ws2812_leds[index].b = blue; | ||||
| #if defined(WS2812_RGBW) | ||||
|     ws2812_rgb_to_rgbw(&ws2812_leds[index]); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         ws2812_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ws2812_flush(void) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
| #if defined(WS2812_RGBW) | ||||
|         ws2812_write_led_rgbw(i, ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b, ws2812_leds[i].w); | ||||
| #else | ||||
|         ws2812_write_led(i, ledarray[i].r, ledarray[i].g, ledarray[i].b); | ||||
|         ws2812_write_led(i, ws2812_leds[i].r, ws2812_leds[i].g, ws2812_leds[i].b); | ||||
| #endif | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -106,7 +106,7 @@ static uint8_t get_protocol_eq(uint8_t data, int pos) { | |||
|     return eq; | ||||
| } | ||||
| 
 | ||||
| static void set_led_color_rgb(rgb_led_t color, int pos) { | ||||
| static void set_led_color_rgb(ws2812_led_t color, int pos) { | ||||
|     uint8_t* tx_start = &txbuf[PREAMBLE_SIZE]; | ||||
| 
 | ||||
| #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) | ||||
|  | @ -137,6 +137,8 @@ static void set_led_color_rgb(rgb_led_t color, int pos) { | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| ws2812_led_t ws2812_leds[WS2812_LED_COUNT]; | ||||
| 
 | ||||
| void ws2812_init(void) { | ||||
|     palSetLineMode(WS2812_DI_PIN, WS2812_MOSI_OUTPUT_MODE); | ||||
| 
 | ||||
|  | @ -187,9 +189,24 @@ void ws2812_init(void) { | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ws2812_setleds(rgb_led_t* ledarray, uint16_t leds) { | ||||
|     for (uint8_t i = 0; i < leds; i++) { | ||||
|         set_led_color_rgb(ledarray[i], i); | ||||
| void ws2812_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     ws2812_leds[index].r = red; | ||||
|     ws2812_leds[index].g = green; | ||||
|     ws2812_leds[index].b = blue; | ||||
| #if defined(WS2812_RGBW) | ||||
|     ws2812_rgb_to_rgbw(&ws2812_leds[index]); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void ws2812_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         ws2812_set_color(i, red, green, blue); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void ws2812_flush(void) { | ||||
|     for (int i = 0; i < WS2812_LED_COUNT; i++) { | ||||
|         set_led_color_rgb(ws2812_leds[i], i); | ||||
|     } | ||||
| 
 | ||||
|     // Send async - each led takes ~0.03ms, 50 leds ~1.5ms, animations flushing faster than send will cause issues.
 | ||||
|  |  | |||
|  | @ -108,14 +108,3 @@ RGB hsv_to_rgb(HSV hsv) { | |||
| RGB hsv_to_rgb_nocie(HSV hsv) { | ||||
|     return hsv_to_rgb_impl(hsv, false); | ||||
| } | ||||
| 
 | ||||
| #ifdef WS2812_RGBW | ||||
| void convert_rgb_to_rgbw(rgb_led_t *led) { | ||||
|     // Determine lowest value in all three colors, put that into
 | ||||
|     // the white channel and then shift all colors by that amount
 | ||||
|     led->w = MIN(led->r, MIN(led->g, led->b)); | ||||
|     led->r -= led->w; | ||||
|     led->g -= led->w; | ||||
|     led->b -= led->w; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -74,31 +74,10 @@ | |||
| 
 | ||||
| // clang-format on
 | ||||
| 
 | ||||
| #define WS2812_BYTE_ORDER_RGB 0 | ||||
| #define WS2812_BYTE_ORDER_GRB 1 | ||||
| #define WS2812_BYTE_ORDER_BGR 2 | ||||
| 
 | ||||
| #ifndef WS2812_BYTE_ORDER | ||||
| #    define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB | ||||
| #endif | ||||
| 
 | ||||
| typedef struct PACKED rgb_led_t { | ||||
| #if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) | ||||
|     uint8_t g; | ||||
|     uint8_t r; | ||||
|     uint8_t b; | ||||
| #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB) | ||||
|     uint8_t r; | ||||
|     uint8_t g; | ||||
|     uint8_t b; | ||||
| #elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) | ||||
|     uint8_t b; | ||||
|     uint8_t g; | ||||
|     uint8_t r; | ||||
| #endif | ||||
| #ifdef WS2812_RGBW | ||||
|     uint8_t w; | ||||
| #endif | ||||
| } rgb_led_t; | ||||
| 
 | ||||
| typedef rgb_led_t RGB; | ||||
|  | @ -111,6 +90,3 @@ typedef struct PACKED HSV { | |||
| 
 | ||||
| RGB hsv_to_rgb(HSV hsv); | ||||
| RGB hsv_to_rgb_nocie(HSV hsv); | ||||
| #ifdef WS2812_RGBW | ||||
| void convert_rgb_to_rgbw(rgb_led_t *led); | ||||
| #endif | ||||
|  |  | |||
|  | @ -139,11 +139,20 @@ void led_matrix_update_pwm_buffers(void) { | |||
|     led_matrix_driver.flush(); | ||||
| } | ||||
| 
 | ||||
| __attribute__((weak)) int led_matrix_led_index(int index) { | ||||
| #if defined(LED_MATRIX_SPLIT) | ||||
|     if (!is_keyboard_left() && index >= k_led_matrix_split[0]) { | ||||
|         return index - k_led_matrix_split[0]; | ||||
|     } | ||||
| #endif | ||||
|     return index; | ||||
| } | ||||
| 
 | ||||
| void led_matrix_set_value(int index, uint8_t value) { | ||||
| #ifdef USE_CIE1931_CURVE | ||||
|     value = pgm_read_byte(&CIE1931_CURVE[value]); | ||||
| #endif | ||||
|     led_matrix_driver.set_value(index, value); | ||||
|     led_matrix_driver.set_value(led_matrix_led_index(index), value); | ||||
| } | ||||
| 
 | ||||
| void led_matrix_set_value_all(uint8_t value) { | ||||
|  |  | |||
|  | @ -121,6 +121,8 @@ void eeconfig_debug_led_matrix(void); | |||
| uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i); | ||||
| uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i); | ||||
| 
 | ||||
| int led_matrix_led_index(int index); | ||||
| 
 | ||||
| void led_matrix_set_value(int index, uint8_t value); | ||||
| void led_matrix_set_value_all(uint8_t value); | ||||
| 
 | ||||
|  |  | |||
|  | @ -143,8 +143,17 @@ void rgb_matrix_update_pwm_buffers(void) { | |||
|     rgb_matrix_driver.flush(); | ||||
| } | ||||
| 
 | ||||
| __attribute__((weak)) int rgb_matrix_led_index(int index) { | ||||
| #if defined(RGB_MATRIX_SPLIT) | ||||
|     if (!is_keyboard_left() && index >= k_rgb_matrix_split[0]) { | ||||
|         return index - k_rgb_matrix_split[0]; | ||||
|     } | ||||
| #endif | ||||
|     return index; | ||||
| } | ||||
| 
 | ||||
| void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { | ||||
|     rgb_matrix_driver.set_color(index, red, green, blue); | ||||
|     rgb_matrix_driver.set_color(rgb_matrix_led_index(index), red, green, blue); | ||||
| } | ||||
| 
 | ||||
| void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { | ||||
|  |  | |||
|  | @ -145,6 +145,8 @@ void eeconfig_update_rgb_matrix(void); | |||
| uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i); | ||||
| uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i); | ||||
| 
 | ||||
| int rgb_matrix_led_index(int index); | ||||
| 
 | ||||
| void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); | ||||
| void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue); | ||||
| 
 | ||||
|  |  | |||
|  | @ -146,61 +146,11 @@ const rgb_matrix_driver_t rgb_matrix_driver = { | |||
| #        pragma message "You need to use a custom driver, or re-implement the WS2812 driver to use a different configuration." | ||||
| #    endif | ||||
| 
 | ||||
| // LED color buffer
 | ||||
| rgb_led_t rgb_matrix_ws2812_array[WS2812_LED_COUNT]; | ||||
| bool      ws2812_dirty = false; | ||||
| 
 | ||||
| static void init(void) { | ||||
|     ws2812_init(); | ||||
|     ws2812_dirty = false; | ||||
| } | ||||
| 
 | ||||
| static void flush(void) { | ||||
|     if (ws2812_dirty) { | ||||
|         ws2812_setleds(rgb_matrix_ws2812_array, WS2812_LED_COUNT); | ||||
|         ws2812_dirty = false; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Set an led in the buffer to a color
 | ||||
| static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) { | ||||
| #    if defined(RGB_MATRIX_SPLIT) | ||||
|     const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; | ||||
|     if (!is_keyboard_left()) { | ||||
|         if (i >= k_rgb_matrix_split[0]) { | ||||
|             i -= k_rgb_matrix_split[0]; | ||||
|         } else { | ||||
|             return; | ||||
|         } | ||||
|     } else if (i >= k_rgb_matrix_split[0]) { | ||||
|         return; | ||||
|     } | ||||
| #    endif | ||||
| 
 | ||||
|     if (rgb_matrix_ws2812_array[i].r == r && rgb_matrix_ws2812_array[i].g == g && rgb_matrix_ws2812_array[i].b == b) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     ws2812_dirty                 = true; | ||||
|     rgb_matrix_ws2812_array[i].r = r; | ||||
|     rgb_matrix_ws2812_array[i].g = g; | ||||
|     rgb_matrix_ws2812_array[i].b = b; | ||||
| #    ifdef WS2812_RGBW | ||||
|     convert_rgb_to_rgbw(&rgb_matrix_ws2812_array[i]); | ||||
| #    endif | ||||
| } | ||||
| 
 | ||||
| static void setled_all(uint8_t r, uint8_t g, uint8_t b) { | ||||
|     for (int i = 0; i < ARRAY_SIZE(rgb_matrix_ws2812_array); i++) { | ||||
|         setled(i, r, g, b); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| const rgb_matrix_driver_t rgb_matrix_driver = { | ||||
|     .init          = init, | ||||
|     .flush         = flush, | ||||
|     .set_color     = setled, | ||||
|     .set_color_all = setled_all, | ||||
|     .init          = ws2812_init, | ||||
|     .flush         = ws2812_flush, | ||||
|     .set_color     = ws2812_set_color, | ||||
|     .set_color_all = ws2812_set_color_all, | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -115,11 +115,6 @@ static bool pre_suspend_enabled; | |||
| animation_status_t animation_status = {}; | ||||
| #endif | ||||
| 
 | ||||
| #ifndef LED_ARRAY | ||||
| rgb_led_t led[RGBLIGHT_LED_COUNT]; | ||||
| #    define LED_ARRAY led | ||||
| #endif | ||||
| 
 | ||||
| #ifdef RGBLIGHT_LAYERS | ||||
| rgblight_segment_t const *const *rgblight_layers = NULL; | ||||
| 
 | ||||
|  | @ -145,23 +140,26 @@ __attribute__((weak)) RGB rgblight_hsv_to_rgb(HSV hsv) { | |||
|     return hsv_to_rgb(hsv); | ||||
| } | ||||
| 
 | ||||
| void setrgb(uint8_t r, uint8_t g, uint8_t b, rgb_led_t *led1) { | ||||
|     led1->r = r; | ||||
|     led1->g = g; | ||||
|     led1->b = b; | ||||
| #ifdef WS2812_RGBW | ||||
|     led1->w = 0; | ||||
| uint8_t rgblight_led_index(uint8_t index) { | ||||
| #if defined(RGBLIGHT_LED_MAP) | ||||
|     return pgm_read_byte(&led_map[index]) - rgblight_ranges.clipping_start_pos; | ||||
| #else | ||||
|     return index - rgblight_ranges.clipping_start_pos; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, rgb_led_t *led1) { | ||||
|     HSV hsv = {hue, sat, val}; | ||||
|     RGB rgb = rgblight_hsv_to_rgb(hsv); | ||||
|     setrgb(rgb.r, rgb.g, rgb.b, led1); | ||||
| void setrgb(uint8_t r, uint8_t g, uint8_t b, int index) { | ||||
|     rgblight_driver.set_color(rgblight_led_index(index), r, g, b); | ||||
| } | ||||
| 
 | ||||
| void sethsv(uint8_t hue, uint8_t sat, uint8_t val, rgb_led_t *led1) { | ||||
|     sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, led1); | ||||
| void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, int index) { | ||||
|     HSV hsv = {hue, sat, val}; | ||||
|     RGB rgb = rgblight_hsv_to_rgb(hsv); | ||||
|     setrgb(rgb.r, rgb.g, rgb.b, index); | ||||
| } | ||||
| 
 | ||||
| void sethsv(uint8_t hue, uint8_t sat, uint8_t val, int index) { | ||||
|     sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, index); | ||||
| } | ||||
| 
 | ||||
| void rgblight_check_config(void) { | ||||
|  | @ -515,9 +513,8 @@ void rgblight_decrease_speed_noeeprom(void) { | |||
| 
 | ||||
| void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) { | ||||
|     if (rgblight_config.enable) { | ||||
|         rgb_led_t tmp_led; | ||||
|         sethsv(hue, sat, val, &tmp_led); | ||||
|         rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); | ||||
|         RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val}); | ||||
|         rgblight_setrgb(rgb.r, rgb.g, rgb.b); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -531,13 +528,12 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w | |||
|         rgblight_status.base_mode = mode_base_table[rgblight_config.mode]; | ||||
|         if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) { | ||||
|             // same static color
 | ||||
|             rgb_led_t tmp_led; | ||||
| #ifdef RGBLIGHT_LAYERS_RETAIN_VAL | ||||
|             // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
 | ||||
|             rgblight_config.val = val; | ||||
| #endif | ||||
|             sethsv(hue, sat, val, &tmp_led); | ||||
|             rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); | ||||
|             RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val}); | ||||
|             rgblight_setrgb(rgb.r, rgb.g, rgb.b); | ||||
|         } else { | ||||
|             // all LEDs in same color
 | ||||
|             if (1 == 0) { // dummy
 | ||||
|  | @ -575,7 +571,7 @@ void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool w | |||
|                         _hue = hue - _hue; | ||||
|                     } | ||||
|                     dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range); | ||||
|                     sethsv(_hue, sat, val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]); | ||||
|                     sethsv(_hue, sat, val, i + rgblight_ranges.effect_start_pos); | ||||
|                 } | ||||
| #    ifdef RGBLIGHT_LAYERS_RETAIN_VAL | ||||
|                 // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val
 | ||||
|  | @ -649,12 +645,7 @@ void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { | |||
|     } | ||||
| 
 | ||||
|     for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { | ||||
|         led[i].r = r; | ||||
|         led[i].g = g; | ||||
|         led[i].b = b; | ||||
| #ifdef WS2812_RGBW | ||||
|         led[i].w = 0; | ||||
| #endif | ||||
|         rgblight_driver.set_color(rgblight_led_index(i), r, g, b); | ||||
|     } | ||||
|     rgblight_set(); | ||||
| } | ||||
|  | @ -664,12 +655,7 @@ void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     led[index].r = r; | ||||
|     led[index].g = g; | ||||
|     led[index].b = b; | ||||
| #ifdef WS2812_RGBW | ||||
|     led[index].w = 0; | ||||
| #endif | ||||
|     rgblight_driver.set_color(rgblight_led_index(index), r, g, b); | ||||
|     rgblight_set(); | ||||
| } | ||||
| 
 | ||||
|  | @ -678,9 +664,8 @@ void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) { | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     rgb_led_t tmp_led; | ||||
|     sethsv(hue, sat, val, &tmp_led); | ||||
|     rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index); | ||||
|     RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val}); | ||||
|     rgblight_setrgb_at(rgb.r, rgb.g, rgb.b, index); | ||||
| } | ||||
| 
 | ||||
| #if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE) | ||||
|  | @ -701,12 +686,7 @@ void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8 | |||
|     } | ||||
| 
 | ||||
|     for (uint8_t i = start; i < end; i++) { | ||||
|         led[i].r = r; | ||||
|         led[i].g = g; | ||||
|         led[i].b = b; | ||||
| #ifdef WS2812_RGBW | ||||
|         led[i].w = 0; | ||||
| #endif | ||||
|         rgblight_driver.set_color(rgblight_led_index(i), r, g, b); | ||||
|     } | ||||
|     rgblight_set(); | ||||
| } | ||||
|  | @ -716,9 +696,8 @@ void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     rgb_led_t tmp_led; | ||||
|     sethsv(hue, sat, val, &tmp_led); | ||||
|     rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end); | ||||
|     RGB rgb = hsv_to_rgb((HSV){hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val}); | ||||
|     rgblight_setrgb_range(rgb.r, rgb.g, rgb.b, start, end); | ||||
| } | ||||
| 
 | ||||
| #ifndef RGBLIGHT_SPLIT | ||||
|  | @ -785,12 +764,12 @@ static void rgblight_layers_write(void) { | |||
|                 break; // No more segments
 | ||||
|             } | ||||
|             // Write segment.count LEDs
 | ||||
|             rgb_led_t *const limit = &led[MIN(segment.index + segment.count, RGBLIGHT_LED_COUNT)]; | ||||
|             for (rgb_led_t *led_ptr = &led[segment.index]; led_ptr < limit; led_ptr++) { | ||||
|             int limit = MIN(segment.index + segment.count, RGBLIGHT_LED_COUNT); | ||||
|             for (int i = segment.index; i < limit; i++) { | ||||
| #    ifdef RGBLIGHT_LAYERS_RETAIN_VAL | ||||
|                 sethsv(segment.hue, segment.sat, current_val, led_ptr); | ||||
|                 sethsv(segment.hue, segment.sat, current_val, i); | ||||
| #    else | ||||
|                 sethsv(segment.hue, segment.sat, segment.val, led_ptr); | ||||
|                 sethsv(segment.hue, segment.sat, segment.val, i); | ||||
| #    endif | ||||
|             } | ||||
|             segment_ptr++; | ||||
|  | @ -897,17 +876,9 @@ void rgblight_wakeup(void) { | |||
| #endif | ||||
| 
 | ||||
| void rgblight_set(void) { | ||||
|     rgb_led_t *start_led; | ||||
|     uint8_t    num_leds = rgblight_ranges.clipping_num_leds; | ||||
| 
 | ||||
|     if (!rgblight_config.enable) { | ||||
|         for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { | ||||
|             led[i].r = 0; | ||||
|             led[i].g = 0; | ||||
|             led[i].b = 0; | ||||
| #ifdef WS2812_RGBW | ||||
|             led[i].w = 0; | ||||
| #endif | ||||
|             rgblight_driver.set_color(rgblight_led_index(i), 0, 0, 0); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -923,22 +894,7 @@ void rgblight_set(void) { | |||
|     } | ||||
| #endif | ||||
| 
 | ||||
| #ifdef RGBLIGHT_LED_MAP | ||||
|     rgb_led_t led0[RGBLIGHT_LED_COUNT]; | ||||
|     for (uint8_t i = 0; i < RGBLIGHT_LED_COUNT; i++) { | ||||
|         led0[i] = led[pgm_read_byte(&led_map[i])]; | ||||
|     } | ||||
|     start_led = led0 + rgblight_ranges.clipping_start_pos; | ||||
| #else | ||||
|     start_led = led + rgblight_ranges.clipping_start_pos; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef WS2812_RGBW | ||||
|     for (uint8_t i = 0; i < num_leds; i++) { | ||||
|         convert_rgb_to_rgbw(&start_led[i]); | ||||
|     } | ||||
| #endif | ||||
|     rgblight_driver.setleds(start_led, num_leds); | ||||
|     rgblight_driver.flush(); | ||||
| } | ||||
| 
 | ||||
| #ifdef RGBLIGHT_SPLIT | ||||
|  | @ -1222,7 +1178,7 @@ void rgblight_effect_rainbow_swirl(animation_status_t *anim) { | |||
| 
 | ||||
|     for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||||
|         hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / rgblight_ranges.effect_num_leds * i + anim->current_hue); | ||||
|         sethsv(hue, rgblight_config.sat, rgblight_config.val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]); | ||||
|         sethsv(hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos); | ||||
|     } | ||||
|     rgblight_set(); | ||||
| 
 | ||||
|  | @ -1259,13 +1215,8 @@ void rgblight_effect_snake(animation_status_t *anim) { | |||
| #    endif | ||||
| 
 | ||||
|     for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||||
|         rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos; | ||||
|         ledp->r         = 0; | ||||
|         ledp->g         = 0; | ||||
|         ledp->b         = 0; | ||||
| #    ifdef WS2812_RGBW | ||||
|         ledp->w = 0; | ||||
| #    endif | ||||
|         rgblight_driver.set_color(rgblight_led_index(i + rgblight_ranges.effect_start_pos), 0, 0, 0); | ||||
| 
 | ||||
|         for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) { | ||||
|             k = pos + j * increment; | ||||
|             if (k > RGBLIGHT_LED_COUNT) { | ||||
|  | @ -1275,7 +1226,7 @@ void rgblight_effect_snake(animation_status_t *anim) { | |||
|                 k = k + rgblight_ranges.effect_num_leds; | ||||
|             } | ||||
|             if (i == k) { | ||||
|                 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), ledp); | ||||
|                 sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), i + rgblight_ranges.effect_start_pos); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -1320,26 +1271,16 @@ void rgblight_effect_knight(animation_status_t *anim) { | |||
| #    endif | ||||
|     // Set all the LEDs to 0
 | ||||
|     for (i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { | ||||
|         led[i].r = 0; | ||||
|         led[i].g = 0; | ||||
|         led[i].b = 0; | ||||
| #    ifdef WS2812_RGBW | ||||
|         led[i].w = 0; | ||||
| #    endif | ||||
|         rgblight_driver.set_color(rgblight_led_index(i), 0, 0, 0); | ||||
|     } | ||||
|     // Determine which LEDs should be lit up
 | ||||
|     for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) { | ||||
|         cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % rgblight_ranges.effect_num_leds + rgblight_ranges.effect_start_pos; | ||||
| 
 | ||||
|         if (i >= low_bound && i <= high_bound) { | ||||
|             sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (rgb_led_t *)&led[cur]); | ||||
|             sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, cur); | ||||
|         } else { | ||||
|             led[cur].r = 0; | ||||
|             led[cur].g = 0; | ||||
|             led[cur].b = 0; | ||||
| #    ifdef WS2812_RGBW | ||||
|             led[cur].w = 0; | ||||
| #    endif | ||||
|             rgblight_driver.set_color(rgblight_led_index(cur), 0, 0, 0); | ||||
|         } | ||||
|     } | ||||
|     rgblight_set(); | ||||
|  | @ -1384,7 +1325,7 @@ void rgblight_effect_christmas(animation_status_t *anim) { | |||
| 
 | ||||
|     for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||||
|         uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue; | ||||
|         sethsv(local_hue, rgblight_config.sat, val, (rgb_led_t *)&led[i + rgblight_ranges.effect_start_pos]); | ||||
|         sethsv(local_hue, rgblight_config.sat, val, i + rgblight_ranges.effect_start_pos); | ||||
|     } | ||||
|     rgblight_set(); | ||||
| 
 | ||||
|  | @ -1407,9 +1348,8 @@ void rgblight_effect_rgbtest(animation_status_t *anim) { | |||
|     uint8_t        b; | ||||
| 
 | ||||
|     if (maxval == 0) { | ||||
|         rgb_led_t tmp_led; | ||||
|         sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led); | ||||
|         maxval = tmp_led.r; | ||||
|         RGB rgb = hsv_to_rgb((HSV){0, 255, RGBLIGHT_LIMIT_VAL}); | ||||
|         maxval  = rgb.r; | ||||
|     } | ||||
|     g = r = b = 0; | ||||
|     switch (anim->pos) { | ||||
|  | @ -1431,13 +1371,12 @@ void rgblight_effect_rgbtest(animation_status_t *anim) { | |||
| #ifdef RGBLIGHT_EFFECT_ALTERNATING | ||||
| void rgblight_effect_alternating(animation_status_t *anim) { | ||||
|     for (int i = 0; i < rgblight_ranges.effect_num_leds; i++) { | ||||
|         rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos; | ||||
|         if (i < rgblight_ranges.effect_num_leds / 2 && anim->pos) { | ||||
|             sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); | ||||
|             sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos); | ||||
|         } else if (i >= rgblight_ranges.effect_num_leds / 2 && !anim->pos) { | ||||
|             sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); | ||||
|             sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, i + rgblight_ranges.effect_start_pos); | ||||
|         } else { | ||||
|             sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp); | ||||
|             sethsv(rgblight_config.hue, rgblight_config.sat, 0, i + rgblight_ranges.effect_start_pos); | ||||
|         } | ||||
|     } | ||||
|     rgblight_set(); | ||||
|  | @ -1504,8 +1443,7 @@ void rgblight_effect_twinkle(animation_status_t *anim) { | |||
|             // This LED is off, and was NOT selected to start brightening
 | ||||
|         } | ||||
| 
 | ||||
|         rgb_led_t *ledp = led + i + rgblight_ranges.effect_start_pos; | ||||
|         sethsv(c->h, c->s, c->v, ledp); | ||||
|         sethsv(c->h, c->s, c->v, i + rgblight_ranges.effect_start_pos); | ||||
|     } | ||||
| 
 | ||||
|     rgblight_set(); | ||||
|  |  | |||
|  | @ -169,7 +169,6 @@ enum RGBLIGHT_EFFECT_MODE { | |||
| #include "rgblight_drivers.h" | ||||
| #include "progmem.h" | ||||
| #include "eeconfig.h" | ||||
| #include "ws2812.h" | ||||
| #include "color.h" | ||||
| 
 | ||||
| #ifdef RGBLIGHT_LAYERS | ||||
|  |  | |||
|  | @ -7,24 +7,20 @@ | |||
| #    include "ws2812.h" | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .init    = ws2812_init, | ||||
|     .setleds = ws2812_setleds, | ||||
|     .init          = ws2812_init, | ||||
|     .set_color     = ws2812_set_color, | ||||
|     .set_color_all = ws2812_set_color_all, | ||||
|     .flush         = ws2812_flush, | ||||
| }; | ||||
| 
 | ||||
| #elif defined(RGBLIGHT_APA102) | ||||
| #    include "apa102.h" | ||||
| 
 | ||||
| // Temporary shim
 | ||||
| static void apa102_setleds(rgb_led_t *ledarray, uint16_t number_of_leds) { | ||||
|     for (uint16_t i = 0; i < number_of_leds; i++) { | ||||
|         apa102_set_color(i, ledarray[i].r, ledarray[i].g, ledarray[i].b); | ||||
|     } | ||||
|     apa102_flush(); | ||||
| } | ||||
| 
 | ||||
| const rgblight_driver_t rgblight_driver = { | ||||
|     .init    = apa102_init, | ||||
|     .setleds = apa102_setleds, | ||||
|     .init          = apa102_init, | ||||
|     .set_color     = apa102_set_color, | ||||
|     .set_color_all = apa102_set_color_all, | ||||
|     .flush         = apa102_flush, | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -4,11 +4,12 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include "color.h" | ||||
| 
 | ||||
| typedef struct { | ||||
|     void (*init)(void); | ||||
|     void (*setleds)(rgb_led_t *ledarray, uint16_t number_of_leds); | ||||
|     void (*set_color)(int index, uint8_t red, uint8_t green, uint8_t blue); | ||||
|     void (*set_color_all)(uint8_t red, uint8_t green, uint8_t blue); | ||||
|     void (*flush)(void); | ||||
| } rgblight_driver_t; | ||||
| 
 | ||||
| extern const rgblight_driver_t rgblight_driver; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ryan
						Ryan