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

LED drivers: create structs to hold PWM/scaling buffers #22955

Merged
merged 3 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 17 additions & 10 deletions drivers/led/aw20216s.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,15 @@
# define AW20216S_SPI_DIVISOR 4
#endif

uint8_t g_pwm_buffer[AW20216S_DRIVER_COUNT][AW20216S_PWM_REGISTER_COUNT];
bool g_pwm_buffer_update_required[AW20216S_DRIVER_COUNT] = {false};
typedef struct aw20216s_driver_t {
uint8_t pwm_buffer[AW20216S_PWM_REGISTER_COUNT];
bool pwm_buffer_dirty;
} PACKED aw20216s_driver_t;

aw20216s_driver_t driver_buffers[AW20216S_DRIVER_COUNT] = {{
.pwm_buffer = {0},
.pwm_buffer_dirty = false,
}};

bool aw20216s_write(pin_t cs_pin, uint8_t page, uint8_t reg, uint8_t* data, uint8_t len) {
static uint8_t s_spi_transfer_buffer[2] = {0};
Expand Down Expand Up @@ -131,14 +138,14 @@ void aw20216s_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
aw20216s_led_t led;
memcpy_P(&led, (&g_aw20216s_leds[index]), sizeof(led));

if (g_pwm_buffer[led.driver][led.r] == red && g_pwm_buffer[led.driver][led.g] == green && g_pwm_buffer[led.driver][led.b] == blue) {
if (driver_buffers[led.driver].pwm_buffer[led.r] == red && driver_buffers[led.driver].pwm_buffer[led.g] == green && driver_buffers[led.driver].pwm_buffer[led.b] == blue) {
return;
}

g_pwm_buffer[led.driver][led.r] = red;
g_pwm_buffer[led.driver][led.g] = green;
g_pwm_buffer[led.driver][led.b] = blue;
g_pwm_buffer_update_required[led.driver] = true;
driver_buffers[led.driver].pwm_buffer[led.r] = red;
driver_buffers[led.driver].pwm_buffer[led.g] = green;
driver_buffers[led.driver].pwm_buffer[led.b] = blue;
driver_buffers[led.driver].pwm_buffer_dirty = true;
}

void aw20216s_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
Expand All @@ -148,9 +155,9 @@ void aw20216s_set_color_all(uint8_t red, uint8_t green, uint8_t blue) {
}

void aw20216s_update_pwm_buffers(pin_t cs_pin, uint8_t index) {
if (g_pwm_buffer_update_required[index]) {
aw20216s_write(cs_pin, AW20216S_PAGE_PWM, 0, g_pwm_buffer[index], AW20216S_PWM_REGISTER_COUNT);
g_pwm_buffer_update_required[index] = false;
if (driver_buffers[index].pwm_buffer_dirty) {
aw20216s_write(cs_pin, AW20216S_PAGE_PWM, 0, driver_buffers[index].pwm_buffer, AW20216S_PWM_REGISTER_COUNT);
driver_buffers[index].pwm_buffer_dirty = false;
}
}

Expand Down
44 changes: 26 additions & 18 deletions drivers/led/issi/is31fl3218-mono.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,20 @@
# define IS31FL3218_I2C_PERSISTENCE 0
#endif

// IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining.
uint8_t g_pwm_buffer[IS31FL3218_PWM_REGISTER_COUNT];
bool g_pwm_buffer_update_required = false;
typedef struct is31fl3218_driver_t {
uint8_t pwm_buffer[IS31FL3218_PWM_REGISTER_COUNT];
bool pwm_buffer_dirty;
uint8_t led_control_buffer[IS31FL3218_LED_CONTROL_REGISTER_COUNT];
bool led_control_buffer_dirty;
} PACKED is31fl3218_driver_t;

uint8_t g_led_control_registers[IS31FL3218_LED_CONTROL_REGISTER_COUNT] = {0};
bool g_led_control_registers_update_required = false;
// IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining.
is31fl3218_driver_t driver_buffers = {
.pwm_buffer = {0},
.pwm_buffer_dirty = false,
.led_control_buffer = {0},
.led_control_buffer_dirty = false,
};

void is31fl3218_write_register(uint8_t reg, uint8_t data) {
#if IS31FL3218_I2C_PERSISTENCE > 0
Expand All @@ -48,10 +56,10 @@ void is31fl3218_write_register(uint8_t reg, uint8_t data) {
void is31fl3218_write_pwm_buffer(void) {
#if IS31FL3218_I2C_PERSISTENCE > 0
for (uint8_t i = 0; i < IS31FL3218_I2C_PERSISTENCE; i++) {
if (i2c_write_register(IS31FL3218_I2C_ADDRESS << 1, IS31FL3218_REG_PWM, g_pwm_buffer, 18, IS31FL3218_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break;
if (i2c_write_register(IS31FL3218_I2C_ADDRESS << 1, IS31FL3218_REG_PWM, driver_buffers.pwm_buffer, 18, IS31FL3218_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break;
}
#else
i2c_write_register(IS31FL3218_I2C_ADDRESS << 1, IS31FL3218_REG_PWM, g_pwm_buffer, 18, IS31FL3218_I2C_TIMEOUT);
i2c_write_register(IS31FL3218_I2C_ADDRESS << 1, IS31FL3218_REG_PWM, driver_buffers.pwm_buffer, 18, IS31FL3218_I2C_TIMEOUT);
#endif
}

Expand Down Expand Up @@ -90,12 +98,12 @@ void is31fl3218_set_value(int index, uint8_t value) {
if (index >= 0 && index < IS31FL3218_LED_COUNT) {
memcpy_P(&led, (&g_is31fl3218_leds[index]), sizeof(led));

if (g_pwm_buffer[led.v] == value) {
if (driver_buffers.pwm_buffer[led.v] == value) {
return;
}

g_pwm_buffer[led.v] = value;
g_pwm_buffer_update_required = true;
driver_buffers.pwm_buffer[led.v] = value;
driver_buffers.pwm_buffer_dirty = true;
}
}

Expand All @@ -113,30 +121,30 @@ void is31fl3218_set_led_control_register(uint8_t index, bool value) {
uint8_t bit_value = led.v % 6;

if (value) {
g_led_control_registers[control_register] |= (1 << bit_value);
driver_buffers.led_control_buffer[control_register] |= (1 << bit_value);
} else {
g_led_control_registers[control_register] &= ~(1 << bit_value);
driver_buffers.led_control_buffer[control_register] &= ~(1 << bit_value);
}

g_led_control_registers_update_required = true;
driver_buffers.led_control_buffer_dirty = true;
}

void is31fl3218_update_pwm_buffers(void) {
if (g_pwm_buffer_update_required) {
if (driver_buffers.pwm_buffer_dirty) {
is31fl3218_write_pwm_buffer();
// Load PWM registers and LED Control register data
is31fl3218_write_register(IS31FL3218_REG_UPDATE, 0x01);

g_pwm_buffer_update_required = false;
driver_buffers.pwm_buffer_dirty = false;
}
}

void is31fl3218_update_led_control_registers(void) {
if (g_led_control_registers_update_required) {
if (driver_buffers.led_control_buffer_dirty) {
for (uint8_t i = 0; i < IS31FL3218_LED_CONTROL_REGISTER_COUNT; i++) {
is31fl3218_write_register(IS31FL3218_REG_LED_CONTROL_1 + i, g_led_control_registers[i]);
is31fl3218_write_register(IS31FL3218_REG_LED_CONTROL_1 + i, driver_buffers.led_control_buffer[i]);
}

g_led_control_registers_update_required = false;
driver_buffers.led_control_buffer_dirty = false;
}
}
56 changes: 32 additions & 24 deletions drivers/led/issi/is31fl3218.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,20 @@
# define IS31FL3218_I2C_PERSISTENCE 0
#endif

// IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining.
uint8_t g_pwm_buffer[IS31FL3218_PWM_REGISTER_COUNT];
bool g_pwm_buffer_update_required = false;
typedef struct is31fl3218_driver_t {
uint8_t pwm_buffer[IS31FL3218_PWM_REGISTER_COUNT];
bool pwm_buffer_dirty;
uint8_t led_control_buffer[IS31FL3218_LED_CONTROL_REGISTER_COUNT];
bool led_control_buffer_dirty;
} PACKED is31fl3218_driver_t;

uint8_t g_led_control_registers[IS31FL3218_LED_CONTROL_REGISTER_COUNT] = {0};
bool g_led_control_registers_update_required = false;
// IS31FL3218 has 18 PWM outputs and a fixed I2C address, so no chaining.
is31fl3218_driver_t driver_buffers = {
.pwm_buffer = {0},
.pwm_buffer_dirty = false,
.led_control_buffer = {0},
.led_control_buffer_dirty = false,
};

void is31fl3218_write_register(uint8_t reg, uint8_t data) {
#if IS31FL3218_I2C_PERSISTENCE > 0
Expand All @@ -48,10 +56,10 @@ void is31fl3218_write_register(uint8_t reg, uint8_t data) {
void is31fl3218_write_pwm_buffer(void) {
#if IS31FL3218_I2C_PERSISTENCE > 0
for (uint8_t i = 0; i < IS31FL3218_I2C_PERSISTENCE; i++) {
if (i2c_write_register(IS31FL3218_I2C_ADDRESS << 1, IS31FL3218_REG_PWM, g_pwm_buffer, 18, IS31FL3218_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break;
if (i2c_write_register(IS31FL3218_I2C_ADDRESS << 1, IS31FL3218_REG_PWM, driver_buffers.pwm_buffer, 18, IS31FL3218_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break;
}
#else
i2c_write_register(IS31FL3218_I2C_ADDRESS << 1, IS31FL3218_REG_PWM, g_pwm_buffer, 18, IS31FL3218_I2C_TIMEOUT);
i2c_write_register(IS31FL3218_I2C_ADDRESS << 1, IS31FL3218_REG_PWM, driver_buffers.pwm_buffer, 18, IS31FL3218_I2C_TIMEOUT);
#endif
}

Expand Down Expand Up @@ -90,14 +98,14 @@ void is31fl3218_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
if (index >= 0 && index < IS31FL3218_LED_COUNT) {
memcpy_P(&led, (&g_is31fl3218_leds[index]), sizeof(led));

if (g_pwm_buffer[led.r] == red && g_pwm_buffer[led.g] == green && g_pwm_buffer[led.b] == blue) {
if (driver_buffers.pwm_buffer[led.r] == red && driver_buffers.pwm_buffer[led.g] == green && driver_buffers.pwm_buffer[led.b] == blue) {
return;
}

g_pwm_buffer[led.r] = red;
g_pwm_buffer[led.g] = green;
g_pwm_buffer[led.b] = blue;
g_pwm_buffer_update_required = true;
driver_buffers.pwm_buffer[led.r] = red;
driver_buffers.pwm_buffer[led.g] = green;
driver_buffers.pwm_buffer[led.b] = blue;
driver_buffers.pwm_buffer_dirty = true;
}
}

Expand All @@ -119,40 +127,40 @@ void is31fl3218_set_led_control_register(uint8_t index, bool red, bool green, bo
uint8_t bit_b = led.b % 6;

if (red) {
g_led_control_registers[control_register_r] |= (1 << bit_r);
driver_buffers.led_control_buffer[control_register_r] |= (1 << bit_r);
} else {
g_led_control_registers[control_register_r] &= ~(1 << bit_r);
driver_buffers.led_control_buffer[control_register_r] &= ~(1 << bit_r);
}
if (green) {
g_led_control_registers[control_register_g] |= (1 << bit_g);
driver_buffers.led_control_buffer[control_register_g] |= (1 << bit_g);
} else {
g_led_control_registers[control_register_g] &= ~(1 << bit_g);
driver_buffers.led_control_buffer[control_register_g] &= ~(1 << bit_g);
}
if (blue) {
g_led_control_registers[control_register_b] |= (1 << bit_b);
driver_buffers.led_control_buffer[control_register_b] |= (1 << bit_b);
} else {
g_led_control_registers[control_register_b] &= ~(1 << bit_b);
driver_buffers.led_control_buffer[control_register_b] &= ~(1 << bit_b);
}

g_led_control_registers_update_required = true;
driver_buffers.led_control_buffer_dirty = true;
}

void is31fl3218_update_pwm_buffers(void) {
if (g_pwm_buffer_update_required) {
if (driver_buffers.pwm_buffer_dirty) {
is31fl3218_write_pwm_buffer();
// Load PWM registers and LED Control register data
is31fl3218_write_register(IS31FL3218_REG_UPDATE, 0x01);

g_pwm_buffer_update_required = false;
driver_buffers.pwm_buffer_dirty = false;
}
}

void is31fl3218_update_led_control_registers(void) {
if (g_led_control_registers_update_required) {
if (driver_buffers.led_control_buffer_dirty) {
for (uint8_t i = 0; i < IS31FL3218_LED_CONTROL_REGISTER_COUNT; i++) {
is31fl3218_write_register(IS31FL3218_REG_LED_CONTROL_1 + i, g_led_control_registers[i]);
is31fl3218_write_register(IS31FL3218_REG_LED_CONTROL_1 + i, driver_buffers.led_control_buffer[i]);
}

g_led_control_registers_update_required = false;
driver_buffers.led_control_buffer_dirty = false;
}
}
44 changes: 26 additions & 18 deletions drivers/led/issi/is31fl3731-mono.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,19 @@ const uint8_t i2c_addresses[IS31FL3731_DRIVER_COUNT] = {
// We could optimize this and take out the unused registers from these
// buffers and the transfers in is31fl3731_write_pwm_buffer() but it's
// probably not worth the extra complexity.
uint8_t g_pwm_buffer[IS31FL3731_DRIVER_COUNT][IS31FL3731_PWM_REGISTER_COUNT];
bool g_pwm_buffer_update_required[IS31FL3731_DRIVER_COUNT] = {false};

uint8_t g_led_control_registers[IS31FL3731_DRIVER_COUNT][IS31FL3731_LED_CONTROL_REGISTER_COUNT] = {0};
bool g_led_control_registers_update_required[IS31FL3731_DRIVER_COUNT] = {false};
typedef struct is31fl3731_driver_t {
uint8_t pwm_buffer[IS31FL3731_PWM_REGISTER_COUNT];
bool pwm_buffer_dirty;
uint8_t led_control_buffer[IS31FL3731_LED_CONTROL_REGISTER_COUNT];
bool led_control_buffer_dirty;
} PACKED is31fl3731_driver_t;

is31fl3731_driver_t driver_buffers[IS31FL3731_DRIVER_COUNT] = {{
.pwm_buffer = {0},
.pwm_buffer_dirty = false,
.led_control_buffer = {0},
.led_control_buffer_dirty = false,
}};

void is31fl3731_write_register(uint8_t index, uint8_t reg, uint8_t data) {
#if IS31FL3731_I2C_PERSISTENCE > 0
Expand All @@ -78,10 +86,10 @@ void is31fl3731_write_pwm_buffer(uint8_t index) {
for (uint8_t i = 0; i < IS31FL3731_PWM_REGISTER_COUNT; i += 16) {
#if IS31FL3731_I2C_PERSISTENCE > 0
for (uint8_t j = 0; j < IS31FL3731_I2C_PERSISTENCE; j++) {
if (i2c_write_register(i2c_addresses[index] << 1, IS31FL3731_FRAME_REG_PWM + i, g_pwm_buffer[index] + i, 16, IS31FL3731_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break;
if (i2c_write_register(i2c_addresses[index] << 1, IS31FL3731_FRAME_REG_PWM + i, driver_buffers[index].pwm_buffer + i, 16, IS31FL3731_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break;
}
#else
i2c_write_register(i2c_addresses[index] << 1, IS31FL3731_FRAME_REG_PWM + i, g_pwm_buffer[index] + i, 16, IS31FL3731_I2C_TIMEOUT);
i2c_write_register(i2c_addresses[index] << 1, IS31FL3731_FRAME_REG_PWM + i, driver_buffers[index].pwm_buffer + i, 16, IS31FL3731_I2C_TIMEOUT);
#endif
}
}
Expand Down Expand Up @@ -160,12 +168,12 @@ void is31fl3731_set_value(int index, uint8_t value) {
if (index >= 0 && index < IS31FL3731_LED_COUNT) {
memcpy_P(&led, (&g_is31fl3731_leds[index]), sizeof(led));

if (g_pwm_buffer[led.driver][led.v] == value) {
if (driver_buffers[led.driver].pwm_buffer[led.v] == value) {
return;
}

g_pwm_buffer[led.driver][led.v] = value;
g_pwm_buffer_update_required[led.driver] = true;
driver_buffers[led.driver].pwm_buffer[led.v] = value;
driver_buffers[led.driver].pwm_buffer_dirty = true;
}
}

Expand All @@ -183,29 +191,29 @@ void is31fl3731_set_led_control_register(uint8_t index, bool value) {
uint8_t bit_value = led.v % 8;

if (value) {
g_led_control_registers[led.driver][control_register] |= (1 << bit_value);
driver_buffers[led.driver].led_control_buffer[control_register] |= (1 << bit_value);
} else {
g_led_control_registers[led.driver][control_register] &= ~(1 << bit_value);
driver_buffers[led.driver].led_control_buffer[control_register] &= ~(1 << bit_value);
}

g_led_control_registers_update_required[led.driver] = true;
driver_buffers[led.driver].led_control_buffer_dirty = true;
}

void is31fl3731_update_pwm_buffers(uint8_t index) {
if (g_pwm_buffer_update_required[index]) {
if (driver_buffers[index].pwm_buffer_dirty) {
is31fl3731_write_pwm_buffer(index);

g_pwm_buffer_update_required[index] = false;
driver_buffers[index].pwm_buffer_dirty = false;
}
}

void is31fl3731_update_led_control_registers(uint8_t index) {
if (g_led_control_registers_update_required[index]) {
if (driver_buffers[index].led_control_buffer_dirty) {
for (uint8_t i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) {
is31fl3731_write_register(index, i, g_led_control_registers[index][i]);
is31fl3731_write_register(index, i, driver_buffers[index].led_control_buffer[i]);
}

g_led_control_registers_update_required[index] = false;
driver_buffers[index].led_control_buffer_dirty = false;
}
}

Expand Down
Loading
Loading