~ruther/qmk_firmware

358bc8eac8e74eb79cd876bc41f3992da2bfcaf3 — Ryan 1 year, 5 months ago 3a2aec4
LED drivers: refactor page selection (#22518)

M drivers/led/issi/is31fl3218-simple.h => drivers/led/issi/is31fl3218-simple.h +2 -0
@@ 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);

M drivers/led/issi/is31fl3218.h => drivers/led/issi/is31fl3218.h +2 -0
@@ 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);

M drivers/led/issi/is31fl3731-simple.c => drivers/led/issi/is31fl3731-simple.c +11 -10
@@ 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


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


@@ 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++) {


@@ 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) {

M drivers/led/issi/is31fl3731-simple.h => drivers/led/issi/is31fl3731-simple.h +1 -0
@@ 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);

M drivers/led/issi/is31fl3731.c => drivers/led/issi/is31fl3731.c +11 -10
@@ 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


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


@@ 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++) {


@@ 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) {

M drivers/led/issi/is31fl3731.h => drivers/led/issi/is31fl3731.h +1 -0
@@ 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);

M drivers/led/issi/is31fl3733-simple.c => drivers/led/issi/is31fl3733-simple.c +14 -21
@@ 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


@@ 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


@@ 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)


@@ 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;


@@ 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]);
        }

M drivers/led/issi/is31fl3733-simple.h => drivers/led/issi/is31fl3733-simple.h +1 -0
@@ 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);

M drivers/led/issi/is31fl3733.c => drivers/led/issi/is31fl3733.c +14 -21
@@ 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


@@ 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


@@ 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)


@@ 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;


@@ 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]);
        }

M drivers/led/issi/is31fl3733.h => drivers/led/issi/is31fl3733.h +1 -0
@@ 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);

M drivers/led/issi/is31fl3736-simple.c => drivers/led/issi/is31fl3736-simple.c +13 -20
@@ 51,7 51,7 @@
uint8_t g_twi_transfer_buffer[20];

// These buffers match the IS31FL3736 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 is31fl3736_write_pwm_buffer() but it's


@@ 75,8 75,13 @@ void is31fl3736_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
#endif
}

void is31fl3736_select_page(uint8_t addr, uint8_t page) {
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, page);
}

void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
    // assumes PG1 is already selected
    // assumes page 1 is already selected

    // transmit PWM registers in 12 transfers of 16 bytes
    // g_twi_transfer_buffer[] is 20 bytes


@@ 135,32 140,23 @@ void is31fl3736_init(uint8_t addr) {
    // Set up the mode and other settings, clear the PWM registers,
    // then disable software shutdown.

    // Unlock the command register.
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3736_select_page(addr, IS31FL3736_COMMAND_LED_CONTROL);

    // Select PG0
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_COMMAND_LED_CONTROL);
    // Turn off all LEDs.
    for (int i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) {
        is31fl3736_write_register(addr, i, 0x00);
    }

    // Unlock the command register.
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3736_select_page(addr, IS31FL3736_COMMAND_PWM);

    // Select PG1
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_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 < IS31FL3736_PWM_REGISTER_COUNT; i++) {
        is31fl3736_write_register(addr, i, 0x00);
    }

    // Unlock the command register.
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3736_select_page(addr, IS31FL3736_COMMAND_FUNCTION);

    // Select PG3
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_COMMAND_FUNCTION);
    // Set de-ghost pull-up resistors (SWx)
    is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_SW_PULLUP, IS31FL3736_SW_PULLUP);
    // Set de-ghost pull-down resistors (CSx)


@@ 217,9 213,7 @@ void is31fl3736_set_led_control_register(uint8_t index, bool value) {

void is31fl3736_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
        is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_COMMAND_PWM);
        is31fl3736_select_page(addr, IS31FL3736_COMMAND_PWM);

        is31fl3736_write_pwm_buffer(addr, g_pwm_buffer[index]);
        g_pwm_buffer_update_required[index] = false;


@@ 228,9 222,8 @@ void is31fl3736_update_pwm_buffers(uint8_t addr, uint8_t index) {

void is31fl3736_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
        is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_COMMAND_LED_CONTROL);
        is31fl3736_select_page(addr, IS31FL3736_COMMAND_LED_CONTROL);

        for (int i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) {
            is31fl3736_write_register(addr, i, g_led_control_registers[index][i]);
        }

M drivers/led/issi/is31fl3736-simple.h => drivers/led/issi/is31fl3736-simple.h +1 -0
@@ 112,6 112,7 @@ extern const is31fl3736_led_t PROGMEM g_is31fl3736_leds[IS31FL3736_LED_COUNT];
void is31fl3736_init_drivers(void);
void is31fl3736_init(uint8_t addr);
void is31fl3736_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3736_select_page(uint8_t addr, uint8_t page);
void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

void is31fl3736_set_value(int index, uint8_t value);

M drivers/led/issi/is31fl3736.c => drivers/led/issi/is31fl3736.c +13 -20
@@ 51,7 51,7 @@
uint8_t g_twi_transfer_buffer[20];

// These buffers match the IS31FL3736 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 is31fl3736_write_pwm_buffer() but it's


@@ 75,8 75,13 @@ void is31fl3736_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
#endif
}

void is31fl3736_select_page(uint8_t addr, uint8_t page) {
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, page);
}

void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
    // assumes PG1 is already selected
    // assumes page 1 is already selected

    // transmit PWM registers in 12 transfers of 16 bytes
    // g_twi_transfer_buffer[] is 20 bytes


@@ 135,32 140,23 @@ void is31fl3736_init(uint8_t addr) {
    // Set up the mode and other settings, clear the PWM registers,
    // then disable software shutdown.

    // Unlock the command register.
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3736_select_page(addr, IS31FL3736_REG_LED_CONTROL);

    // Select PG0
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_REG_LED_CONTROL);
    // Turn off all LEDs.
    for (int i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) {
        is31fl3736_write_register(addr, i, 0x00);
    }

    // Unlock the command register.
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITELOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3736_select_page(addr, IS31FL3736_COMMAND_PWM);

    // Select PG1
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_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 < IS31FL3736_PWM_REGISTER_COUNT; i++) {
        is31fl3736_write_register(addr, i, 0x00);
    }

    // Unlock the command register.
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3736_select_page(addr, IS31FL3736_COMMAND_FUNCTION);

    // Select PG3
    is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_COMMAND_FUNCTION);
    // Set de-ghost pull-up resistors (SWx)
    is31fl3736_write_register(addr, IS31FL3736_FUNCTION_REG_SW_PULLUP, IS31FL3736_SW_PULLUP);
    // Set de-ghost pull-down resistors (CSx)


@@ 234,9 230,7 @@ void is31fl3736_set_led_control_register(uint8_t index, bool red, bool green, bo

void is31fl3736_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
        is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_COMMAND_PWM);
        is31fl3736_select_page(addr, IS31FL3736_COMMAND_PWM);

        is31fl3736_write_pwm_buffer(addr, g_pwm_buffer[index]);
        g_pwm_buffer_update_required[index] = false;


@@ 245,9 239,8 @@ void is31fl3736_update_pwm_buffers(uint8_t addr, uint8_t index) {

void is31fl3736_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
        is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND_WRITE_LOCK, IS31FL3736_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3736_write_register(addr, IS31FL3736_REG_COMMAND, IS31FL3736_COMMAND_LED_CONTROL);
        is31fl3736_select_page(addr, IS31FL3736_COMMAND_LED_CONTROL);

        for (int i = 0; i < IS31FL3736_LED_CONTROL_REGISTER_COUNT; i++) {
            is31fl3736_write_register(addr, i, g_led_control_registers[index][i]);
        }

M drivers/led/issi/is31fl3736.h => drivers/led/issi/is31fl3736.h +1 -0
@@ 126,6 126,7 @@ extern const is31fl3736_led_t PROGMEM g_is31fl3736_leds[IS31FL3736_LED_COUNT];
void is31fl3736_init_drivers(void);
void is31fl3736_init(uint8_t addr);
void is31fl3736_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3736_select_page(uint8_t addr, uint8_t page);
void is31fl3736_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

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

M drivers/led/issi/is31fl3737-simple.c => drivers/led/issi/is31fl3737-simple.c +13 -20
@@ 53,7 53,7 @@
uint8_t g_twi_transfer_buffer[20];

// These buffers match the IS31FL3737 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 is31fl3737_write_pwm_buffer() but it's


@@ 78,8 78,13 @@ void is31fl3737_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
#endif
}

void is31fl3737_select_page(uint8_t addr, uint8_t page) {
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, page);
}

void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
    // assumes PG1 is already selected
    // assumes page 1 is already selected

    // transmit PWM registers in 12 transfers of 16 bytes
    // g_twi_transfer_buffer[] is 20 bytes


@@ 138,32 143,23 @@ void is31fl3737_init(uint8_t addr) {
    // Set up the mode and other settings, clear the PWM registers,
    // then disable software shutdown.

    // Unlock the command register.
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3737_select_page(addr, IS31FL3737_COMMAND_LED_CONTROL);

    // Select PG0
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_COMMAND_LED_CONTROL);
    // Turn off all LEDs.
    for (int i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) {
        is31fl3737_write_register(addr, i, 0x00);
    }

    // Unlock the command register.
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3737_select_page(addr, IS31FL3737_COMMAND_PWM);

    // Select PG1
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_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 < IS31FL3737_PWM_REGISTER_COUNT; i++) {
        is31fl3737_write_register(addr, i, 0x00);
    }

    // Unlock the command register.
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3737_select_page(addr, IS31FL3737_COMMAND_FUNCTION);

    // Select PG3
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_COMMAND_FUNCTION);
    // Set de-ghost pull-up resistors (SWx)
    is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_SW_PULLUP, IS31FL3737_SW_PULLUP);
    // Set de-ghost pull-down resistors (CSx)


@@ 214,9 210,7 @@ void is31fl3737_set_led_control_register(uint8_t index, bool value) {

void is31fl3737_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
        is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_COMMAND_PWM);
        is31fl3737_select_page(addr, IS31FL3737_COMMAND_PWM);

        is31fl3737_write_pwm_buffer(addr, g_pwm_buffer[index]);
        g_pwm_buffer_update_required[index] = false;


@@ 225,9 219,8 @@ void is31fl3737_update_pwm_buffers(uint8_t addr, uint8_t index) {

void is31fl3737_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
        is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_COMMAND_LED_CONTROL);
        is31fl3737_select_page(addr, IS31FL3737_COMMAND_LED_CONTROL);

        for (int i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) {
            is31fl3737_write_register(addr, i, g_led_control_registers[index][i]);
        }

M drivers/led/issi/is31fl3737-simple.h => drivers/led/issi/is31fl3737-simple.h +1 -0
@@ 102,6 102,7 @@ extern const is31fl3737_led_t PROGMEM g_is31fl3737_leds[IS31FL3737_LED_COUNT];
void is31fl3737_init_drivers(void);
void is31fl3737_init(uint8_t addr);
void is31fl3737_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3737_select_page(uint8_t addr, uint8_t page);
void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

void is31fl3737_set_value(int index, uint8_t value);

M drivers/led/issi/is31fl3737.c => drivers/led/issi/is31fl3737.c +13 -20
@@ 53,7 53,7 @@
uint8_t g_twi_transfer_buffer[20];

// These buffers match the IS31FL3737 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 is31fl3737_write_pwm_buffer() but it's


@@ 78,8 78,13 @@ void is31fl3737_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
#endif
}

void is31fl3737_select_page(uint8_t addr, uint8_t page) {
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, page);
}

void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
    // assumes PG1 is already selected
    // assumes page 1 is already selected

    // transmit PWM registers in 12 transfers of 16 bytes
    // g_twi_transfer_buffer[] is 20 bytes


@@ 138,32 143,23 @@ void is31fl3737_init(uint8_t addr) {
    // Set up the mode and other settings, clear the PWM registers,
    // then disable software shutdown.

    // Unlock the command register.
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3737_select_page(addr, IS31FL3737_COMMAND_LED_CONTROL);

    // Select PG0
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_COMMAND_LED_CONTROL);
    // Turn off all LEDs.
    for (int i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) {
        is31fl3737_write_register(addr, i, 0x00);
    }

    // Unlock the command register.
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3737_select_page(addr, IS31FL3737_COMMAND_PWM);

    // Select PG1
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_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 < IS31FL3737_PWM_REGISTER_COUNT; i++) {
        is31fl3737_write_register(addr, i, 0x00);
    }

    // Unlock the command register.
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3737_select_page(addr, IS31FL3737_COMMAND_FUNCTION);

    // Select PG3
    is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_COMMAND_FUNCTION);
    // Set de-ghost pull-up resistors (SWx)
    is31fl3737_write_register(addr, IS31FL3737_FUNCTION_REG_SW_PULLUP, IS31FL3737_SW_PULLUP);
    // Set de-ghost pull-down resistors (CSx)


@@ 230,9 226,7 @@ void is31fl3737_set_led_control_register(uint8_t index, bool red, bool green, bo

void is31fl3737_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
        is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_COMMAND_PWM);
        is31fl3737_select_page(addr, IS31FL3737_COMMAND_PWM);

        is31fl3737_write_pwm_buffer(addr, g_pwm_buffer[index]);
        g_pwm_buffer_update_required[index] = false;


@@ 241,9 235,8 @@ void is31fl3737_update_pwm_buffers(uint8_t addr, uint8_t index) {

void is31fl3737_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
        is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND_WRITE_LOCK, IS31FL3737_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3737_write_register(addr, IS31FL3737_REG_COMMAND, IS31FL3737_COMMAND_LED_CONTROL);
        is31fl3737_select_page(addr, IS31FL3737_COMMAND_LED_CONTROL);

        for (int i = 0; i < IS31FL3737_LED_CONTROL_REGISTER_COUNT; i++) {
            is31fl3737_write_register(addr, i, g_led_control_registers[index][i]);
        }

M drivers/led/issi/is31fl3737.h => drivers/led/issi/is31fl3737.h +1 -0
@@ 119,6 119,7 @@ extern const is31fl3737_led_t PROGMEM g_is31fl3737_leds[IS31FL3737_LED_COUNT];
void is31fl3737_init_drivers(void);
void is31fl3737_init(uint8_t addr);
void is31fl3737_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3737_select_page(uint8_t addr, uint8_t page);
void is31fl3737_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

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

M drivers/led/issi/is31fl3741-simple.c => drivers/led/issi/is31fl3741-simple.c +14 -21
@@ 56,7 56,7 @@
uint8_t g_twi_transfer_buffer[20] = {0xFF};

// These buffers match the IS31FL3741 and IS31FL3741A PWM registers.
// The scaling buffers match the PG2 and PG3 LED On/Off registers.
// The scaling buffers match the page 2 and 3 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 is31fl3741_write_pwm_buffer() but it's


@@ 80,14 80,17 @@ void is31fl3741_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
#endif
}

void is31fl3741_select_page(uint8_t addr, uint8_t page) {
    is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, page);
}

bool is31fl3741_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
    // Assume PG0 is already selected
    // Assume page 0 is already selected

    for (int i = 0; i < 342; i += 18) {
        if (i == 180) {
            // unlock the command register and select PG1
            is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
            is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_PWM_1);
            is31fl3741_select_page(addr, IS31FL3741_COMMAND_PWM_1);
        }

        g_twi_transfer_buffer[0] = i % 180;


@@ 162,11 165,7 @@ void is31fl3741_init(uint8_t addr) {
    // then disable software shutdown.
    // Unlock the command register.

    // Unlock the command register.
    is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);

    // Select PG4
    is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_FUNCTION);
    is31fl3741_select_page(addr, IS31FL3741_COMMAND_FUNCTION);

    // Set to Normal operation
    is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_CONFIGURATION, IS31FL3741_CONFIGURATION);


@@ 218,9 217,7 @@ void is31fl3741_set_led_control_register(uint8_t index, bool value) {

void is31fl3741_update_pwm_buffers(uint8_t addr, uint8_t index) {
    if (g_pwm_buffer_update_required[index]) {
        // unlock the command register and select PG2
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_PWM_0);
        is31fl3741_select_page(addr, IS31FL3741_COMMAND_PWM_0);

        is31fl3741_write_pwm_buffer(addr, g_pwm_buffer[index]);
    }


@@ 236,20 233,16 @@ void is31fl3741_set_pwm_buffer(const is31fl3741_led_t *pled, uint8_t value) {

void is31fl3741_update_led_control_registers(uint8_t addr, uint8_t index) {
    if (g_scaling_registers_update_required[index]) {
        // unlock the command register and select PG2
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_SCALING_0);
        is31fl3741_select_page(addr, IS31FL3741_COMMAND_SCALING_0);

        // CS1_SW1 to CS30_SW6 are on PG2
        // CS1_SW1 to CS30_SW6 are on page 2
        for (int i = CS1_SW1; i <= CS30_SW6; ++i) {
            is31fl3741_write_register(addr, i, g_scaling_registers[index][i]);
        }

        // unlock the command register and select PG3
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_SCALING_1);
        is31fl3741_select_page(addr, IS31FL3741_COMMAND_SCALING_1);

        // CS1_SW7 to CS39_SW9 are on PG3
        // CS1_SW7 to CS39_SW9 are on page 3
        for (int i = CS1_SW7; i <= CS39_SW9; ++i) {
            is31fl3741_write_register(addr, i - CS1_SW7, g_scaling_registers[index][i]);
        }

M drivers/led/issi/is31fl3741-simple.h => drivers/led/issi/is31fl3741-simple.h +1 -0
@@ 104,6 104,7 @@ extern const is31fl3741_led_t PROGMEM g_is31fl3741_leds[IS31FL3741_LED_COUNT];
void is31fl3741_init_drivers(void);
void is31fl3741_init(uint8_t addr);
void is31fl3741_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3741_select_page(uint8_t addr, uint8_t page);
bool is31fl3741_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

void is31fl3741_set_value(int index, uint8_t value);

M drivers/led/issi/is31fl3741.c => drivers/led/issi/is31fl3741.c +14 -21
@@ 56,7 56,7 @@
uint8_t g_twi_transfer_buffer[20] = {0xFF};

// These buffers match the IS31FL3741 and IS31FL3741A PWM registers.
// The scaling buffers match the PG2 and PG3 LED On/Off registers.
// The scaling buffers match the page 2 and 3 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 is31fl3741_write_pwm_buffer() but it's


@@ 80,14 80,17 @@ void is31fl3741_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
#endif
}

void is31fl3741_select_page(uint8_t addr, uint8_t page) {
    is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, page);
}

bool is31fl3741_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
    // Assume PG0 is already selected
    // Assume page 0 is already selected

    for (int i = 0; i < 342; i += 18) {
        if (i == 180) {
            // unlock the command register and select PG1
            is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
            is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_PWM_1);
            is31fl3741_select_page(addr, IS31FL3741_COMMAND_PWM_1);
        }

        g_twi_transfer_buffer[0] = i % 180;


@@ 162,11 165,7 @@ void is31fl3741_init(uint8_t addr) {
    // then disable software shutdown.
    // Unlock the command register.

    // Unlock the command register.
    is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);

    // Select PG4
    is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_FUNCTION);
    is31fl3741_select_page(addr, IS31FL3741_COMMAND_FUNCTION);

    // Set to Normal operation
    is31fl3741_write_register(addr, IS31FL3741_FUNCTION_REG_CONFIGURATION, IS31FL3741_CONFIGURATION);


@@ 232,9 231,7 @@ void is31fl3741_set_led_control_register(uint8_t index, bool red, bool green, bo

void is31fl3741_update_pwm_buffers(uint8_t addr, uint8_t index) {
    if (g_pwm_buffer_update_required[index]) {
        // unlock the command register and select PG2
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_PWM_0);
        is31fl3741_select_page(addr, IS31FL3741_COMMAND_PWM_0);

        is31fl3741_write_pwm_buffer(addr, g_pwm_buffer[index]);
    }


@@ 252,20 249,16 @@ void is31fl3741_set_pwm_buffer(const is31fl3741_led_t *pled, uint8_t red, uint8_

void is31fl3741_update_led_control_registers(uint8_t addr, uint8_t index) {
    if (g_scaling_registers_update_required[index]) {
        // unlock the command register and select PG2
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_SCALING_0);
        is31fl3741_select_page(addr, IS31FL3741_COMMAND_SCALING_0);

        // CS1_SW1 to CS30_SW6 are on PG2
        // CS1_SW1 to CS30_SW6 are on page 2
        for (int i = CS1_SW1; i <= CS30_SW6; ++i) {
            is31fl3741_write_register(addr, i, g_scaling_registers[index][i]);
        }

        // unlock the command register and select PG3
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND_WRITE_LOCK, IS31FL3741_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3741_write_register(addr, IS31FL3741_REG_COMMAND, IS31FL3741_COMMAND_SCALING_1);
        is31fl3741_select_page(addr, IS31FL3741_COMMAND_SCALING_1);

        // CS1_SW7 to CS39_SW9 are on PG3
        // CS1_SW7 to CS39_SW9 are on page 3
        for (int i = CS1_SW7; i <= CS39_SW9; ++i) {
            is31fl3741_write_register(addr, i - CS1_SW7, g_scaling_registers[index][i]);
        }

M drivers/led/issi/is31fl3741.h => drivers/led/issi/is31fl3741.h +1 -0
@@ 121,6 121,7 @@ extern const is31fl3741_led_t PROGMEM g_is31fl3741_leds[IS31FL3741_LED_COUNT];
void is31fl3741_init_drivers(void);
void is31fl3741_init(uint8_t addr);
void is31fl3741_write_register(uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3741_select_page(uint8_t addr, uint8_t page);
bool is31fl3741_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);

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

M drivers/led/snled27351-simple.c => drivers/led/snled27351-simple.c +24 -17
@@ 71,6 71,10 @@ bool snled27351_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
    return true;
}

void snled27351_select_page(uint8_t addr, uint8_t page) {
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, page);
}

bool snled27351_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
    // Assumes PG1 is already selected.
    // If any of the transactions fails function returns false.


@@ 133,8 137,8 @@ void snled27351_init_drivers(void) {
}

void snled27351_init(uint8_t addr) {
    // Select to function page
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_FUNCTION);
    snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION);

    // Setting LED driver to shutdown mode
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN);
    // Setting internal channel pulldown/pullup


@@ 147,33 151,35 @@ void snled27351_init(uint8_t addr) {
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SLEW_RATE_CONTROL_MODE_2, SNLED27351_SLEW_RATE_CONTROL_MODE_2_DSL_ENABLE | SNLED27351_SLEW_RATE_CONTROL_MODE_2_SSL_ENABLE);
    // Setting Iref
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, 0);
    // Set LED CONTROL PAGE (Page 0)
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_LED_CONTROL);

    snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL);

    for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) {
        snled27351_write_register(addr, i, 0x00);
    }

    // Set PWM PAGE (Page 1)
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_PWM);
    snled27351_select_page(addr, SNLED27351_COMMAND_PWM);

    for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) {
        snled27351_write_register(addr, i, 0x00);
    }

    // Set CURRENT PAGE (Page 4)
    snled27351_select_page(addr, SNLED27351_COMMAND_CURRENT_TUNE);

    uint8_t current_tune_reg_list[SNLED27351_LED_CURRENT_TUNE_LENGTH] = SNLED27351_CURRENT_TUNE;
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_CURRENT_TUNE);
    for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) {
        snled27351_write_register(addr, i, current_tune_reg_list[i]);
    }

    snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL);

    // Enable LEDs ON/OFF
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_LED_CONTROL);
    for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) {
        snled27351_write_register(addr, i, 0xFF);
    }

    // Select to function page
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_FUNCTION);
    snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION);

    // Setting LED driver to normal mode
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL);
}


@@ 215,7 221,7 @@ void snled27351_set_led_control_register(uint8_t index, bool value) {

void snled27351_update_pwm_buffers(uint8_t addr, uint8_t index) {
    if (g_pwm_buffer_update_required[index]) {
        snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_PWM);
        snled27351_select_page(addr, SNLED27351_COMMAND_PWM);

        // If any of the transactions fail we risk writing dirty PG0,
        // refresh page 0 just in case.


@@ 228,7 234,8 @@ void snled27351_update_pwm_buffers(uint8_t addr, uint8_t index) {

void snled27351_update_led_control_registers(uint8_t addr, uint8_t index) {
    if (g_led_control_registers_update_required[index]) {
        snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_LED_CONTROL);
        snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL);

        for (int i = 0; i < SNLED27351_LED_CONTROL_REGISTER_COUNT; i++) {
            snled27351_write_register(addr, i, g_led_control_registers[index][i]);
        }


@@ 250,15 257,15 @@ void snled27351_flush(void) {
}

void snled27351_sw_return_normal(uint8_t addr) {
    // Select to function page
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_FUNCTION);
    snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION);

    // Setting LED driver to normal mode
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL);
}

void snled27351_sw_shutdown(uint8_t addr) {
    // Select to function page
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_FUNCTION);
    snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION);

    // Setting LED driver to shutdown mode
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN);
    // Write SW Sleep Register

M drivers/led/snled27351-simple.h => drivers/led/snled27351-simple.h +1 -0
@@ 155,6 155,7 @@ extern const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT];

void snled27351_init_drivers(void);
void snled27351_init(uint8_t addr);
void snled27351_select_page(uint8_t addr, uint8_t page);
bool snled27351_write_register(uint8_t addr, uint8_t reg, uint8_t data);
bool snled27351_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);


M drivers/led/snled27351.c => drivers/led/snled27351.c +24 -18
@@ 71,6 71,10 @@ bool snled27351_write_register(uint8_t addr, uint8_t reg, uint8_t data) {
    return true;
}

void snled27351_select_page(uint8_t addr, uint8_t page) {
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, page);
}

bool snled27351_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) {
    // Assumes PG1 is already selected.
    // If any of the transactions fails function returns false.


@@ 132,8 136,8 @@ void snled27351_init_drivers(void) {
}

void snled27351_init(uint8_t addr) {
    // Select to function page
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_FUNCTION);
    snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION);

    // Setting LED driver to shutdown mode
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN);
    // Setting internal channel pulldown/pullup


@@ 146,33 150,34 @@ void snled27351_init(uint8_t addr) {
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SLEW_RATE_CONTROL_MODE_2, SNLED27351_SLEW_RATE_CONTROL_MODE_2_DSL_ENABLE | SNLED27351_SLEW_RATE_CONTROL_MODE_2_SSL_ENABLE);
    // Setting Iref
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SLEEP, 0);
    // Set LED CONTROL PAGE (Page 0)
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_LED_CONTROL);

    snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL);

    for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) {
        snled27351_write_register(addr, i, 0x00);
    }

    // Set PWM PAGE (Page 1)
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_PWM);
    snled27351_select_page(addr, SNLED27351_COMMAND_PWM);

    for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) {
        snled27351_write_register(addr, i, 0x00);
    }

    // Set CURRENT PAGE (Page 4)
    snled27351_select_page(addr, SNLED27351_COMMAND_CURRENT_TUNE);

    uint8_t current_tune_reg_list[SNLED27351_LED_CURRENT_TUNE_LENGTH] = SNLED27351_CURRENT_TUNE;
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_CURRENT_TUNE);
    for (int i = 0; i < SNLED27351_LED_CURRENT_TUNE_LENGTH; i++) {
        snled27351_write_register(addr, i, current_tune_reg_list[i]);
    }

    // Enable LEDs ON/OFF
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_LED_CONTROL);
    snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL);

    for (int i = 0; i < SNLED27351_LED_CONTROL_ON_OFF_LENGTH; i++) {
        snled27351_write_register(addr, i, 0xFF);
    }

    // Select to function page
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_FUNCTION);
    snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION);

    // Setting LED driver to normal mode
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL);
}


@@ 230,7 235,7 @@ void snled27351_set_led_control_register(uint8_t index, bool red, bool green, bo

void snled27351_update_pwm_buffers(uint8_t addr, uint8_t index) {
    if (g_pwm_buffer_update_required[index]) {
        snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_PWM);
        snled27351_select_page(addr, SNLED27351_COMMAND_PWM);

        // If any of the transactions fail we risk writing dirty PG0,
        // refresh page 0 just in case.


@@ 243,7 248,8 @@ void snled27351_update_pwm_buffers(uint8_t addr, uint8_t index) {

void snled27351_update_led_control_registers(uint8_t addr, uint8_t index) {
    if (g_led_control_registers_update_required[index]) {
        snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_LED_CONTROL);
        snled27351_select_page(addr, SNLED27351_COMMAND_LED_CONTROL);

        for (int i = 0; i < SNLED27351_LED_CONTROL_REGISTER_COUNT; i++) {
            snled27351_write_register(addr, i, g_led_control_registers[index][i]);
        }


@@ 265,15 271,15 @@ void snled27351_flush(void) {
}

void snled27351_sw_return_normal(uint8_t addr) {
    // Select to function page
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_FUNCTION);
    snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION);

    // Setting LED driver to normal mode
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_NORMAL);
}

void snled27351_sw_shutdown(uint8_t addr) {
    // Select to function page
    snled27351_write_register(addr, SNLED27351_REG_COMMAND, SNLED27351_COMMAND_FUNCTION);
    snled27351_select_page(addr, SNLED27351_COMMAND_FUNCTION);

    // Setting LED driver to shutdown mode
    snled27351_write_register(addr, SNLED27351_FUNCTION_REG_SOFTWARE_SHUTDOWN, SNLED27351_SOFTWARE_SHUTDOWN_SSD_SHUTDOWN);
    // Write SW Sleep Register

M drivers/led/snled27351.h => drivers/led/snled27351.h +1 -0
@@ 169,6 169,7 @@ extern const snled27351_led_t PROGMEM g_snled27351_leds[SNLED27351_LED_COUNT];

void snled27351_init_drivers(void);
void snled27351_init(uint8_t addr);
void snled27351_select_page(uint8_t addr, uint8_t page);
bool snled27351_write_register(uint8_t addr, uint8_t reg, uint8_t data);
bool snled27351_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer);


M keyboards/input_club/k_type/is31fl3733-dual.c => keyboards/input_club/k_type/is31fl3733-dual.c +14 -21
@@ 64,7 64,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


@@ 94,8 94,13 @@ bool is31fl3733_write_register(uint8_t index, uint8_t addr, uint8_t reg, uint8_t
    return true;
}

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

bool is31fl3733_write_pwm_buffer(uint8_t index, 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


@@ 150,32 155,23 @@ void is31fl3733_init(uint8_t bus, 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(bus, addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
    is31fl3733_select_page(bus, addr, IS31FL3733_COMMAND_LED_CONTROL);

    // Select PG0
    is31fl3733_write_register(bus, 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(bus, addr, i, 0x00);
    }

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

    // Select PG1
    is31fl3733_write_register(bus, 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(bus, addr, i, 0x00);
    }

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

    // Select PG3
    is31fl3733_write_register(bus, addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_FUNCTION);
    // Set de-ghost pull-up resistors (SWx)
    is31fl3733_write_register(bus, addr, IS31FL3733_FUNCTION_REG_SW_PULLUP, IS31FL3733_SW_PULLUP);
    // Set de-ghost pull-down resistors (CSx)


@@ 242,11 238,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(index, addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3733_write_register(index, addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_PWM);
        is31fl3733_select_page(index, 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(index, addr, g_pwm_buffer[index])) {
            g_led_control_registers_update_required[index] = true;


@@ 257,9 251,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(index, addr, IS31FL3733_REG_COMMAND_WRITE_LOCK, IS31FL3733_COMMAND_WRITE_LOCK_MAGIC);
        is31fl3733_write_register(index, addr, IS31FL3733_REG_COMMAND, IS31FL3733_COMMAND_LED_CONTROL);
        is31fl3733_select_page(index, addr, IS31FL3733_COMMAND_LED_CONTROL);

        for (int i = 0; i < IS31FL3733_LED_CONTROL_REGISTER_COUNT; i++) {
            is31fl3733_write_register(index, addr, i, g_led_control_registers[index][i]);
        }

M keyboards/input_club/k_type/is31fl3733-dual.h => keyboards/input_club/k_type/is31fl3733-dual.h +1 -0
@@ 70,6 70,7 @@ extern const is31fl3733_led_t PROGMEM g_is31fl3733_leds[IS31FL3733_LED_COUNT];
void is31fl3733_init_drivers(void);
void is31fl3733_init(uint8_t bus, uint8_t addr, uint8_t sync);
bool is31fl3733_write_register(uint8_t index, uint8_t addr, uint8_t reg, uint8_t data);
void is31fl3733_select_page(uint8_t index, uint8_t addr, uint8_t page);
bool is31fl3733_write_pwm_buffer(uint8_t index, uint8_t addr, uint8_t *pwm_buffer);

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

M keyboards/input_club/k_type/keymaps/andrew-fahmy/config.h => keyboards/input_club/k_type/keymaps/andrew-fahmy/config.h +2 -34
@@ 16,37 16,5 @@

#pragma once


#ifdef RGB_MATRIX_ENABLE
// #    define RGB_MATRIX_FRAMEBUFFER_EFFECTS
// #    define RGB_MATRIX_KEYPRESSES
#    define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_RAINDROPS

// #    define DEBUG_MATRIX_SCAN_RATE

#    define RGB_MATRIX_LED_FLUSH_LIMIT 100
// #    define RGB_MATRIX_LED_PROCESS_LIMIT 2

// i2c_master defines
#    define I2C_COUNT 2

#    define I2C1_BANK GPIOB
#    define I2C1_SCL 0 // A2 on pinout = B0
#    define I2C1_SDA 1 // A2 on pinout = B1
#    define I2C1_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
#    define I2C1_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2

#    define USE_I2C2
#    define I2C2_BANK GPIOC
#    define I2C2_SCL 10 // A2 on pinout = C10
#    define I2C2_SDA 11 // A2 on pinout = C11
#    define I2C2_SCL_PAL_MODE PAL_MODE_ALTERNATIVE_2
#    define I2C2_SDA_PAL_MODE PAL_MODE_ALTERNATIVE_2

#    define DRIVER_ADDR_1 0b1010000
#    define DRIVER_ADDR_2 0b1010000
#    define DRIVER_COUNT 2
#    define DRIVER_1_LED_TOTAL 64
#    define DRIVER_2_LED_TOTAL 55
#    define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)
#endif
#define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_RAINDROPS
#define RGB_MATRIX_LED_FLUSH_LIMIT 100

Do not follow this link