Skip to content

Commit

Permalink
LED drivers: refactor page selection (qmk#22518)
Browse files Browse the repository at this point in the history
  • Loading branch information
fauxpark authored and itsjonny96 committed Jan 6, 2024
1 parent 36c40c1 commit 847cfbd
Show file tree
Hide file tree
Showing 29 changed files with 211 additions and 274 deletions.
2 changes: 2 additions & 0 deletions drivers/led/issi/is31fl3218-simple.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ extern const is31fl3218_led_t PROGMEM g_is31fl3218_leds[IS31FL3218_LED_COUNT];

void is31fl3218_init(void);

void is31fl3218_write_register(uint8_t reg, uint8_t data);

void is31fl3218_set_value(int index, uint8_t value);

void is31fl3218_set_value_all(uint8_t value);
Expand Down
2 changes: 2 additions & 0 deletions drivers/led/issi/is31fl3218.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ extern const is31fl3218_led_t PROGMEM g_is31fl3218_leds[IS31FL3218_LED_COUNT];

void is31fl3218_init(void);

void is31fl3218_write_register(uint8_t reg, uint8_t data);

void is31fl3218_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);

void is31fl3218_set_color_all(uint8_t red, uint8_t green, uint8_t blue);
Expand Down
21 changes: 11 additions & 10 deletions drivers/led/issi/is31fl3731-simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,12 @@ void is31fl3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
#endif
}

void is31fl3731_select_page(uint8_t addr, uint8_t page) {
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, page);
}

void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
// assumes bank is already selected
// assumes page 0 is already selected

// transmit PWM registers in 9 transfers of 16 bytes
// g_twi_transfer_buffer[] is 20 bytes
Expand Down Expand Up @@ -123,8 +127,7 @@ void is31fl3731_init(uint8_t addr) {
// then set up the mode and other settings, clear the PWM registers,
// then disable software shutdown.

// select "function register" bank
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, IS31FL3731_COMMAND_FUNCTION);
is31fl3731_select_page(addr, IS31FL3731_COMMAND_FUNCTION);

// enable software shutdown
is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x00);
Expand All @@ -142,8 +145,7 @@ void is31fl3731_init(uint8_t addr) {
// audio sync off
is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_AUDIO_SYNC, 0x00);

// select bank 0
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, IS31FL3731_COMMAND_FRAME_1);
is31fl3731_select_page(addr, IS31FL3731_COMMAND_FRAME_1);

// turn off all LEDs in the LED control register
for (int i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) {
Expand All @@ -160,16 +162,15 @@ void is31fl3731_init(uint8_t addr) {
is31fl3731_write_register(addr, i, 0x00);
}

// select "function register" bank
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, IS31FL3731_COMMAND_FUNCTION);
is31fl3731_select_page(addr, IS31FL3731_COMMAND_FUNCTION);

// disable software shutdown
is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x01);

// select bank 0 and leave it selected.
// most usage after initialization is just writing PWM buffers in bank 0
// select page 0 and leave it selected.
// most usage after initialization is just writing PWM buffers in page 0
// as there's not much point in double-buffering
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, IS31FL3731_COMMAND_FRAME_1);
is31fl3731_select_page(addr, IS31FL3731_COMMAND_FRAME_1);
}

void is31fl3731_set_value(int index, uint8_t value) {
Expand Down
1 change: 1 addition & 0 deletions drivers/led/issi/is31fl3731-simple.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ extern const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT];
void is31fl3731_init_drivers(void);
void is31fl3731_init(uint8_t addr);
void is31fl3731_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3731_select_page(uint8_t addr, uint8_t page);
void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

void is31fl3731_set_value(int index, uint8_t value);
Expand Down
21 changes: 11 additions & 10 deletions drivers/led/issi/is31fl3731.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,12 @@ void is31fl3731_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
#endif
}

void is31fl3731_select_page(uint8_t addr, uint8_t page) {
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, page);
}

void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
// assumes bank is already selected
// assumes page 0 is already selected

// transmit PWM registers in 9 transfers of 16 bytes
// g_twi_transfer_buffer[] is 20 bytes
Expand Down Expand Up @@ -120,8 +124,7 @@ void is31fl3731_init(uint8_t addr) {
// then set up the mode and other settings, clear the PWM registers,
// then disable software shutdown.

// select "function register" bank
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, IS31FL3731_COMMAND_FUNCTION);
is31fl3731_select_page(addr, IS31FL3731_COMMAND_FUNCTION);

// enable software shutdown
is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x00);
Expand All @@ -139,8 +142,7 @@ void is31fl3731_init(uint8_t addr) {
// audio sync off
is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_AUDIO_SYNC, 0x00);

// select bank 0
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, IS31FL3731_COMMAND_FRAME_1);
is31fl3731_select_page(addr, IS31FL3731_COMMAND_FRAME_1);

// turn off all LEDs in the LED control register
for (int i = 0; i < IS31FL3731_LED_CONTROL_REGISTER_COUNT; i++) {
Expand All @@ -157,16 +159,15 @@ void is31fl3731_init(uint8_t addr) {
is31fl3731_write_register(addr, i, 0x00);
}

// select "function register" bank
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, IS31FL3731_COMMAND_FUNCTION);
is31fl3731_select_page(addr, IS31FL3731_COMMAND_FUNCTION);

// disable software shutdown
is31fl3731_write_register(addr, IS31FL3731_FUNCTION_REG_SHUTDOWN, 0x01);

// select bank 0 and leave it selected.
// most usage after initialization is just writing PWM buffers in bank 0
// select page 0 and leave it selected.
// most usage after initialization is just writing PWM buffers in page 0
// as there's not much point in double-buffering
is31fl3731_write_register(addr, IS31FL3731_REG_COMMAND, IS31FL3731_COMMAND_FRAME_1);
is31fl3731_select_page(addr, IS31FL3731_COMMAND_FRAME_1);
}

void is31fl3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) {
Expand Down
1 change: 1 addition & 0 deletions drivers/led/issi/is31fl3731.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ extern const is31fl3731_led_t PROGMEM g_is31fl3731_leds[IS31FL3731_LED_COUNT];
void is31fl3731_init_drivers(void);
void is31fl3731_init(uint8_t addr);
void is31fl3731_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3731_select_page(uint8_t addr, uint8_t page);
void is31fl3731_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

void is31fl3731_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
Expand Down
35 changes: 14 additions & 21 deletions drivers/led/issi/is31fl3733-simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
uint8_t g_twi_transfer_buffer[20];

// These buffers match the IS31FL3733 PWM registers.
// The control buffers match the PG0 LED On/Off registers.
// The control buffers match the page 0 LED On/Off registers.
// Storing them like this is optimal for I2C transfers to the registers.
// We could optimize this and take out the unused registers from these
// buffers and the transfers in is31fl3733_write_pwm_buffer() but it's
Expand Down Expand Up @@ -97,8 +97,13 @@ bool is31fl3733_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
return true;
}

void is31fl3733_select_page(uint8_t addr, uint8_t page) {
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, page);
}

bool is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
// Assumes PG1 is already selected.
// Assumes page 1 is already selected.
// If any of the transactions fails function returns false.
// Transmit PWM registers in 12 transfers of 16 bytes.
// g_twi_transfer_buffer[] is 20 bytes
Expand Down Expand Up @@ -163,32 +168,23 @@ void is31fl3733_init(uint8_t addr, uint8_t sync) {
// then disable software shutdown.
// Sync is passed so set it according to the datasheet.

// Unlock the command register.
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_LED_CONTROL);

// Select PG0
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_LED_CONTROL);
// Turn off all LEDs.
for (int i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) {
is31fl3733_write_register(addr, i, 0x00);
}

// Unlock the command register.
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_PWM);

// Select PG1
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_PWM);
// Set PWM on all LEDs to 0
// No need to setup Breath registers to PWM as that is the default.
for (int i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i++) {
is31fl3733_write_register(addr, i, 0x00);
}

// Unlock the command register.
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_FUNCTION);

// Select PG3
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_FUNCTION);
// Set de-ghost pull-up resistors (SWx)
is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_SW_PULLUP, IS31FL3733_SW_PULLUP);
// Set de-ghost pull-down resistors (CSx)
Expand Down Expand Up @@ -239,11 +235,9 @@ void is31fl3733_set_led_control_register(uint8_t index, bool value) {

void is31fl3733_update_pwm_buffers(uint8_t addr, uint8_t index) {
if (g_pwm_buffer_update_required[index]) {
// Firstly we need to unlock the command register and select PG1.
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_PWM);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_PWM);

// If any of the transactions fail we risk writing dirty PG0,
// If any of the transactions fail we risk writing dirty page 0,
// refresh page 0 just in case.
if (!is31fl3733_write_pwm_buffer(addr, g_pwm_buffer[index])) {
g_led_control_registers_update_required[index] = true;
Expand All @@ -254,9 +248,8 @@ void is31fl3733_update_pwm_buffers(uint8_t addr, uint8_t index) {

void is31fl3733_update_led_control_registers(uint8_t addr, uint8_t index) {
if (g_led_control_registers_update_required[index]) {
// Firstly we need to unlock the command register and select PG0
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_LED_CONTROL);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_LED_CONTROL);

for (int i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) {
is31fl3733_write_register(addr, i, g_led_control_registers[index][i]);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/led/issi/is31fl3733-simple.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ extern const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT];
void is31fl3733_init_drivers(void);
void is31fl3733_init(uint8_t addr, uint8_t sync);
bool is31fl3733_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3733_select_page(uint8_t addr, uint8_t page);
bool is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

void is31fl3733_set_value(int index, uint8_t value);
Expand Down
35 changes: 14 additions & 21 deletions drivers/led/issi/is31fl3733.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
uint8_t g_twi_transfer_buffer[20];

// These buffers match the IS31FL3733 PWM registers.
// The control buffers match the PG0 LED On/Off registers.
// The control buffers match the page 0 LED On/Off registers.
// Storing them like this is optimal for I2C transfers to the registers.
// We could optimize this and take out the unused registers from these
// buffers and the transfers in is31fl3733_write_pwm_buffer() but it's
Expand Down Expand Up @@ -96,8 +96,13 @@ bool is31fl3733_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
return true;
}

void is31fl3733_select_page(uint8_t addr, uint8_t page) {
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, page);
}

bool is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
// Assumes PG1 is already selected.
// Assumes page 1 is already selected.
// If any of the transactions fails function returns false.
// Transmit PWM registers in 12 transfers of 16 bytes.
// g_twi_transfer_buffer[] is 20 bytes
Expand Down Expand Up @@ -162,32 +167,23 @@ void is31fl3733_init(uint8_t addr, uint8_t sync) {
// then disable software shutdown.
// Sync is passed so set it according to the datasheet.

// Unlock the command register.
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_LED_CONTROL);

// Select PG0
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_LED_CONTROL);
// Turn off all LEDs.
for (int i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) {
is31fl3733_write_register(addr, i, 0x00);
}

// Unlock the command register.
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_PWM);

// Select PG1
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_PWM);
// Set PWM on all LEDs to 0
// No need to setup Breath registers to PWM as that is the default.
for (int i = 0; i < IS31FL3733_PWM_REGISTER_COUNT; i++) {
is31fl3733_write_register(addr, i, 0x00);
}

// Unlock the command register.
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_FUNCTION);

// Select PG3
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_FUNCTION);
// Set de-ghost pull-up resistors (SWx)
is31fl3733_write_register(addr, IS31FL3733_FUNCTION_REG_SW_PULLUP, IS31FL3733_SW_PULLUP);
// Set de-ghost pull-down resistors (CSx)
Expand Down Expand Up @@ -254,11 +250,9 @@ void is31fl3733_set_led_control_register(uint8_t index, bool red, bool green, bo

void is31fl3733_update_pwm_buffers(uint8_t addr, uint8_t index) {
if (g_pwm_buffer_update_required[index]) {
// Firstly we need to unlock the command register and select PG1.
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_PWM);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_PWM);

// If any of the transactions fail we risk writing dirty PG0,
// If any of the transactions fail we risk writing dirty page 0,
// refresh page 0 just in case.
if (!is31fl3733_write_pwm_buffer(addr, g_pwm_buffer[index])) {
g_led_control_registers_update_required[index] = true;
Expand All @@ -269,9 +263,8 @@ void is31fl3733_update_pwm_buffers(uint8_t addr, uint8_t index) {

void is31fl3733_update_led_control_registers(uint8_t addr, uint8_t index) {
if (g_led_control_registers_update_required[index]) {
// Firstly we need to unlock the command register and select PG0
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
is31fl3733_write_register(addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_LED_CONTROL);
is31fl3733_select_page(addr, IS31FL3733_COMMAND_LED_CONTROL);

for (int i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) {
is31fl3733_write_register(addr, i, g_led_control_registers[index][i]);
}
Expand Down
1 change: 1 addition & 0 deletions drivers/led/issi/is31fl3733.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ extern const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT];
void is31fl3733_init_drivers(void);
void is31fl3733_init(uint8_t addr, uint8_t sync);
bool is31fl3733_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3733_select_page(uint8_t addr, uint8_t page);
bool is31fl3733_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

void is31fl3733_set_color(int index, uint8_t red, uint8_t green, uint8_t blue);
Expand Down
Loading

0 comments on commit 847cfbd

Please sign in to comment.