Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WS2812 API rework #24364

Merged
merged 35 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5b3a01a
Begin WS2812 API rework
fauxpark Sep 5, 2024
c10f945
Move RGBW conversion, clean up color.h, fix RGBW for AVR bitbang
fauxpark Sep 5, 2024
8402591
Formatting & update PS2AVRGB I2C driver (untested)
fauxpark Sep 5, 2024
bcec89f
Tested ARM bitbang RGB+RGBW
fauxpark Sep 5, 2024
2a78180
Tested ARM SPI RGB - RGBW not working
fauxpark Sep 5, 2024
db8ac94
Tested ARM PWM RGB+RGBW
fauxpark Sep 5, 2024
990ce36
Tested RP2040 PIO driver RGB+RGBW
fauxpark Sep 5, 2024
fbbaabd
Merge remote-tracking branch 'upstream/develop' into ws2812-api-rework
fauxpark Sep 5, 2024
dacf4ab
Update RGBLight
fauxpark Sep 6, 2024
c2baabd
Formatting
fauxpark Sep 6, 2024
beee116
Fix BM60HSRGB rev2
fauxpark Sep 6, 2024
1b0afc0
Fix oddforge/vea
fauxpark Sep 6, 2024
c86a721
Fix 1k and XD002 RGBLite
fauxpark Sep 6, 2024
31c1c08
Fix model_m/mschwingen
fauxpark Sep 6, 2024
97c3e57
Fix handwired/promethium
fauxpark Sep 6, 2024
aa6418e
Rename `WS2812_LED_TOTAL` for BM60HSRGB
fauxpark Sep 6, 2024
c607700
Fix work_louder boards
fauxpark Sep 6, 2024
1e2dee4
Fix dawn60
fauxpark Sep 6, 2024
b5196a3
Fix rgbkb/pan
fauxpark Sep 6, 2024
8fa9a90
Fix neson_design/700e and n6
fauxpark Sep 7, 2024
c350693
Fix ergodox_ez/shine
fauxpark Sep 7, 2024
604aabc
ergodox_ez/shine: invert indices for left half
fauxpark Sep 7, 2024
a9c22f8
Fix matrix/abelx
fauxpark Sep 7, 2024
e30933d
Fix matrix/m20add
fauxpark Sep 7, 2024
ea2f4c2
Remove custom rgblight driver for matrix/noah - should be done with l…
fauxpark Sep 7, 2024
4763797
Fix LED indexes for RGBLight split
fauxpark Sep 9, 2024
b46823c
Rename `convert_rgb_to_rgbw()` to `ws2812_rgb_to_rgbw()`
fauxpark Sep 9, 2024
239652d
Update WS2812 API docs
fauxpark Sep 9, 2024
3e95609
Merge remote-tracking branch 'upstream/develop' into ws2812-api-rework
fauxpark Sep 15, 2024
1a9afd1
`ergodox_ez/shine`: simplify LED index calculation
fauxpark Sep 15, 2024
7465949
LED/RGB Matrix: Add weak function for LED index resolution
fauxpark Sep 15, 2024
e5cd715
Bandaid fix for RGB Matrix splits not using WS2812
fauxpark Sep 20, 2024
28fdc7d
Merge remote-tracking branch 'upstream/develop' into ws2812-api-rework
fauxpark Sep 21, 2024
a6e6398
`steelseries/prime_plus`: redo custom RGBLight driver
fauxpark Sep 21, 2024
9e84565
Update keyboards/steelseries/prime_plus/rgblight_custom.c
fauxpark Sep 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion builddefs/common_features.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
45 changes: 38 additions & 7 deletions docs/drivers/ws2812.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 15 additions & 0 deletions drivers/ws2812.c
Original file line number Diff line number Diff line change
@@ -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
45 changes: 32 additions & 13 deletions drivers/ws2812.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -62,17 +62,36 @@
# define WS2812_LED_COUNT RGB_MATRIX_LED_COUNT
#endif

#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 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);

/* 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);
void ws2812_rgb_to_rgbw(ws2812_led_t *led);
2 changes: 2 additions & 0 deletions keyboards/1k/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions keyboards/1k/keymaps/default/rgblite.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions keyboards/ergodox_ez/post_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
82 changes: 45 additions & 37 deletions keyboards/ergodox_ez/shine/rgblight_custom.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
#define WS2812_I2C_ADDRESS_LEFT 0x84

#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);
}
i2c_transmit(0x84, data, sizeof(data), ERGODOX_EZ_I2C_TIMEOUT);
}

ws2812_setleds(led, led_num);
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,
};
1 change: 1 addition & 0 deletions keyboards/handwired/promethium/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ enum led_sequence {
};

# define RGBSPS_NUM LED_TOTAL
# define WS2812_LED_COUNT RGBSPS_NUM
#endif

/* PS/2 mouse */
Expand Down
8 changes: 2 additions & 6 deletions keyboards/handwired/promethium/rgbsps.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,14 @@
#include "ws2812.h"
#include "rgbsps.h"

rgb_led_t led[RGBSPS_NUM];

void keyboard_pre_init_kb(void) {
ws2812_init();

keyboard_pre_init_user();
}

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) {
Expand All @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions keyboards/ibm/model_m/mschwingen/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading