diff options
Diffstat (limited to 'drivers/led/issi/is31fl3741-mono.c')
-rw-r--r-- | drivers/led/issi/is31fl3741-mono.c | 103 |
1 files changed, 65 insertions, 38 deletions
diff --git a/drivers/led/issi/is31fl3741-mono.c b/drivers/led/issi/is31fl3741-mono.c index 0212f6f204..806664d415 100644 --- a/drivers/led/issi/is31fl3741-mono.c +++ b/drivers/led/issi/is31fl3741-mono.c @@ -21,8 +21,10 @@ #include "i2c_master.h" #include "wait.h" -#define IS31FL3741_PWM_REGISTER_COUNT 351 -#define IS31FL3741_SCALING_REGISTER_COUNT 351 +#define IS31FL3741_PWM_0_REGISTER_COUNT 180 +#define IS31FL3741_PWM_1_REGISTER_COUNT 171 +#define IS31FL3741_SCALING_0_REGISTER_COUNT 180 +#define IS31FL3741_SCALING_1_REGISTER_COUNT 171 #ifndef IS31FL3741_I2C_TIMEOUT # define IS31FL3741_I2C_TIMEOUT 100 @@ -72,16 +74,20 @@ const uint8_t i2c_addresses[IS31FL3741_DRIVER_COUNT] = { // buffers and the transfers in is31fl3741_write_pwm_buffer() but it's // probably not worth the extra complexity. typedef struct is31fl3741_driver_t { - uint8_t pwm_buffer[IS31FL3741_PWM_REGISTER_COUNT]; + uint8_t pwm_buffer_0[IS31FL3741_PWM_0_REGISTER_COUNT]; + uint8_t pwm_buffer_1[IS31FL3741_PWM_1_REGISTER_COUNT]; bool pwm_buffer_dirty; - uint8_t scaling_buffer[IS31FL3741_SCALING_REGISTER_COUNT]; + uint8_t scaling_buffer_0[IS31FL3741_SCALING_0_REGISTER_COUNT]; + uint8_t scaling_buffer_1[IS31FL3741_SCALING_1_REGISTER_COUNT]; bool scaling_buffer_dirty; } PACKED is31fl3741_driver_t; is31fl3741_driver_t driver_buffers[IS31FL3741_DRIVER_COUNT] = {{ - .pwm_buffer = {0}, + .pwm_buffer_0 = {0}, + .pwm_buffer_1 = {0}, .pwm_buffer_dirty = false, - .scaling_buffer = {0}, + .scaling_buffer_0 = {0}, + .scaling_buffer_1 = {0}, .scaling_buffer_dirty = false, }}; @@ -101,30 +107,35 @@ void is31fl3741_select_page(uint8_t index, uint8_t page) { } void is31fl3741_write_pwm_buffer(uint8_t index) { - // Assume page 0 is already selected + is31fl3741_select_page(index, IS31FL3741_COMMAND_PWM_0); - for (uint16_t i = 0; i < 342; i += 18) { - if (i == 180) { - is31fl3741_select_page(index, IS31FL3741_COMMAND_PWM_1); - } + // Transmit PWM0 registers in 6 transfers of 30 bytes. + // Iterate over the pwm_buffer_0 contents at 30 byte intervals. + for (uint8_t i = 0; i < IS31FL3741_PWM_0_REGISTER_COUNT; i += 30) { #if IS31FL3741_I2C_PERSISTENCE > 0 for (uint8_t j = 0; j < IS31FL3741_I2C_PERSISTENCE; j++) { - if (i2c_write_register(i2c_addresses[index] << 1, i % 180, driver_buffers[index].pwm_buffer + i, 18, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; + if (i2c_write_register(i2c_addresses[index] << 1, i, driver_buffers[index].pwm_buffer_0 + i, 30, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; } #else - i2c_write_register(i2c_addresses[index] << 1, i % 180, driver_buffers[index].pwm_buffer + i, 18, IS31FL3741_I2C_TIMEOUT); + i2c_write_register(i2c_addresses[index] << 1, i, driver_buffers[index].pwm_buffer_0 + i, 30, IS31FL3741_I2C_TIMEOUT); #endif } - // transfer the left cause the total number is 351 + is31fl3741_select_page(index, IS31FL3741_COMMAND_PWM_1); + + // Transmit PWM1 registers in 9 transfers of 19 bytes. + + // Iterate over the pwm_buffer_1 contents at 19 byte intervals. + for (uint8_t i = 0; i < IS31FL3741_PWM_1_REGISTER_COUNT; i += 19) { #if IS31FL3741_I2C_PERSISTENCE > 0 - for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { - if (i2c_write_register(i2c_addresses[index] << 1, 162, driver_buffers[index].pwm_buffer + 342, 9, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; - } + for (uint8_t i = 0; i < IS31FL3741_I2C_PERSISTENCE; i++) { + if (i2c_write_register(i2c_addresses[index] << 1, i, driver_buffers[index].pwm_buffer_1 + i, 19, IS31FL3741_I2C_TIMEOUT) == I2C_STATUS_SUCCESS) break; + } #else - i2c_write_register(i2c_addresses[index] << 1, 162, driver_buffers[index].pwm_buffer + 342, 9, IS31FL3741_I2C_TIMEOUT); + i2c_write_register(i2c_addresses[index] << 1, i, driver_buffers[index].pwm_buffer_1 + i, 19, IS31FL3741_I2C_TIMEOUT); #endif + } } void is31fl3741_init_drivers(void) { @@ -168,18 +179,34 @@ void is31fl3741_init(uint8_t index) { wait_ms(10); } +uint8_t get_pwm_value(uint8_t driver, uint16_t reg) { + if (reg & 0x100) { + return driver_buffers[driver].pwm_buffer_1[reg & 0xFF]; + } else { + return driver_buffers[driver].pwm_buffer_0[reg]; + } +} + +void set_pwm_value(uint8_t driver, uint16_t reg, uint8_t value) { + if (reg & 0x100) { + driver_buffers[driver].pwm_buffer_1[reg & 0xFF] = value; + } else { + driver_buffers[driver].pwm_buffer_0[reg] = value; + } +} + void is31fl3741_set_value(int index, uint8_t value) { is31fl3741_led_t led; if (index >= 0 && index < IS31FL3741_LED_COUNT) { memcpy_P(&led, (&g_is31fl3741_leds[index]), sizeof(led)); - if (driver_buffers[led.driver].pwm_buffer[led.v] == value) { + if (get_pwm_value(led.driver, led.v) == value) { return; } - driver_buffers[led.driver].pwm_buffer[led.v] = value; - driver_buffers[led.driver].pwm_buffer_dirty = true; + set_pwm_value(led.driver, led.v, value); + driver_buffers[led.driver].pwm_buffer_dirty = true; } } @@ -189,23 +216,25 @@ void is31fl3741_set_value_all(uint8_t value) { } } +void set_scaling_value(uint8_t driver, uint16_t reg, uint8_t value) { + if (reg & 0x100) { + driver_buffers[driver].scaling_buffer_1[reg & 0xFF] = value; + } else { + driver_buffers[driver].scaling_buffer_0[reg] = value; + } +} + void is31fl3741_set_led_control_register(uint8_t index, bool value) { is31fl3741_led_t led; memcpy_P(&led, (&g_is31fl3741_leds[index]), sizeof(led)); - if (value) { - driver_buffers[led.driver].scaling_buffer[led.v] = 0xFF; - } else { - driver_buffers[led.driver].scaling_buffer[led.v] = 0x00; - } + set_scaling_value(led.driver, led.v, value ? 0xFF : 0x00); driver_buffers[led.driver].scaling_buffer_dirty = true; } void is31fl3741_update_pwm_buffers(uint8_t index) { if (driver_buffers[index].pwm_buffer_dirty) { - is31fl3741_select_page(index, IS31FL3741_COMMAND_PWM_0); - is31fl3741_write_pwm_buffer(index); driver_buffers[index].pwm_buffer_dirty = false; @@ -213,24 +242,22 @@ void is31fl3741_update_pwm_buffers(uint8_t index) { } void is31fl3741_set_pwm_buffer(const is31fl3741_led_t *pled, uint8_t value) { - driver_buffers[pled->driver].pwm_buffer[pled->v] = value; - driver_buffers[pled->driver].pwm_buffer_dirty = true; + set_pwm_value(pled->driver, pled->v, value); + driver_buffers[pled->driver].pwm_buffer_dirty = true; } void is31fl3741_update_led_control_registers(uint8_t index) { if (driver_buffers[index].scaling_buffer_dirty) { is31fl3741_select_page(index, IS31FL3741_COMMAND_SCALING_0); - // CS1_SW1 to CS30_SW6 are on page 2 - for (int i = CS1_SW1; i <= CS30_SW6; ++i) { - is31fl3741_write_register(index, i, driver_buffers[index].scaling_buffer[i]); + for (uint8_t i = 0; i < IS31FL3741_SCALING_0_REGISTER_COUNT; i++) { + is31fl3741_write_register(index, i, driver_buffers[index].scaling_buffer_0[i]); } is31fl3741_select_page(index, IS31FL3741_COMMAND_SCALING_1); - // CS1_SW7 to CS39_SW9 are on page 3 - for (int i = CS1_SW7; i <= CS39_SW9; ++i) { - is31fl3741_write_register(index, i - CS1_SW7, driver_buffers[index].scaling_buffer[i]); + for (uint8_t i = 0; i < IS31FL3741_SCALING_1_REGISTER_COUNT; i++) { + is31fl3741_write_register(index, i, driver_buffers[index].scaling_buffer_1[i]); } driver_buffers[index].scaling_buffer_dirty = false; @@ -238,8 +265,8 @@ void is31fl3741_update_led_control_registers(uint8_t index) { } void is31fl3741_set_scaling_registers(const is31fl3741_led_t *pled, uint8_t value) { - driver_buffers[pled->driver].scaling_buffer[pled->v] = value; - driver_buffers[pled->driver].scaling_buffer_dirty = true; + set_scaling_value(pled->driver, pled->v, value); + driver_buffers[pled->driver].scaling_buffer_dirty = true; } void is31fl3741_flush(void) { |